chore: initialize from backend template 0a6dd0e
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
# Web Security Boundary Implementation Plan
|
||||
|
||||
> **Execution:** Follow test-driven development and request an independent read-only review before
|
||||
> advancing to Redis session/CSRF.
|
||||
|
||||
**Goal:** Make JWT/JWKS and CORS filter-boundary behavior hermetic, release-blocking, and impossible
|
||||
to skip silently.
|
||||
|
||||
**Architecture:** Tests remain in inbound-web, use only existing dependencies, and cross the real
|
||||
Spring Security filter chain. A tagged Gradle task isolates them from the ordinary unit suite.
|
||||
|
||||
**Tech Stack:** Java 21, Spring Boot 4.0.0, Spring Security 7, Nimbus JOSE JWT, JDK HttpServer,
|
||||
MockMvc, Gradle 9.
|
||||
|
||||
### Task 1: Dedicated No-Skip Test Gate
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/adapter/inbound/web/build.gradle`
|
||||
|
||||
- [x] Register `webSecurityBoundaryTest` over `sourceSets.test` with tag inclusion, no-discovery
|
||||
failure, no up-to-date reuse, UTC, and a root-suite skipped-count guard.
|
||||
- [x] Exclude `security-boundary` from ordinary `test` and require the dedicated task from `check`.
|
||||
- [x] Confirm 13 tagged tests are discovered with zero skips and no dependency/lock entry is added.
|
||||
|
||||
### Task 2: JWT/JWKS RED Contracts
|
||||
|
||||
**Files:**
|
||||
- Create: `src/adapter/inbound/web/src/test/java/dev/caskeleton/adapter/inbound/web/auth/JwtJwksSecurityFilterIntegrationTest.java`
|
||||
|
||||
- [x] Add a loopback OIDC discovery/JWKS server with request counters and deterministic 503 mode.
|
||||
- [x] Add RS256 token generation using ephemeral keys and conspicuous secret sentinels.
|
||||
- [x] Prove lazy startup and valid bearer-to-principal conversion.
|
||||
- [x] Prove exact expiry, issuer, audience, signature, unknown-kid, and JWKS-outage envelopes/headers.
|
||||
- [x] Prove same-context recovery after a first-request JWKS 503 and prove mismatched discovery
|
||||
metadata reaches the safe 500 `INTERNAL_AUTH_MISCONFIGURATION` filter boundary.
|
||||
- [x] Run the dedicated task and record RED: unknown kid was classified as signature failure and a
|
||||
first-request JWKS 503 escaped as `JwtDecoderInitializationException`/`AuthenticationServiceException`.
|
||||
|
||||
### Task 3: CORS RED Contracts
|
||||
|
||||
**Files:**
|
||||
- Create: `src/adapter/inbound/web/src/test/java/dev/caskeleton/adapter/inbound/web/auth/CorsSecurityFilterIntegrationTest.java`
|
||||
|
||||
- [x] Prove approved credentialed preflight bypasses bearer authentication and emits exact headers.
|
||||
- [x] Prove denied origin, disabled CORS, wildcard-without-credentials, and approved actual-origin behavior.
|
||||
- [x] Assert bounded `Vary` behavior and no reflection of an unapproved sentinel origin.
|
||||
- [x] Run the dedicated task: all five CORS filter-boundary contracts passed without production changes.
|
||||
|
||||
### Task 4: Minimal Production Fixes and Verification
|
||||
|
||||
- [x] If RED exposes a production mismatch, change only the owning classifier/security configuration
|
||||
and keep stable error-code/header contracts intact.
|
||||
- [x] Run `webSecurityBoundaryTest`, ordinary inbound-web `test`, module static analysis, `check`,
|
||||
dependency-lock verification, architecture verification, and `git diff --check`.
|
||||
- [x] Request an independent read-only review; add the requested same-context recovery and non-I/O
|
||||
initialization-failure contracts, and bind the loopback server to an explicit IPv4 address.
|
||||
Reference in New Issue
Block a user