Files
hsiegeln b594ac6f4a docs(04): capture phase context
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 19:37:51 +01:00

4.9 KiB

Phase 4: Security - Context

Gathered: 2026-03-11 Status: Ready for planning

## Phase Boundary

All agent-server communication is authenticated and integrity-protected. JWT for API access control, Ed25519 signatures for pushed configuration/commands, bootstrap token for initial agent registration. This phase secures the communication channel between agents and server — not user/UI auth (deferred to v2 with web UI).

## Implementation Decisions

Bootstrap token flow

  • Single shared token from CAMELEER_AUTH_TOKEN env var — no config file fallback
  • Agent passes bootstrap token via Authorization: Bearer <token> header on POST /register
  • Server returns 401 Unauthorized when token is missing or invalid — no detail about what's wrong
  • Server fails fast on startup if CAMELEER_AUTH_TOKEN is not set — prevents running insecure
  • Hot rotation via dual-token overlap: support CAMELEER_AUTH_TOKEN_PREVIOUS env var, server accepts both during rotation window. Remove old var when all agents updated

JWT lifecycle

  • Access JWT expires after 1 hour
  • Separate refresh token with 7-day expiry, issued alongside access JWT at registration
  • Agent calls POST /api/v1/agents/{id}/refresh with refresh token to get new access JWT
  • JWT claims: sub = agentId, custom claim for group
  • Registration response includes both access JWT and refresh token (replaces current serverPublicKey: null placeholder with actual public key)

Ed25519 signing

  • Ephemeral keypair generated fresh each server startup — no persistence needed
  • Agents receive public key during registration; must re-register after server restart to get new key
  • Signature included as a signature field in the SSE event data JSON — agent verifies payload minus signature field
  • All command types signed (config-update, deep-trace, replay) — uniform security model

Endpoint protection

  • Public (no JWT): GET /health, POST /register (uses bootstrap token), OpenAPI/Swagger UI docs
  • Protected (JWT required): all other endpoints including ingestion (/data/**), search, agent management, commands
  • SSE connections authenticated via JWT as query parameter: /agents/{id}/events?token=<jwt> (EventSource API doesn't support custom headers)
  • Spring Security filter chain (spring-boot-starter-security) with custom JwtAuthenticationFilter

Claude's Discretion

  • JWT signing algorithm (HMAC with server secret vs Ed25519 for JWT too)
  • Nimbus JOSE+JWT vs jjwt vs other JWT library
  • Ed25519 implementation library (Bouncy Castle vs JDK built-in)
  • Spring Security configuration details (SecurityFilterChain bean, permit patterns)
  • Refresh token storage mechanism (in-memory map, agent registry, or stateless)
## Specific Ideas
  • "This phase and version really is about securing the communication channel between agent and server" — scope is agent-server auth, not user-facing auth
  • Bootstrap token rotation without downtime was explicitly called out as important
  • Agents already re-register on restart (Phase 3 design), so ephemeral Ed25519 keys align naturally

<code_context>

Existing Code Insights

Reusable Assets

  • ProtocolVersionInterceptor + WebConfig: Path-based request filtering pattern — Spring Security filter chain replaces this for auth
  • AgentRegistrationController.register(): Already returns serverPublicKey: null — fill with real Ed25519 public key
  • SseConnectionManager.sendEvent(): SSE delivery point — signing hooks into data before this call
  • AgentRegistryConfig: Configuration properties pattern — extend for security settings (token expiry, etc.)
  • AgentRegistryService: Agent lookup by ID — used for JWT validation (verify agent exists)

Established Patterns

  • Core module: interfaces + domain logic; App module: Spring Boot + implementations
  • application.yml for all configurable values with sensible defaults
  • AgentEventListener interface decouples core from app module — signing logic can live in app module

Integration Points

  • POST /register needs bootstrap token validation before reaching current registration logic
  • SseConnectionManager.connect() needs JWT validation from query parameter
  • SseConnectionManager.onCommandReady() needs to sign payload before delivery
  • All existing controllers need JWT auth enforced — Spring Security filter handles this transparently
  • WebConfig excluded paths need to align with Spring Security permit patterns

</code_context>

## Deferred Ideas
  • User/UI authentication — belongs with web UI in v2
  • Role-based access control (admin vs agent vs viewer) — future phase
  • Token revocation list — evaluate after v1 usage patterns
  • Mutual TLS as additional transport security — infrastructure concern, not application layer
  • Key rotation API endpoint — adds attack surface, stick with restart-based rotation for v1

Phase: 04-security Context gathered: 2026-03-11