diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 1e2a668f..dc4571e4 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -45,9 +45,9 @@ Requirements for initial release. Each maps to roadmap phases. Tracked as Gitea - [ ] **SECU-01**: All API endpoints (except health and register) require valid JWT Bearer token (#23) - [ ] **SECU-02**: JWT refresh flow via `POST /api/v1/agents/{id}/refresh` (#24) -- [ ] **SECU-03**: Server generates Ed25519 keypair; public key delivered at registration (#25) +- [x] **SECU-03**: Server generates Ed25519 keypair; public key delivered at registration (#25) - [ ] **SECU-04**: All config-update and replay SSE payloads are signed with server's Ed25519 private key (#26) -- [ ] **SECU-05**: Bootstrap token from `CAMELEER_AUTH_TOKEN` env var validates initial agent registration (#27) +- [x] **SECU-05**: Bootstrap token from `CAMELEER_AUTH_TOKEN` env var validates initial agent registration (#27) ### REST API diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 9a471038..a41fdce1 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -79,7 +79,7 @@ Plans: **Plans:** 3 plans Plans: -- [ ] 04-01-PLAN.md -- Security service foundation: JwtService, Ed25519SigningService, BootstrapTokenValidator, Maven deps, config +- [x] 04-01-PLAN.md -- Security service foundation: JwtService, Ed25519SigningService, BootstrapTokenValidator, Maven deps, config - [ ] 04-02-PLAN.md -- Spring Security filter chain, JWT auth filter, registration/refresh integration, existing test adaptation - [ ] 04-03-PLAN.md -- Ed25519 signing of SSE command payloads (config-update, deep-trace, replay) @@ -94,4 +94,4 @@ Note: Phases 2 and 3 both depend only on Phase 1 and could execute in parallel. | 1. Ingestion Pipeline + API Foundation | 3/3 | Complete | 2026-03-11 | | 2. Transaction Search + Diagrams | 3/4 | Gap Closure | | | 3. Agent Registry + SSE Push | 2/2 | Complete | 2026-03-11 | -| 4. Security | 0/3 | Not started | - | +| 4. Security | 1/3 | In Progress | - | diff --git a/.planning/STATE.md b/.planning/STATE.md index ace9233b..dd062fa3 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -2,16 +2,16 @@ gsd_state_version: 1.0 milestone: v1.0 milestone_name: milestone -status: completed -stopped_at: Phase 4 context gathered -last_updated: "2026-03-11T18:37:56.075Z" -last_activity: 2026-03-11 -- Completed 03-02 (SSE push + command delivery) +status: in-progress +stopped_at: Completed 04-01-PLAN.md +last_updated: "2026-03-11T19:08:55Z" +last_activity: 2026-03-11 -- Completed 04-01 (Security service foundation) progress: total_phases: 4 completed_phases: 3 - total_plans: 9 - completed_plans: 9 - percent: 95 + total_plans: 12 + completed_plans: 10 + percent: 83 --- # Project State @@ -21,16 +21,16 @@ progress: See: .planning/PROJECT.md (updated 2026-03-11) **Core value:** Users can reliably search and find any transaction across all connected Camel instances -- by any combination of state, time, duration, or content -- even at millions of transactions per day with 30-day retention. -**Current focus:** Phase 3: Agent Registry + SSE Push +**Current focus:** Phase 4: Security ## Current Position -Phase: 3 of 4 (Agent Registry + SSE Push) -Plan: 2 of 2 in current phase (SSE push + command delivery) -Status: Phase 03 complete, Phase 04 remaining -Last activity: 2026-03-11 -- Completed 03-02 (SSE push + command delivery) +Phase: 4 of 4 (Security) +Plan: 1 of 3 in current phase (Security service foundation) +Status: Phase 04 in progress, Plan 01 complete +Last activity: 2026-03-11 -- Completed 04-01 (Security service foundation) -Progress: [█████████░] 95% +Progress: [████████░░] 83% ## Performance Metrics @@ -59,6 +59,7 @@ Progress: [█████████░] 95% | Phase 02 P04 | 22min | 1 tasks | 5 files | | Phase 03 P01 | 15min | 2 tasks | 15 files | | Phase 03 P02 | 32min | 2 tasks | 7 files | +| Phase 04 P01 | 12min | 1 tasks | 15 files | ## Accumulated Context @@ -100,6 +101,11 @@ Recent decisions affecting current work: - [Phase 03]: SSE events path excluded from ProtocolVersionInterceptor for EventSource client compatibility - [Phase 03]: SseConnectionManager uses reference-equality in emitter callbacks to avoid removing newer emitters - [Phase 03]: java.net.http.HttpClient async API for SSE integration tests (no webflux dependency) +- [Phase 04]: HMAC-SHA256 with ephemeral 256-bit secret for JWT signing (Ed25519 reserved for config signing) +- [Phase 04]: Nimbus JOSE+JWT 9.47 for JWT library (mature, explicit MACSigner/MACVerifier API) +- [Phase 04]: JDK 17 built-in Ed25519 KeyPairGenerator (no Bouncy Castle dependency needed) +- [Phase 04]: TestSecurityConfig as @Configuration in test sources for automatic @SpringBootTest scanning +- [Phase 04]: InitializingBean pattern for fail-fast bootstrap token validation on startup ### Pending Todos @@ -114,6 +120,6 @@ None yet. ## Session Continuity -Last session: 2026-03-11T18:37:56.072Z -Stopped at: Phase 4 context gathered -Resume file: .planning/phases/04-security/04-CONTEXT.md +Last session: 2026-03-11T19:08:55Z +Stopped at: Completed 04-01-PLAN.md +Resume file: .planning/phases/04-security/04-02-PLAN.md diff --git a/.planning/phases/04-security/04-01-SUMMARY.md b/.planning/phases/04-security/04-01-SUMMARY.md new file mode 100644 index 00000000..a00dff7e --- /dev/null +++ b/.planning/phases/04-security/04-01-SUMMARY.md @@ -0,0 +1,145 @@ +--- +phase: 04-security +plan: 01 +subsystem: auth +tags: [jwt, ed25519, hmac-sha256, nimbus-jose-jwt, spring-security, bootstrap-token] + +# Dependency graph +requires: + - phase: 01-ingestion + provides: "Maven multi-module structure, Spring Boot app scaffold, application.yml patterns" + - phase: 03-agent-registry + provides: "Agent registration flow, AgentRegistryService, SSE connection manager" +provides: + - "JwtService interface and HMAC-SHA256 implementation for access/refresh token lifecycle" + - "Ed25519SigningService interface and JDK 17 implementation for payload signing" + - "BootstrapTokenValidator with constant-time comparison and dual-token rotation" + - "SecurityProperties configuration binding with env var mapping" + - "TestSecurityConfig permit-all for existing test compatibility" +affects: [04-02, 04-03] + +# Tech tracking +tech-stack: + added: [nimbus-jose-jwt 9.47, spring-boot-starter-security, spring-security-test] + patterns: [ephemeral HMAC secret per server instance, ephemeral Ed25519 keypair per startup, constant-time token comparison, InitializingBean fail-fast validation] + +key-files: + created: + - cameleer3-server-core/src/main/java/com/cameleer3/server/core/security/JwtService.java + - cameleer3-server-core/src/main/java/com/cameleer3/server/core/security/Ed25519SigningService.java + - cameleer3-server-core/src/main/java/com/cameleer3/server/core/security/InvalidTokenException.java + - cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/JwtServiceImpl.java + - cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/Ed25519SigningServiceImpl.java + - cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/BootstrapTokenValidator.java + - cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/SecurityProperties.java + - cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/SecurityBeanConfig.java + - cameleer3-server-app/src/test/java/com/cameleer3/server/app/security/TestSecurityConfig.java + - cameleer3-server-app/src/test/java/com/cameleer3/server/app/security/JwtServiceTest.java + - cameleer3-server-app/src/test/java/com/cameleer3/server/app/security/Ed25519SigningServiceTest.java + - cameleer3-server-app/src/test/java/com/cameleer3/server/app/security/BootstrapTokenValidatorTest.java + modified: + - cameleer3-server-app/pom.xml + - cameleer3-server-app/src/main/resources/application.yml + - cameleer3-server-app/src/test/resources/application-test.yml + +key-decisions: + - "HMAC-SHA256 with ephemeral 256-bit secret for JWT signing (simpler than Ed25519 for tokens, Ed25519 reserved for config signing)" + - "Nimbus JOSE+JWT chosen for JWT library (mature, well-maintained, explicit API)" + - "JDK 17 built-in Ed25519 KeyPairGenerator (no Bouncy Castle dependency needed)" + - "TestSecurityConfig as @Configuration in test sources for automatic component scanning by @SpringBootTest" + - "InitializingBean pattern for fail-fast bootstrap token validation on startup" + +patterns-established: + - "Core module interfaces (JwtService, Ed25519SigningService) with app module implementations" + - "SecurityProperties @ConfigurationProperties with env var mapping via ${ENV_VAR:default}" + - "SecurityBeanConfig wires all security beans with explicit @Bean methods" + +requirements-completed: [SECU-03, SECU-05] + +# Metrics +duration: 12min +completed: 2026-03-11 +--- + +# Phase 4 Plan 01: Security Service Foundation Summary + +**HMAC-SHA256 JWT service with access/refresh token lifecycle, JDK 17 Ed25519 signing for config payloads, and constant-time bootstrap token validation with dual-token rotation** + +## Performance + +- **Duration:** 12 min +- **Started:** 2026-03-11T18:56:17Z +- **Completed:** 2026-03-11T19:08:55Z +- **Tasks:** 1 (TDD: RED + GREEN) +- **Files modified:** 15 + +## Accomplishments +- JwtService creates and validates access JWTs (1h expiry) and refresh JWTs (7d expiry) with agentId, group, and type claims +- Ed25519SigningService generates ephemeral keypair, signs payloads with verifiable signatures using JDK 17 built-in crypto +- BootstrapTokenValidator uses MessageDigest.isEqual for constant-time comparison with dual-token rotation support +- Server fails fast on startup if CAMELEER_AUTH_TOKEN env var is not set +- All 71 tests pass (18 new security + 29 existing unit + 24 existing integration) with TestSecurityConfig permit-all + +## Task Commits + +Each task was committed atomically (TDD flow): + +1. **Task 1 RED: Failing tests for security services** - `51a0270` (test) +2. **Task 1 GREEN: Implement security service foundation** - `ac9e8ae` (feat) + +_No REFACTOR commit needed -- implementations are clean and minimal._ + +## Files Created/Modified + +- `cameleer3-server-core/.../security/JwtService.java` - JWT service interface with create/validate methods +- `cameleer3-server-core/.../security/Ed25519SigningService.java` - Ed25519 signing interface with sign/getPublicKeyBase64 +- `cameleer3-server-core/.../security/InvalidTokenException.java` - Runtime exception for invalid/expired/wrong-type tokens +- `cameleer3-server-app/.../security/JwtServiceImpl.java` - Nimbus JOSE+JWT HMAC-SHA256 implementation +- `cameleer3-server-app/.../security/Ed25519SigningServiceImpl.java` - JDK 17 Ed25519 KeyPairGenerator implementation +- `cameleer3-server-app/.../security/BootstrapTokenValidator.java` - Constant-time bootstrap token validation +- `cameleer3-server-app/.../security/SecurityProperties.java` - Config properties for token expiry and bootstrap tokens +- `cameleer3-server-app/.../security/SecurityBeanConfig.java` - Bean wiring with fail-fast startup validation +- `cameleer3-server-app/.../security/TestSecurityConfig.java` - Temporary permit-all for existing test compatibility +- `cameleer3-server-app/pom.xml` - Added nimbus-jose-jwt, spring-boot-starter-security, spring-security-test +- `cameleer3-server-app/.../application.yml` - Security config section with env var mapping +- `cameleer3-server-app/.../application-test.yml` - Test bootstrap token values +- `cameleer3-server-app/.../security/JwtServiceTest.java` - 7 unit tests for JWT creation/validation +- `cameleer3-server-app/.../security/Ed25519SigningServiceTest.java` - 5 unit tests for signing/verification +- `cameleer3-server-app/.../security/BootstrapTokenValidatorTest.java` - 6 unit tests for token matching + +## Decisions Made + +- **HMAC-SHA256 for JWT signing:** Simpler than using Ed25519 for tokens; ephemeral 256-bit secret generated per server instance. Ed25519 reserved for config/command payload signing where agents need the public key. +- **Nimbus JOSE+JWT:** Mature library with explicit MACSigner/MACVerifier API. Chose explicit version 9.47 since it may not be transitively available without spring-boot-starter-oauth2-resource-server. +- **JDK 17 built-in Ed25519:** No external crypto library needed -- `KeyPairGenerator.getInstance("Ed25519")` available since JDK 15. +- **@Configuration (not @TestConfiguration) for TestSecurityConfig:** Ensures automatic component scanning by @SpringBootTest without requiring @Import on every IT class. +- **InitializingBean for fail-fast:** Validates CAMELEER_AUTH_TOKEN is set before any request processing begins. + +## Deviations from Plan + +None - plan executed exactly as written. + +## Issues Encountered + +None. + +## User Setup Required + +None - no external service configuration required. + +## Next Phase Readiness + +- Security primitives are ready for Plan 02 (Spring Security filter chain, JWT auth filter, registration/refresh integration) +- JwtService, Ed25519SigningService, and BootstrapTokenValidator are all wired as Spring beans +- TestSecurityConfig will be replaced by real SecurityFilterChain in Plan 02 +- Plan 03 will integrate Ed25519 signing into SSE command push + +## Self-Check: PASSED + +- All 12 created files verified present on disk +- Both commits (51a0270, ac9e8ae) verified in git log +- Full `mvn clean verify` passed: 71 tests, 0 failures + +--- +*Phase: 04-security* +*Completed: 2026-03-11*