4.9 KiB
4.9 KiB
Phase 4: Security - Context
Gathered: 2026-03-11 Status: Ready for planning
## Phase BoundaryAll 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 DecisionsBootstrap token flow
- Single shared token from
CAMELEER_AUTH_TOKENenv var — no config file fallback - Agent passes bootstrap token via
Authorization: Bearer <token>header onPOST /register - Server returns
401 Unauthorizedwhen token is missing or invalid — no detail about what's wrong - Server fails fast on startup if
CAMELEER_AUTH_TOKENis not set — prevents running insecure - Hot rotation via dual-token overlap: support
CAMELEER_AUTH_TOKEN_PREVIOUSenv 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}/refreshwith 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: nullplaceholder 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
signaturefield 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 customJwtAuthenticationFilter
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)
- "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 authAgentRegistrationController.register(): Already returnsserverPublicKey: null— fill with real Ed25519 public keySseConnectionManager.sendEvent(): SSE delivery point — signing hooks into data before this callAgentRegistryConfig: 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.ymlfor all configurable values with sensible defaultsAgentEventListenerinterface decouples core from app module — signing logic can live in app module
Integration Points
POST /registerneeds bootstrap token validation before reaching current registration logicSseConnectionManager.connect()needs JWT validation from query parameterSseConnectionManager.onCommandReady()needs to sign payload before delivery- All existing controllers need JWT auth enforced — Spring Security filter handles this transparently
WebConfigexcluded 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