chore: rename cameleer3 to cameleer
Rename Java packages from com.cameleer3 to com.cameleer, module directories from cameleer3-* to cameleer-*, and all references throughout workflows, Dockerfiles, docs, migrations, and pom.xml. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5,19 +5,19 @@ type: execute
|
||||
wave: 1
|
||||
depends_on: []
|
||||
files_modified:
|
||||
- cameleer3-server-app/pom.xml
|
||||
- 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-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/main/resources/application.yml
|
||||
- cameleer3-server-app/src/test/resources/application-test.yml
|
||||
- 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
|
||||
- cameleer-server-app/pom.xml
|
||||
- cameleer-server-core/src/main/java/com/cameleer/server/core/security/JwtService.java
|
||||
- cameleer-server-core/src/main/java/com/cameleer/server/core/security/Ed25519SigningService.java
|
||||
- cameleer-server-app/src/main/java/com/cameleer/server/app/security/JwtServiceImpl.java
|
||||
- cameleer-server-app/src/main/java/com/cameleer/server/app/security/Ed25519SigningServiceImpl.java
|
||||
- cameleer-server-app/src/main/java/com/cameleer/server/app/security/BootstrapTokenValidator.java
|
||||
- cameleer-server-app/src/main/java/com/cameleer/server/app/security/SecurityProperties.java
|
||||
- cameleer-server-app/src/main/java/com/cameleer/server/app/security/SecurityBeanConfig.java
|
||||
- cameleer-server-app/src/main/resources/application.yml
|
||||
- cameleer-server-app/src/test/resources/application-test.yml
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/security/JwtServiceTest.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/security/Ed25519SigningServiceTest.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/security/BootstrapTokenValidatorTest.java
|
||||
autonomous: true
|
||||
requirements:
|
||||
- SECU-03
|
||||
@@ -31,15 +31,15 @@ must_haves:
|
||||
- "BootstrapTokenValidator accepts CAMELEER_AUTH_TOKEN and optionally CAMELEER_AUTH_TOKEN_PREVIOUS using constant-time comparison"
|
||||
- "Server fails fast on startup if CAMELEER_AUTH_TOKEN is not set"
|
||||
artifacts:
|
||||
- path: "cameleer3-server-core/src/main/java/com/cameleer3/server/core/security/JwtService.java"
|
||||
- path: "cameleer-server-core/src/main/java/com/cameleer/server/core/security/JwtService.java"
|
||||
provides: "JWT service interface with createAccessToken, createRefreshToken, validateAndExtractAgentId"
|
||||
- path: "cameleer3-server-core/src/main/java/com/cameleer3/server/core/security/Ed25519SigningService.java"
|
||||
- path: "cameleer-server-core/src/main/java/com/cameleer/server/core/security/Ed25519SigningService.java"
|
||||
provides: "Ed25519 signing interface with sign(payload) and getPublicKeyBase64()"
|
||||
- path: "cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/JwtServiceImpl.java"
|
||||
- path: "cameleer-server-app/src/main/java/com/cameleer/server/app/security/JwtServiceImpl.java"
|
||||
provides: "Nimbus JOSE+JWT HMAC-SHA256 implementation"
|
||||
- path: "cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/Ed25519SigningServiceImpl.java"
|
||||
- path: "cameleer-server-app/src/main/java/com/cameleer/server/app/security/Ed25519SigningServiceImpl.java"
|
||||
provides: "JDK 17 Ed25519 KeyPairGenerator implementation"
|
||||
- path: "cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/BootstrapTokenValidator.java"
|
||||
- path: "cameleer-server-app/src/main/java/com/cameleer/server/app/security/BootstrapTokenValidator.java"
|
||||
provides: "Constant-time bootstrap token validation with dual-token rotation"
|
||||
key_links:
|
||||
- from: "JwtServiceImpl"
|
||||
@@ -76,10 +76,10 @@ Output: Working JwtService, Ed25519SigningService, BootstrapTokenValidator with
|
||||
@.planning/phases/04-security/04-RESEARCH.md
|
||||
@.planning/phases/04-security/04-VALIDATION.md
|
||||
|
||||
@cameleer3-server-app/pom.xml
|
||||
@cameleer3-server-app/src/main/resources/application.yml
|
||||
@cameleer3-server-app/src/test/resources/application-test.yml
|
||||
@cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/AgentRegistryConfig.java
|
||||
@cameleer-server-app/pom.xml
|
||||
@cameleer-server-app/src/main/resources/application.yml
|
||||
@cameleer-server-app/src/test/resources/application-test.yml
|
||||
@cameleer-server-app/src/main/java/com/cameleer/server/app/config/AgentRegistryConfig.java
|
||||
|
||||
<interfaces>
|
||||
<!-- Existing patterns to follow: core module = interfaces/domain, app module = Spring implementations -->
|
||||
@@ -106,19 +106,19 @@ public class AgentRegistryConfig { ... }
|
||||
<task type="auto" tdd="true">
|
||||
<name>Task 1: Core interfaces + app implementations + Maven deps</name>
|
||||
<files>
|
||||
cameleer3-server-app/pom.xml,
|
||||
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-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/main/resources/application.yml,
|
||||
cameleer3-server-app/src/test/resources/application-test.yml,
|
||||
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
|
||||
cameleer-server-app/pom.xml,
|
||||
cameleer-server-core/src/main/java/com/cameleer/server/core/security/JwtService.java,
|
||||
cameleer-server-core/src/main/java/com/cameleer/server/core/security/Ed25519SigningService.java,
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/security/JwtServiceImpl.java,
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/security/Ed25519SigningServiceImpl.java,
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/security/BootstrapTokenValidator.java,
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/security/SecurityProperties.java,
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/security/SecurityBeanConfig.java,
|
||||
cameleer-server-app/src/main/resources/application.yml,
|
||||
cameleer-server-app/src/test/resources/application-test.yml,
|
||||
cameleer-server-app/src/test/java/com/cameleer/server/app/security/JwtServiceTest.java,
|
||||
cameleer-server-app/src/test/java/com/cameleer/server/app/security/Ed25519SigningServiceTest.java,
|
||||
cameleer-server-app/src/test/java/com/cameleer/server/app/security/BootstrapTokenValidatorTest.java
|
||||
</files>
|
||||
<behavior>
|
||||
JwtService tests:
|
||||
@@ -145,7 +145,7 @@ public class AgentRegistryConfig { ... }
|
||||
- Uses constant-time comparison (MessageDigest.isEqual)
|
||||
</behavior>
|
||||
<action>
|
||||
1. Add Maven dependencies to cameleer3-server-app/pom.xml:
|
||||
1. Add Maven dependencies to cameleer-server-app/pom.xml:
|
||||
- `spring-boot-starter-security` (managed version)
|
||||
- `com.nimbusds:nimbus-jose-jwt:9.47` (explicit, may not be transitive without OAuth2 resource server)
|
||||
- `spring-security-test` scope test (managed version)
|
||||
@@ -165,12 +165,12 @@ public class AgentRegistryConfig { ... }
|
||||
|
||||
5. Update application-test.yml: Add `security.bootstrap-token: test-bootstrap-token`, `security.bootstrap-token-previous: old-bootstrap-token`. Also set `CAMELEER_AUTH_TOKEN: test-bootstrap-token` as an env override if needed.
|
||||
|
||||
6. IMPORTANT: Adding spring-boot-starter-security will break ALL existing tests immediately (401 on all endpoints). To prevent this during Plan 01 (before the security filter chain is configured in Plan 02), add a temporary test security config class `src/test/java/com/cameleer3/server/app/security/TestSecurityConfig.java` annotated `@TestConfiguration` that creates a `SecurityFilterChain` permitting all requests. This keeps existing tests green while security services are built. Plan 02 will replace this with real security config and update tests.
|
||||
6. IMPORTANT: Adding spring-boot-starter-security will break ALL existing tests immediately (401 on all endpoints). To prevent this during Plan 01 (before the security filter chain is configured in Plan 02), add a temporary test security config class `src/test/java/com/cameleer/server/app/security/TestSecurityConfig.java` annotated `@TestConfiguration` that creates a `SecurityFilterChain` permitting all requests. This keeps existing tests green while security services are built. Plan 02 will replace this with real security config and update tests.
|
||||
|
||||
7. Write unit tests per the behavior spec above. Tests should NOT require Spring context -- construct implementations directly with test SecurityProperties.
|
||||
</action>
|
||||
<verify>
|
||||
<automated>cd /c/Users/Hendrik/Documents/projects/cameleer3-server && mvn test -pl cameleer3-server-app -Dtest="JwtServiceTest,Ed25519SigningServiceTest,BootstrapTokenValidatorTest" -Dsurefire.reuseForks=false</automated>
|
||||
<automated>cd /c/Users/Hendrik/Documents/projects/cameleer-server && mvn test -pl cameleer-server-app -Dtest="JwtServiceTest,Ed25519SigningServiceTest,BootstrapTokenValidatorTest" -Dsurefire.reuseForks=false</automated>
|
||||
</verify>
|
||||
<done>
|
||||
- JwtService creates and validates access/refresh JWTs with correct claims and expiry
|
||||
|
||||
@@ -25,22 +25,22 @@ tech-stack:
|
||||
|
||||
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
|
||||
- cameleer-server-core/src/main/java/com/cameleer/server/core/security/JwtService.java
|
||||
- cameleer-server-core/src/main/java/com/cameleer/server/core/security/Ed25519SigningService.java
|
||||
- cameleer-server-core/src/main/java/com/cameleer/server/core/security/InvalidTokenException.java
|
||||
- cameleer-server-app/src/main/java/com/cameleer/server/app/security/JwtServiceImpl.java
|
||||
- cameleer-server-app/src/main/java/com/cameleer/server/app/security/Ed25519SigningServiceImpl.java
|
||||
- cameleer-server-app/src/main/java/com/cameleer/server/app/security/BootstrapTokenValidator.java
|
||||
- cameleer-server-app/src/main/java/com/cameleer/server/app/security/SecurityProperties.java
|
||||
- cameleer-server-app/src/main/java/com/cameleer/server/app/security/SecurityBeanConfig.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/security/TestSecurityConfig.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/security/JwtServiceTest.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/security/Ed25519SigningServiceTest.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/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
|
||||
- cameleer-server-app/pom.xml
|
||||
- cameleer-server-app/src/main/resources/application.yml
|
||||
- cameleer-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)"
|
||||
@@ -91,21 +91,21 @@ _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
|
||||
- `cameleer-server-core/.../security/JwtService.java` - JWT service interface with create/validate methods
|
||||
- `cameleer-server-core/.../security/Ed25519SigningService.java` - Ed25519 signing interface with sign/getPublicKeyBase64
|
||||
- `cameleer-server-core/.../security/InvalidTokenException.java` - Runtime exception for invalid/expired/wrong-type tokens
|
||||
- `cameleer-server-app/.../security/JwtServiceImpl.java` - Nimbus JOSE+JWT HMAC-SHA256 implementation
|
||||
- `cameleer-server-app/.../security/Ed25519SigningServiceImpl.java` - JDK 17 Ed25519 KeyPairGenerator implementation
|
||||
- `cameleer-server-app/.../security/BootstrapTokenValidator.java` - Constant-time bootstrap token validation
|
||||
- `cameleer-server-app/.../security/SecurityProperties.java` - Config properties for token expiry and bootstrap tokens
|
||||
- `cameleer-server-app/.../security/SecurityBeanConfig.java` - Bean wiring with fail-fast startup validation
|
||||
- `cameleer-server-app/.../security/TestSecurityConfig.java` - Temporary permit-all for existing test compatibility
|
||||
- `cameleer-server-app/pom.xml` - Added nimbus-jose-jwt, spring-boot-starter-security, spring-security-test
|
||||
- `cameleer-server-app/.../application.yml` - Security config section with env var mapping
|
||||
- `cameleer-server-app/.../application-test.yml` - Test bootstrap token values
|
||||
- `cameleer-server-app/.../security/JwtServiceTest.java` - 7 unit tests for JWT creation/validation
|
||||
- `cameleer-server-app/.../security/Ed25519SigningServiceTest.java` - 5 unit tests for signing/verification
|
||||
- `cameleer-server-app/.../security/BootstrapTokenValidatorTest.java` - 6 unit tests for token matching
|
||||
|
||||
## Decisions Made
|
||||
|
||||
|
||||
@@ -5,17 +5,17 @@ type: execute
|
||||
wave: 2
|
||||
depends_on: ["04-01"]
|
||||
files_modified:
|
||||
- cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/JwtAuthenticationFilter.java
|
||||
- cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/SecurityConfig.java
|
||||
- cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/AgentRegistrationController.java
|
||||
- cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/AgentSseController.java
|
||||
- cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/WebConfig.java
|
||||
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/security/SecurityFilterIT.java
|
||||
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/security/JwtRefreshIT.java
|
||||
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/security/RegistrationSecurityIT.java
|
||||
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/security/BootstrapTokenIT.java
|
||||
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/TestSecurityHelper.java
|
||||
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/security/TestSecurityConfig.java
|
||||
- cameleer-server-app/src/main/java/com/cameleer/server/app/security/JwtAuthenticationFilter.java
|
||||
- cameleer-server-app/src/main/java/com/cameleer/server/app/security/SecurityConfig.java
|
||||
- cameleer-server-app/src/main/java/com/cameleer/server/app/controller/AgentRegistrationController.java
|
||||
- cameleer-server-app/src/main/java/com/cameleer/server/app/controller/AgentSseController.java
|
||||
- cameleer-server-app/src/main/java/com/cameleer/server/app/config/WebConfig.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/security/SecurityFilterIT.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/security/JwtRefreshIT.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/security/RegistrationSecurityIT.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/security/BootstrapTokenIT.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/TestSecurityHelper.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/security/TestSecurityConfig.java
|
||||
autonomous: true
|
||||
requirements:
|
||||
- SECU-01
|
||||
@@ -30,11 +30,11 @@ must_haves:
|
||||
- "SSE endpoint accepts JWT via ?token= query parameter"
|
||||
- "Health endpoint and Swagger UI remain publicly accessible"
|
||||
artifacts:
|
||||
- path: "cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/JwtAuthenticationFilter.java"
|
||||
- path: "cameleer-server-app/src/main/java/com/cameleer/server/app/security/JwtAuthenticationFilter.java"
|
||||
provides: "OncePerRequestFilter extracting JWT from header or query param"
|
||||
- path: "cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/SecurityConfig.java"
|
||||
- path: "cameleer-server-app/src/main/java/com/cameleer/server/app/security/SecurityConfig.java"
|
||||
provides: "SecurityFilterChain with permitAll for public paths, authenticated for rest"
|
||||
- path: "cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/AgentRegistrationController.java"
|
||||
- path: "cameleer-server-app/src/main/java/com/cameleer/server/app/controller/AgentRegistrationController.java"
|
||||
provides: "Updated register endpoint with bootstrap token validation, JWT issuance, public key"
|
||||
key_links:
|
||||
- from: "JwtAuthenticationFilter"
|
||||
@@ -76,11 +76,11 @@ Output: Working security filter chain with protected/public endpoints, registrat
|
||||
@.planning/phases/04-security/04-VALIDATION.md
|
||||
@.planning/phases/04-security/04-01-SUMMARY.md
|
||||
|
||||
@cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/AgentRegistrationController.java
|
||||
@cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/AgentSseController.java
|
||||
@cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/WebConfig.java
|
||||
@cameleer3-server-app/src/test/java/com/cameleer3/server/app/AbstractClickHouseIT.java
|
||||
@cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/AgentRegistrationControllerIT.java
|
||||
@cameleer-server-app/src/main/java/com/cameleer/server/app/controller/AgentRegistrationController.java
|
||||
@cameleer-server-app/src/main/java/com/cameleer/server/app/controller/AgentSseController.java
|
||||
@cameleer-server-app/src/main/java/com/cameleer/server/app/config/WebConfig.java
|
||||
@cameleer-server-app/src/test/java/com/cameleer/server/app/AbstractClickHouseIT.java
|
||||
@cameleer-server-app/src/test/java/com/cameleer/server/app/controller/AgentRegistrationControllerIT.java
|
||||
|
||||
<interfaces>
|
||||
<!-- From Plan 01 (will exist after execution): -->
|
||||
@@ -136,11 +136,11 @@ public class AgentRegistryService {
|
||||
<task type="auto">
|
||||
<name>Task 1: SecurityFilterChain + JwtAuthenticationFilter + registration/refresh integration</name>
|
||||
<files>
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/JwtAuthenticationFilter.java,
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/SecurityConfig.java,
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/AgentRegistrationController.java,
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/AgentSseController.java,
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/WebConfig.java
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/security/JwtAuthenticationFilter.java,
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/security/SecurityConfig.java,
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/controller/AgentRegistrationController.java,
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/controller/AgentSseController.java,
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/config/WebConfig.java
|
||||
</files>
|
||||
<action>
|
||||
1. Create `JwtAuthenticationFilter extends OncePerRequestFilter` (NOT annotated @Component -- constructed in SecurityConfig to avoid double registration):
|
||||
@@ -176,7 +176,7 @@ public class AgentRegistryService {
|
||||
6. Update `WebConfig` if needed: The `ProtocolVersionInterceptor` excluded paths should align with Spring Security public paths. The SSE events path is already excluded from protocol version check (Phase 3 decision). Verify no conflicts.
|
||||
</action>
|
||||
<verify>
|
||||
<automated>cd /c/Users/Hendrik/Documents/projects/cameleer3-server && mvn clean compile -pl cameleer3-server-app</automated>
|
||||
<automated>cd /c/Users/Hendrik/Documents/projects/cameleer-server && mvn clean compile -pl cameleer-server-app</automated>
|
||||
</verify>
|
||||
<done>
|
||||
- SecurityConfig creates stateless filter chain with correct public/protected path split
|
||||
@@ -190,28 +190,28 @@ public class AgentRegistryService {
|
||||
<task type="auto">
|
||||
<name>Task 2: Security integration tests + existing test adaptation</name>
|
||||
<files>
|
||||
cameleer3-server-app/src/test/java/com/cameleer3/server/app/TestSecurityHelper.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/SecurityFilterIT.java,
|
||||
cameleer3-server-app/src/test/java/com/cameleer3/server/app/security/JwtRefreshIT.java,
|
||||
cameleer3-server-app/src/test/java/com/cameleer3/server/app/security/RegistrationSecurityIT.java,
|
||||
cameleer3-server-app/src/test/java/com/cameleer3/server/app/security/BootstrapTokenIT.java,
|
||||
cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/AgentRegistrationControllerIT.java,
|
||||
cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/ExecutionControllerIT.java,
|
||||
cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/DiagramControllerIT.java,
|
||||
cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/MetricsControllerIT.java,
|
||||
cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/BackpressureIT.java,
|
||||
cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/DiagramRenderControllerIT.java,
|
||||
cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/DetailControllerIT.java,
|
||||
cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/SearchControllerIT.java,
|
||||
cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/AgentCommandControllerIT.java,
|
||||
cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/AgentSseControllerIT.java,
|
||||
cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/DiagramLinkingIT.java,
|
||||
cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/IngestionSchemaIT.java,
|
||||
cameleer3-server-app/src/test/java/com/cameleer3/server/app/interceptor/ProtocolVersionIT.java,
|
||||
cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/OpenApiIT.java,
|
||||
cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/ForwardCompatIT.java,
|
||||
cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/HealthControllerIT.java
|
||||
cameleer-server-app/src/test/java/com/cameleer/server/app/TestSecurityHelper.java,
|
||||
cameleer-server-app/src/test/java/com/cameleer/server/app/security/TestSecurityConfig.java,
|
||||
cameleer-server-app/src/test/java/com/cameleer/server/app/security/SecurityFilterIT.java,
|
||||
cameleer-server-app/src/test/java/com/cameleer/server/app/security/JwtRefreshIT.java,
|
||||
cameleer-server-app/src/test/java/com/cameleer/server/app/security/RegistrationSecurityIT.java,
|
||||
cameleer-server-app/src/test/java/com/cameleer/server/app/security/BootstrapTokenIT.java,
|
||||
cameleer-server-app/src/test/java/com/cameleer/server/app/controller/AgentRegistrationControllerIT.java,
|
||||
cameleer-server-app/src/test/java/com/cameleer/server/app/controller/ExecutionControllerIT.java,
|
||||
cameleer-server-app/src/test/java/com/cameleer/server/app/controller/DiagramControllerIT.java,
|
||||
cameleer-server-app/src/test/java/com/cameleer/server/app/controller/MetricsControllerIT.java,
|
||||
cameleer-server-app/src/test/java/com/cameleer/server/app/controller/BackpressureIT.java,
|
||||
cameleer-server-app/src/test/java/com/cameleer/server/app/controller/DiagramRenderControllerIT.java,
|
||||
cameleer-server-app/src/test/java/com/cameleer/server/app/controller/DetailControllerIT.java,
|
||||
cameleer-server-app/src/test/java/com/cameleer/server/app/controller/SearchControllerIT.java,
|
||||
cameleer-server-app/src/test/java/com/cameleer/server/app/controller/AgentCommandControllerIT.java,
|
||||
cameleer-server-app/src/test/java/com/cameleer/server/app/controller/AgentSseControllerIT.java,
|
||||
cameleer-server-app/src/test/java/com/cameleer/server/app/storage/DiagramLinkingIT.java,
|
||||
cameleer-server-app/src/test/java/com/cameleer/server/app/storage/IngestionSchemaIT.java,
|
||||
cameleer-server-app/src/test/java/com/cameleer/server/app/interceptor/ProtocolVersionIT.java,
|
||||
cameleer-server-app/src/test/java/com/cameleer/server/app/controller/OpenApiIT.java,
|
||||
cameleer-server-app/src/test/java/com/cameleer/server/app/controller/ForwardCompatIT.java,
|
||||
cameleer-server-app/src/test/java/com/cameleer/server/app/controller/HealthControllerIT.java
|
||||
</files>
|
||||
<action>
|
||||
1. Replace the Plan 01 temporary `TestSecurityConfig` (permit-all) with real security active in tests. Remove the permit-all override so tests run with actual security enforcement.
|
||||
@@ -259,7 +259,7 @@ public class AgentRegistryService {
|
||||
- Test: New access token from refresh can access protected endpoints
|
||||
</action>
|
||||
<verify>
|
||||
<automated>cd /c/Users/Hendrik/Documents/projects/cameleer3-server && mvn clean verify</automated>
|
||||
<automated>cd /c/Users/Hendrik/Documents/projects/cameleer-server && mvn clean verify</automated>
|
||||
</verify>
|
||||
<done>
|
||||
- All 17 existing ITs pass with JWT authentication
|
||||
|
||||
@@ -25,31 +25,31 @@ tech-stack:
|
||||
|
||||
key-files:
|
||||
created:
|
||||
- cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/JwtAuthenticationFilter.java
|
||||
- cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/SecurityConfig.java
|
||||
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/TestSecurityHelper.java
|
||||
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/security/SecurityFilterIT.java
|
||||
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/security/BootstrapTokenIT.java
|
||||
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/security/RegistrationSecurityIT.java
|
||||
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/security/JwtRefreshIT.java
|
||||
- cameleer-server-app/src/main/java/com/cameleer/server/app/security/JwtAuthenticationFilter.java
|
||||
- cameleer-server-app/src/main/java/com/cameleer/server/app/security/SecurityConfig.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/TestSecurityHelper.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/security/SecurityFilterIT.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/security/BootstrapTokenIT.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/security/RegistrationSecurityIT.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/security/JwtRefreshIT.java
|
||||
modified:
|
||||
- cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/AgentRegistrationController.java
|
||||
- cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/WebConfig.java
|
||||
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/security/TestSecurityConfig.java
|
||||
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/AgentRegistrationControllerIT.java
|
||||
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/ExecutionControllerIT.java
|
||||
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/DiagramControllerIT.java
|
||||
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/MetricsControllerIT.java
|
||||
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/BackpressureIT.java
|
||||
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/DiagramRenderControllerIT.java
|
||||
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/DetailControllerIT.java
|
||||
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/SearchControllerIT.java
|
||||
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/AgentCommandControllerIT.java
|
||||
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/AgentSseControllerIT.java
|
||||
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/DiagramLinkingIT.java
|
||||
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/IngestionSchemaIT.java
|
||||
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/interceptor/ProtocolVersionIT.java
|
||||
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/ForwardCompatIT.java
|
||||
- cameleer-server-app/src/main/java/com/cameleer/server/app/controller/AgentRegistrationController.java
|
||||
- cameleer-server-app/src/main/java/com/cameleer/server/app/config/WebConfig.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/security/TestSecurityConfig.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/controller/AgentRegistrationControllerIT.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/controller/ExecutionControllerIT.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/controller/DiagramControllerIT.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/controller/MetricsControllerIT.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/controller/BackpressureIT.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/controller/DiagramRenderControllerIT.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/controller/DetailControllerIT.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/controller/SearchControllerIT.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/controller/AgentCommandControllerIT.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/controller/AgentSseControllerIT.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/storage/DiagramLinkingIT.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/storage/IngestionSchemaIT.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/interceptor/ProtocolVersionIT.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/controller/ForwardCompatIT.java
|
||||
|
||||
key-decisions:
|
||||
- "Added /error to SecurityConfig permitAll to allow Spring Boot error page forwarding through security"
|
||||
|
||||
@@ -5,10 +5,10 @@ type: execute
|
||||
wave: 2
|
||||
depends_on: ["04-01"]
|
||||
files_modified:
|
||||
- cameleer3-server-app/src/main/java/com/cameleer3/server/app/agent/SseConnectionManager.java
|
||||
- cameleer3-server-app/src/main/java/com/cameleer3/server/app/agent/SsePayloadSigner.java
|
||||
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/security/SseSigningIT.java
|
||||
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/agent/SsePayloadSignerTest.java
|
||||
- cameleer-server-app/src/main/java/com/cameleer/server/app/agent/SseConnectionManager.java
|
||||
- cameleer-server-app/src/main/java/com/cameleer/server/app/agent/SsePayloadSigner.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/security/SseSigningIT.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/agent/SsePayloadSignerTest.java
|
||||
autonomous: true
|
||||
requirements:
|
||||
- SECU-04
|
||||
@@ -19,9 +19,9 @@ must_haves:
|
||||
- "Signature is computed over the payload JSON without the signature field, then added as a 'signature' field"
|
||||
- "Agent can verify the signature using the public key received at registration"
|
||||
artifacts:
|
||||
- path: "cameleer3-server-app/src/main/java/com/cameleer3/server/app/agent/SsePayloadSigner.java"
|
||||
- path: "cameleer-server-app/src/main/java/com/cameleer/server/app/agent/SsePayloadSigner.java"
|
||||
provides: "Component that signs SSE command payloads before delivery"
|
||||
- path: "cameleer3-server-app/src/main/java/com/cameleer3/server/app/agent/SseConnectionManager.java"
|
||||
- path: "cameleer-server-app/src/main/java/com/cameleer/server/app/agent/SseConnectionManager.java"
|
||||
provides: "Updated onCommandReady with signing before sendEvent"
|
||||
key_links:
|
||||
- from: "SseConnectionManager.onCommandReady"
|
||||
@@ -54,7 +54,7 @@ Output: All SSE command events carry verifiable Ed25519 signatures.
|
||||
@.planning/phases/04-security/04-RESEARCH.md
|
||||
@.planning/phases/04-security/04-01-SUMMARY.md
|
||||
|
||||
@cameleer3-server-app/src/main/java/com/cameleer3/server/app/agent/SseConnectionManager.java
|
||||
@cameleer-server-app/src/main/java/com/cameleer/server/app/agent/SseConnectionManager.java
|
||||
|
||||
<interfaces>
|
||||
<!-- From Plan 01 (will exist after execution): -->
|
||||
@@ -98,10 +98,10 @@ public record AgentCommand(String id, CommandType type, String payload, String a
|
||||
<task type="auto" tdd="true">
|
||||
<name>Task 1: SsePayloadSigner + signing integration in SseConnectionManager</name>
|
||||
<files>
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/agent/SsePayloadSigner.java,
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/agent/SseConnectionManager.java,
|
||||
cameleer3-server-app/src/test/java/com/cameleer3/server/app/agent/SsePayloadSignerTest.java,
|
||||
cameleer3-server-app/src/test/java/com/cameleer3/server/app/security/SseSigningIT.java
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/agent/SsePayloadSigner.java,
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/agent/SseConnectionManager.java,
|
||||
cameleer-server-app/src/test/java/com/cameleer/server/app/agent/SsePayloadSignerTest.java,
|
||||
cameleer-server-app/src/test/java/com/cameleer/server/app/security/SseSigningIT.java
|
||||
</files>
|
||||
<behavior>
|
||||
SsePayloadSigner unit tests:
|
||||
@@ -155,7 +155,7 @@ public record AgentCommand(String id, CommandType type, String payload, String a
|
||||
- NOTE: This test depends on Plan 02's bootstrap token and JWT auth being in place. If Plan 03 executes before Plan 02, the test will need the TestSecurityHelper or a different auth approach. Since both are Wave 2 but independent, document this: "If Plan 02 is not yet complete, use TestSecurityHelper from Plan 01's temporary permit-all config."
|
||||
</action>
|
||||
<verify>
|
||||
<automated>cd /c/Users/Hendrik/Documents/projects/cameleer3-server && mvn test -pl cameleer3-server-app -Dtest="SsePayloadSignerTest,SseSigningIT" -Dsurefire.reuseForks=false</automated>
|
||||
<automated>cd /c/Users/Hendrik/Documents/projects/cameleer-server && mvn test -pl cameleer-server-app -Dtest="SsePayloadSignerTest,SseSigningIT" -Dsurefire.reuseForks=false</automated>
|
||||
</verify>
|
||||
<done>
|
||||
- SsePayloadSigner signs JSON payloads with Ed25519 and adds signature field
|
||||
|
||||
@@ -22,11 +22,11 @@ tech-stack:
|
||||
|
||||
key-files:
|
||||
created:
|
||||
- cameleer3-server-app/src/main/java/com/cameleer3/server/app/agent/SsePayloadSigner.java
|
||||
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/agent/SsePayloadSignerTest.java
|
||||
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/security/SseSigningIT.java
|
||||
- cameleer-server-app/src/main/java/com/cameleer/server/app/agent/SsePayloadSigner.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/agent/SsePayloadSignerTest.java
|
||||
- cameleer-server-app/src/test/java/com/cameleer/server/app/security/SseSigningIT.java
|
||||
modified:
|
||||
- cameleer3-server-app/src/main/java/com/cameleer3/server/app/agent/SseConnectionManager.java
|
||||
- cameleer-server-app/src/main/java/com/cameleer/server/app/agent/SseConnectionManager.java
|
||||
|
||||
key-decisions:
|
||||
- "Signed payload parsed to JsonNode before passing to SseEmitter to avoid double-quoting raw JSON strings"
|
||||
@@ -73,10 +73,10 @@ _No REFACTOR commit needed -- implementation is clean and minimal._
|
||||
|
||||
## Files Created/Modified
|
||||
|
||||
- `cameleer3-server-app/.../agent/SsePayloadSigner.java` - Component that signs JSON payloads with Ed25519 and adds signature field
|
||||
- `cameleer3-server-app/.../agent/SseConnectionManager.java` - Updated onCommandReady to sign payload before SSE delivery
|
||||
- `cameleer3-server-app/.../agent/SsePayloadSignerTest.java` - 7 unit tests for signing behavior and edge cases
|
||||
- `cameleer3-server-app/.../security/SseSigningIT.java` - 2 integration tests for end-to-end signature verification
|
||||
- `cameleer-server-app/.../agent/SsePayloadSigner.java` - Component that signs JSON payloads with Ed25519 and adds signature field
|
||||
- `cameleer-server-app/.../agent/SseConnectionManager.java` - Updated onCommandReady to sign payload before SSE delivery
|
||||
- `cameleer-server-app/.../agent/SsePayloadSignerTest.java` - 7 unit tests for signing behavior and edge cases
|
||||
- `cameleer-server-app/.../security/SseSigningIT.java` - 2 integration tests for end-to-end signature verification
|
||||
|
||||
## Decisions Made
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
## Summary
|
||||
|
||||
This phase adds authentication and integrity protection to the Cameleer3 server. The implementation uses Spring Security 6.4.3 (managed by Spring Boot 3.4.3) with a custom `OncePerRequestFilter` for JWT validation, JDK 17 built-in Ed25519 for signing SSE payloads, and environment variable-based bootstrap tokens for agent registration. The approach is deliberately simple -- no OAuth2 resource server, no external identity provider, just symmetric HMAC JWTs for access control and Ed25519 signatures for payload integrity.
|
||||
This phase adds authentication and integrity protection to the Cameleer server. The implementation uses Spring Security 6.4.3 (managed by Spring Boot 3.4.3) with a custom `OncePerRequestFilter` for JWT validation, JDK 17 built-in Ed25519 for signing SSE payloads, and environment variable-based bootstrap tokens for agent registration. The approach is deliberately simple -- no OAuth2 resource server, no external identity provider, just symmetric HMAC JWTs for access control and Ed25519 signatures for payload integrity.
|
||||
|
||||
The existing codebase has clear integration points: `AgentRegistrationController.register()` already returns `serverPublicKey: null` as a placeholder, `SseConnectionManager.onCommandReady()` is the signing hook for SSE events, and `WebConfig` already defines excluded paths that align with the public endpoint list. Spring Security's `SecurityFilterChain` replaces the need for hand-rolled authorization logic -- endpoints are protected by default, with explicit `permitAll()` for health, register, and docs.
|
||||
|
||||
@@ -89,7 +89,7 @@ The existing codebase has clear integration points: `AgentRegistrationController
|
||||
- **Ed25519 library:** Use JDK built-in. Zero external dependencies, native performance, well-tested in JDK 17+.
|
||||
- **Refresh token storage:** Use stateless signed refresh tokens (also HMAC-signed JWTs with different claims/expiry). This avoids any in-memory storage for refresh tokens and scales naturally. The refresh token is just a JWT with `type=refresh`, `sub=agentId`, and 7-day expiry. On refresh, validate the refresh JWT, check agent still exists, issue new access JWT.
|
||||
|
||||
**Installation (add to cameleer3-server-app pom.xml):**
|
||||
**Installation (add to cameleer-server-app pom.xml):**
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
@@ -108,12 +108,12 @@ Note: If `spring-boot-starter-security` brings Nimbus transitively (via `spring-
|
||||
|
||||
### Recommended Project Structure
|
||||
```
|
||||
cameleer3-server-core/src/main/java/com/cameleer3/server/core/
|
||||
cameleer-server-core/src/main/java/com/cameleer/server/core/
|
||||
security/
|
||||
JwtService.java # Interface: createAccessToken, createRefreshToken, validateToken, extractAgentId
|
||||
Ed25519SigningService.java # Interface: sign(payload) -> signature, getPublicKeyBase64()
|
||||
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/
|
||||
security/
|
||||
JwtServiceImpl.java # Nimbus JOSE+JWT HMAC implementation
|
||||
Ed25519SigningServiceImpl.java # JDK Ed25519 keypair + signing implementation
|
||||
@@ -439,23 +439,23 @@ public boolean validateBootstrapToken(String provided) {
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| Framework | JUnit 5 + Spring Boot Test (spring-boot-starter-test) |
|
||||
| Config file | `cameleer3-server-app/src/test/resources/application-test.yml` |
|
||||
| Quick run command | `mvn test -pl cameleer3-server-app -Dtest=Security*Test -Dsurefire.reuseForks=false` |
|
||||
| Config file | `cameleer-server-app/src/test/resources/application-test.yml` |
|
||||
| Quick run command | `mvn test -pl cameleer-server-app -Dtest=Security*Test -Dsurefire.reuseForks=false` |
|
||||
| Full suite command | `mvn clean verify` |
|
||||
|
||||
### Phase Requirements to Test Map
|
||||
| Req ID | Behavior | Test Type | Automated Command | File Exists? |
|
||||
|--------|----------|-----------|-------------------|-------------|
|
||||
| SECU-01 | Protected endpoints reject requests without JWT; public endpoints accessible | integration | `mvn test -pl cameleer3-server-app -Dtest=SecurityFilterIT -Dsurefire.reuseForks=false` | No -- Wave 0 |
|
||||
| SECU-02 | Refresh endpoint issues new access JWT from valid refresh token | integration | `mvn test -pl cameleer3-server-app -Dtest=JwtRefreshIT -Dsurefire.reuseForks=false` | No -- Wave 0 |
|
||||
| SECU-03 | Ed25519 keypair generated at startup; public key in registration response | integration | `mvn test -pl cameleer3-server-app -Dtest=RegistrationSecurityIT -Dsurefire.reuseForks=false` | No -- Wave 0 |
|
||||
| SECU-04 | SSE payloads carry valid Ed25519 signature | integration | `mvn test -pl cameleer3-server-app -Dtest=SseSigningIT -Dsurefire.reuseForks=false` | No -- Wave 0 |
|
||||
| SECU-05 | Bootstrap token required for registration; rejects invalid/missing tokens | integration | `mvn test -pl cameleer3-server-app -Dtest=BootstrapTokenIT -Dsurefire.reuseForks=false` | No -- Wave 0 |
|
||||
| N/A | JWT creation, validation, expiry logic | unit | `mvn test -pl cameleer3-server-app -Dtest=JwtServiceTest -Dsurefire.reuseForks=false` | No -- Wave 0 |
|
||||
| N/A | Ed25519 signing and verification roundtrip | unit | `mvn test -pl cameleer3-server-app -Dtest=Ed25519SigningServiceTest -Dsurefire.reuseForks=false` | No -- Wave 0 |
|
||||
| SECU-01 | Protected endpoints reject requests without JWT; public endpoints accessible | integration | `mvn test -pl cameleer-server-app -Dtest=SecurityFilterIT -Dsurefire.reuseForks=false` | No -- Wave 0 |
|
||||
| SECU-02 | Refresh endpoint issues new access JWT from valid refresh token | integration | `mvn test -pl cameleer-server-app -Dtest=JwtRefreshIT -Dsurefire.reuseForks=false` | No -- Wave 0 |
|
||||
| SECU-03 | Ed25519 keypair generated at startup; public key in registration response | integration | `mvn test -pl cameleer-server-app -Dtest=RegistrationSecurityIT -Dsurefire.reuseForks=false` | No -- Wave 0 |
|
||||
| SECU-04 | SSE payloads carry valid Ed25519 signature | integration | `mvn test -pl cameleer-server-app -Dtest=SseSigningIT -Dsurefire.reuseForks=false` | No -- Wave 0 |
|
||||
| SECU-05 | Bootstrap token required for registration; rejects invalid/missing tokens | integration | `mvn test -pl cameleer-server-app -Dtest=BootstrapTokenIT -Dsurefire.reuseForks=false` | No -- Wave 0 |
|
||||
| N/A | JWT creation, validation, expiry logic | unit | `mvn test -pl cameleer-server-app -Dtest=JwtServiceTest -Dsurefire.reuseForks=false` | No -- Wave 0 |
|
||||
| N/A | Ed25519 signing and verification roundtrip | unit | `mvn test -pl cameleer-server-app -Dtest=Ed25519SigningServiceTest -Dsurefire.reuseForks=false` | No -- Wave 0 |
|
||||
|
||||
### Sampling Rate
|
||||
- **Per task commit:** `mvn test -pl cameleer3-server-app -Dsurefire.reuseForks=false`
|
||||
- **Per task commit:** `mvn test -pl cameleer-server-app -Dsurefire.reuseForks=false`
|
||||
- **Per wave merge:** `mvn clean verify`
|
||||
- **Phase gate:** Full suite green before `/gsd:verify-work`
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@ created: 2026-03-11
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| **Framework** | JUnit 5 + Spring Boot Test + Spring Security Test |
|
||||
| **Config file** | cameleer3-server-app/src/test/resources/application-test.yml |
|
||||
| **Quick run command** | `mvn test -pl cameleer3-server-app -Dtest="Security*,Jwt*,Bootstrap*,Ed25519*" -Dsurefire.reuseForks=false` |
|
||||
| **Config file** | cameleer-server-app/src/test/resources/application-test.yml |
|
||||
| **Quick run command** | `mvn test -pl cameleer-server-app -Dtest="Security*,Jwt*,Bootstrap*,Ed25519*" -Dsurefire.reuseForks=false` |
|
||||
| **Full suite command** | `mvn clean verify` |
|
||||
| **Estimated runtime** | ~60 seconds |
|
||||
|
||||
@@ -27,7 +27,7 @@ created: 2026-03-11
|
||||
|
||||
## Sampling Rate
|
||||
|
||||
- **After every task commit:** Run `mvn test -pl cameleer3-server-app -Dsurefire.reuseForks=false`
|
||||
- **After every task commit:** Run `mvn test -pl cameleer-server-app -Dsurefire.reuseForks=false`
|
||||
- **After every plan wave:** Run `mvn clean verify`
|
||||
- **Before `/gsd:verify-work`:** Full suite must be green
|
||||
- **Max feedback latency:** 60 seconds
|
||||
@@ -38,13 +38,13 @@ created: 2026-03-11
|
||||
|
||||
| Task ID | Plan | Wave | Requirement | Test Type | Automated Command | File Exists | Status |
|
||||
|---------|------|------|-------------|-----------|-------------------|-------------|--------|
|
||||
| 04-01-01 | 01 | 1 | SECU-03 | unit | `mvn test -pl cameleer3-server-app -Dtest=Ed25519SigningServiceTest -Dsurefire.reuseForks=false` | ❌ W0 | ⬜ pending |
|
||||
| 04-01-02 | 01 | 1 | SECU-01 | unit | `mvn test -pl cameleer3-server-app -Dtest=JwtServiceTest -Dsurefire.reuseForks=false` | ❌ W0 | ⬜ pending |
|
||||
| 04-01-03 | 01 | 1 | SECU-05 | integration | `mvn test -pl cameleer3-server-app -Dtest=BootstrapTokenIT -Dsurefire.reuseForks=false` | ❌ W0 | ⬜ pending |
|
||||
| 04-01-04 | 01 | 1 | SECU-01 | integration | `mvn test -pl cameleer3-server-app -Dtest=SecurityFilterIT -Dsurefire.reuseForks=false` | ❌ W0 | ⬜ pending |
|
||||
| 04-01-05 | 01 | 1 | SECU-02 | integration | `mvn test -pl cameleer3-server-app -Dtest=JwtRefreshIT -Dsurefire.reuseForks=false` | ❌ W0 | ⬜ pending |
|
||||
| 04-01-06 | 01 | 1 | SECU-04 | integration | `mvn test -pl cameleer3-server-app -Dtest=SseSigningIT -Dsurefire.reuseForks=false` | ❌ W0 | ⬜ pending |
|
||||
| 04-01-07 | 01 | 1 | N/A | integration | `mvn test -pl cameleer3-server-app -Dtest=RegistrationSecurityIT -Dsurefire.reuseForks=false` | ❌ W0 | ⬜ pending |
|
||||
| 04-01-01 | 01 | 1 | SECU-03 | unit | `mvn test -pl cameleer-server-app -Dtest=Ed25519SigningServiceTest -Dsurefire.reuseForks=false` | ❌ W0 | ⬜ pending |
|
||||
| 04-01-02 | 01 | 1 | SECU-01 | unit | `mvn test -pl cameleer-server-app -Dtest=JwtServiceTest -Dsurefire.reuseForks=false` | ❌ W0 | ⬜ pending |
|
||||
| 04-01-03 | 01 | 1 | SECU-05 | integration | `mvn test -pl cameleer-server-app -Dtest=BootstrapTokenIT -Dsurefire.reuseForks=false` | ❌ W0 | ⬜ pending |
|
||||
| 04-01-04 | 01 | 1 | SECU-01 | integration | `mvn test -pl cameleer-server-app -Dtest=SecurityFilterIT -Dsurefire.reuseForks=false` | ❌ W0 | ⬜ pending |
|
||||
| 04-01-05 | 01 | 1 | SECU-02 | integration | `mvn test -pl cameleer-server-app -Dtest=JwtRefreshIT -Dsurefire.reuseForks=false` | ❌ W0 | ⬜ pending |
|
||||
| 04-01-06 | 01 | 1 | SECU-04 | integration | `mvn test -pl cameleer-server-app -Dtest=SseSigningIT -Dsurefire.reuseForks=false` | ❌ W0 | ⬜ pending |
|
||||
| 04-01-07 | 01 | 1 | N/A | integration | `mvn test -pl cameleer-server-app -Dtest=RegistrationSecurityIT -Dsurefire.reuseForks=false` | ❌ W0 | ⬜ pending |
|
||||
|
||||
*Status: ⬜ pending · ✅ green · ❌ red · ⚠️ flaky*
|
||||
|
||||
|
||||
@@ -39,19 +39,19 @@ All truths drawn from PLAN frontmatter must_haves across plans 01, 02, and 03.
|
||||
|
||||
| Artifact | Provides | Status | Details |
|
||||
|----------|----------|--------|---------|
|
||||
| `cameleer3-server-core/.../security/JwtService.java` | JWT interface: createAccessToken, createRefreshToken, validateAndExtractAgentId, validateRefreshToken | VERIFIED | 49 lines, substantive interface with 4 methods |
|
||||
| `cameleer3-server-core/.../security/Ed25519SigningService.java` | Ed25519 interface: sign(payload), getPublicKeyBase64() | VERIFIED | 29 lines, substantive interface with 2 methods |
|
||||
| `cameleer3-server-app/.../security/JwtServiceImpl.java` | Nimbus JOSE+JWT HMAC-SHA256 implementation | VERIFIED | 120 lines; uses `MACSigner`/`MACVerifier`, ephemeral 256-bit secret, correct claims |
|
||||
| `cameleer3-server-app/.../security/Ed25519SigningServiceImpl.java` | JDK 17 Ed25519 KeyPairGenerator implementation | VERIFIED | 54 lines; `KeyPairGenerator.getInstance("Ed25519")`, `Signature.getInstance("Ed25519")`, Base64-encoded output |
|
||||
| `cameleer3-server-app/.../security/BootstrapTokenValidator.java` | Constant-time bootstrap token validation with dual-token rotation | VERIFIED | 50 lines; `MessageDigest.isEqual()`, checks current and previous token, null/blank guard |
|
||||
| `cameleer3-server-app/.../security/SecurityProperties.java` | Config binding with env var mapping | VERIFIED | 48 lines; `@ConfigurationProperties(prefix="security")`; all 4 fields with defaults |
|
||||
| `cameleer3-server-app/.../security/SecurityBeanConfig.java` | Bean wiring with fail-fast validation | VERIFIED | 43 lines; `@EnableConfigurationProperties`, all 3 service beans, `InitializingBean` check |
|
||||
| `cameleer3-server-app/.../security/JwtAuthenticationFilter.java` | OncePerRequestFilter extracting JWT from header or query param | VERIFIED | 72 lines; extracts from `Authorization: Bearer` then `?token=` query param; sets `SecurityContextHolder` |
|
||||
| `cameleer3-server-app/.../security/SecurityConfig.java` | SecurityFilterChain with permitAll for public paths, authenticated for rest | VERIFIED | 54 lines; stateless, CSRF disabled, correct permitAll list, `addFilterBefore` JwtAuthenticationFilter |
|
||||
| `cameleer3-server-app/.../controller/AgentRegistrationController.java` | Updated register endpoint with bootstrap token validation, JWT issuance, public key; refresh endpoint | VERIFIED | 230 lines; both `/register` and `/{id}/refresh` endpoints fully wired |
|
||||
| `cameleer3-server-app/.../agent/SsePayloadSigner.java` | Component that signs SSE command payloads | VERIFIED | 77 lines; `@Component`, signs then adds field, defensive null/blank handling |
|
||||
| `cameleer3-server-app/.../agent/SseConnectionManager.java` | Updated onCommandReady with signing before sendEvent | VERIFIED | `onCommandReady()` calls `ssePayloadSigner.signPayload()`, parses to `JsonNode` to avoid double-quoting |
|
||||
| `cameleer3-server-app/.../resources/application.yml` | Security config with env var mapping | VERIFIED | `security.bootstrap-token: ${CAMELEER_AUTH_TOKEN:}` and `security.bootstrap-token-previous: ${CAMELEER_AUTH_TOKEN_PREVIOUS:}` present |
|
||||
| `cameleer-server-core/.../security/JwtService.java` | JWT interface: createAccessToken, createRefreshToken, validateAndExtractAgentId, validateRefreshToken | VERIFIED | 49 lines, substantive interface with 4 methods |
|
||||
| `cameleer-server-core/.../security/Ed25519SigningService.java` | Ed25519 interface: sign(payload), getPublicKeyBase64() | VERIFIED | 29 lines, substantive interface with 2 methods |
|
||||
| `cameleer-server-app/.../security/JwtServiceImpl.java` | Nimbus JOSE+JWT HMAC-SHA256 implementation | VERIFIED | 120 lines; uses `MACSigner`/`MACVerifier`, ephemeral 256-bit secret, correct claims |
|
||||
| `cameleer-server-app/.../security/Ed25519SigningServiceImpl.java` | JDK 17 Ed25519 KeyPairGenerator implementation | VERIFIED | 54 lines; `KeyPairGenerator.getInstance("Ed25519")`, `Signature.getInstance("Ed25519")`, Base64-encoded output |
|
||||
| `cameleer-server-app/.../security/BootstrapTokenValidator.java` | Constant-time bootstrap token validation with dual-token rotation | VERIFIED | 50 lines; `MessageDigest.isEqual()`, checks current and previous token, null/blank guard |
|
||||
| `cameleer-server-app/.../security/SecurityProperties.java` | Config binding with env var mapping | VERIFIED | 48 lines; `@ConfigurationProperties(prefix="security")`; all 4 fields with defaults |
|
||||
| `cameleer-server-app/.../security/SecurityBeanConfig.java` | Bean wiring with fail-fast validation | VERIFIED | 43 lines; `@EnableConfigurationProperties`, all 3 service beans, `InitializingBean` check |
|
||||
| `cameleer-server-app/.../security/JwtAuthenticationFilter.java` | OncePerRequestFilter extracting JWT from header or query param | VERIFIED | 72 lines; extracts from `Authorization: Bearer` then `?token=` query param; sets `SecurityContextHolder` |
|
||||
| `cameleer-server-app/.../security/SecurityConfig.java` | SecurityFilterChain with permitAll for public paths, authenticated for rest | VERIFIED | 54 lines; stateless, CSRF disabled, correct permitAll list, `addFilterBefore` JwtAuthenticationFilter |
|
||||
| `cameleer-server-app/.../controller/AgentRegistrationController.java` | Updated register endpoint with bootstrap token validation, JWT issuance, public key; refresh endpoint | VERIFIED | 230 lines; both `/register` and `/{id}/refresh` endpoints fully wired |
|
||||
| `cameleer-server-app/.../agent/SsePayloadSigner.java` | Component that signs SSE command payloads | VERIFIED | 77 lines; `@Component`, signs then adds field, defensive null/blank handling |
|
||||
| `cameleer-server-app/.../agent/SseConnectionManager.java` | Updated onCommandReady with signing before sendEvent | VERIFIED | `onCommandReady()` calls `ssePayloadSigner.signPayload()`, parses to `JsonNode` to avoid double-quoting |
|
||||
| `cameleer-server-app/.../resources/application.yml` | Security config with env var mapping | VERIFIED | `security.bootstrap-token: ${CAMELEER_AUTH_TOKEN:}` and `security.bootstrap-token-previous: ${CAMELEER_AUTH_TOKEN_PREVIOUS:}` present |
|
||||
|
||||
### Key Link Verification
|
||||
|
||||
|
||||
Reference in New Issue
Block a user