chore: update configuration and Docker setup for JWT and test results
ci/woodpecker/push/build-arm Pipeline was successful

Enhanced the .gitignore to exclude test results and updated the Dockerfile to include a new entrypoint script for improved container initialization. Refactored JWT configuration to support additional parameters for automatic refresh intervals, ensuring better control over token management. Updated the ConfigurationResolver to enforce required environment variables without hardcoded fallbacks, enhancing security and flexibility.
This commit is contained in:
Oleksandr Bezdieniezhnykh
2026-05-15 03:23:23 +03:00
parent 7025f4d075
commit 78dea8ebab
40 changed files with 1990 additions and 510 deletions
+30 -8
View File
@@ -87,11 +87,11 @@ All symbol-level claims reconcile. ✓
| F2 Mission create/read/update | Existence check on `vehicle_id` returns `ArgumentException → 400` (spec wants 404) | `FlightService.CreateFlight / UpdateFlight``aircraftExists` check throws `ArgumentException("Aircraft {id} not found")` → middleware → 400 | ✓ matches; spec divergence carry-forward |
| F3 Mission cascade-delete | Order: `map_objects → waypoints/media/annotations/detection → waypoints → missions`. NOT transaction-wrapped. Post-B7: no orthophoto/gps_correction branches | `FlightService.DeleteFlight` order today: `map_objects → gps_corrections → orthophotos → waypoints/media/annotations/detection → waypoints → flights`. NOT transaction-wrapped | ✓ B7 removes the two extra branches |
| F4 Waypoint create/read/update/delete | Delete walks `media/annotations/detection`, post-B7 no `gps_corrections` branch; `UpdateWaypoint` is full overwrite | `WaypointService.DeleteWaypoint` walks `media/annotations/detection` AND `gps_corrections` today; `UpdateWaypoint` is full overwrite | ✓ B7 removes `gps_corrections` branch |
| F5 JWT validation | HS256, shared secret, `ValidateIssuer/ValidateAudience = false`, `ClockSkew = 1 minute`, single `"FL"` policy post-B7 | `JwtExtensions` matches exactly; today has BOTH `"FL"` and `"GPS"` policies | ✓ B7 drops `"GPS"` |
| F6 Startup + migration | `Program.cs` builds host → resolves `DATABASE_URL` (with `ConvertPostgresUrl`) → `JWT_SECRET` → registers scoped services → migrates → starts. Pipeline: `ErrorHandlingMiddleware FIRST → Cors → Authentication → Authorization → Swagger → MapControllers → MapGet("/health") → Run` | `Program.cs` matches exactly; service registration is `FlightService, WaypointService, AircraftService` today instead of `Mission/Waypoint/VehicleService` | ✓ B5+B6 rename + DI re-registration |
| F5 JWT validation | **REISSUED 2026-05-14** — ECDSA-SHA256 against admin's JWKS (cached via `ConfigurationManager<JsonWebKeySet>` with `HttpDocumentRetriever{RequireHttps=true}` + private `JwksRetriever`); `ValidateIssuer = true` against `JWT_ISSUER`; `ValidateAudience = true` against `JWT_AUDIENCE`; `ClockSkew = 30 seconds`; `ValidAlgorithms = [EcdsaSha256]`; `RequireSignedTokens = true`; `RequireExpirationTime = true`. Single `"FL"` policy post-B7 | `Auth/JwtExtensions.cs` matches the reissued claim exactly; today has BOTH `"FL"` and `"GPS"` policies | ✓ B7 drops `"GPS"`. **The previous verdict ("matches exactly" against the HS256 / shared-secret doc) was wrong** — the underlying docs were stale; corrected via the 2026-05-14 re-verification pass and rewritten in `modules/auth.md`, `components/05_identity/description.md`, `diagrams/flows/flow_jwt_validation.md`, `architecture.md` § 7 + Tech Stack, `system-flows.md` Cross-cutting #1 + F5, and `00_problem/*` (see § 4.3 below) |
| F6 Startup + migration | **REISSUED 2026-05-14**`Program.cs` builds host → `ConfigurationResolver.ResolveRequiredOrThrow` resolves `DATABASE_URL` (with `ConvertPostgresUrl`) → resolves `JWT_ISSUER` + `JWT_AUDIENCE` + `JWT_JWKS_URL` (all required, no fallback) → registers scoped services + JWT bearer + JWKS `ConfigurationManager` → reads `CorsConfig:AllowedOrigins` + `CorsConfig:AllowAnyOrigin``CorsConfigurationValidator.EnsureSafeForEnvironment` (throws in Production with implicit-permissive config) → registers CORS policy (permissive OR `WithOrigins`) → migrates → starts. Pipeline: `ErrorHandlingMiddleware FIRST → Cors → Authentication → Authorization → Swagger → MapControllers → MapGet("/health") → Run`. May emit `PermissiveDefaultWarning` startup log when implicit-permissive CORS applies | `Program.cs` matches the reissued claim exactly; service registration is `FlightService, WaypointService, AircraftService` today instead of `Mission/Waypoint/VehicleService` | ✓ B5+B6 rename + DI re-registration. **The previous verdict ("matches exactly" against docs claiming hardcoded `JWT_SECRET` fallback + unconditional permissive CORS) was wrong** — corrected via the 2026-05-14 re-verification pass and rewritten in `modules/program.md`, `components/07_host/description.md`, `diagrams/flows/flow_startup_migration.md`, `architecture.md` § 3 deployment table + ADR-005, and `system-flows.md` F6 |
| F7 Health probe | `MapGet("/health", () => Results.Ok(new { status = "healthy" }))`, anonymous | identical | ✓ no rename gap |
All flow claims reconcile. ✓
All flow claims reconcile after the 2026-05-14 reissue. ✓
## 4. Drift NOT covered by the rename mapping
@@ -117,7 +117,29 @@ These are real findings. **Items in § 4.1 were corrected inline as part of this
|---|-------|---------|------------------|
| F1 | Cascade-delete error scenario in `diagrams/flows/flow_mission_cascade_delete.md` § Error Scenarios | Text references "step 7" (a successful `DELETE FROM missions`) but the cascade order list above it numbers steps 15 and the data-flow table numbers them 18. Three different numberings in one file | Pre-existing inconsistency; minor; correcting it would also need a numbering decision the user might prefer to make once globally |
| F2 | `module-layout.md` § Per-Component Mapping — `05_identity` Public API | Lists only the `"FL"` policy as the public API surface. Code today also exposes `"GPS"`. Forward-looking is correct (B7 will drop `"GPS"`); the `05_identity/description.md` already mentions the dual-policy state in its forward-looking note. Decision: leave `module-layout.md` forward-looking-only (consistent with the rest of the file), OR add a one-line "today also exposes `\"GPS\"` — see B7" caveat | Editorial choice for the user — both readings are defensible |
| F3 | The pre-existing carry-forward divergences in `00_discovery.md` § Spec ↔ Code Divergences (Geopoint shape, error envelope `errors` field, Swagger / CORS unconditional, etc.) | All real, all already documented with their resolution path (this Epic vs out-of-Epic). No new finding here | These are the *intentional* carry-forward items. They are the agenda for future Epics; not in scope for verification |
| F3 | The pre-existing carry-forward divergences in `00_discovery.md` § Spec ↔ Code Divergences (Geopoint shape, error envelope `errors` field, Swagger unconditional, etc.) **note: "CORS unconditional" was REMOVED from this list on 2026-05-14**. CORS is gated by `Infrastructure/CorsConfigurationValidator.cs`; it throws in Production with implicit-permissive config and falls back to permissive (with `PermissiveDefaultWarning`) only in non-Production. See § 4.3 below | All remaining items are real, already documented with their resolution path | These are the *intentional* carry-forward items |
### 4.3 Re-verification pass on 2026-05-14 (targeted)
While preparing autodev Step 4 (Code Testability Revision), a targeted code-level cross-check of `Auth/JwtExtensions.cs`, `Program.cs`, `Infrastructure/{ConfigurationResolver, CorsConfigurationValidator}.cs`, `Database/DatabaseMigrator.cs`, and `Services/*.cs` against the corresponding `_docs/` artifacts surfaced that the original § 3 verdicts for F5 (JWT) and F6 (Startup) had been performed **doc-vs-doc** rather than against actual source. The actual code state is materially different from what the docs described. The findings were captured in `_docs/02_document/05_drift_findings_2026-05-14.md`; the doc revisions applied in this pass:
| Doc | Sections rewritten |
|-----|--------------------|
| `modules/auth.md` | Full rewrite — ECDSA + JWKS + `ConfigurationManager` + iss/aud + 30s skew + alg pin; no fallback |
| `modules/program.md` | Internal Logic block; Configuration table (6 keys); Security; External Integrations; Notes |
| `modules/database.md` | Internal Logic — explicit `TIMESTAMP` (not `TIMESTAMPTZ`), explicit `REFERENCES`, explicit `DEFAULT` clauses |
| `components/05_identity/description.md` | Full rewrite — same scope as `modules/auth.md` |
| `components/07_host/description.md` | Header source-of-truth note; Implementation Details (Configuration table + CORS gating); Caveats |
| `diagrams/flows/flow_jwt_validation.md` | Full rewrite — new sequence with JWKS resolver + algorithm-pin step + iss/aud branches |
| `diagrams/flows/flow_startup_migration.md` | Preconditions + sequence + flowchart + data-flow + error-scenarios — 4 required env vars + CORS gate |
| `architecture.md` | Architecture Vision; § 5 External Integrations; § 7 Security Architecture; § 3 Environment-specific config table; Tech Stack JWT row; ADR-005 (scope reduced) |
| `data_model.md` | § 5 ERD — column-type annotations; § 6 Owned-table invariants — explicit FK / TIMESTAMP notes |
| `system-flows.md` | Cross-cutting #1 (JWT); F5 sequence + error table; F6 sequence + error table |
| `04_verification_log.md` (this file) | § 3 rows F5 + F6 reissued; § 4.2 row F3 corrected; this § 4.3 block added |
| `00_problem/*` (Phase 2 — next session) | AC-5 group, AC-6.1/6.2, AC-9.1, AC-1.5/1.6/2.3, E1, E3, E4, E9 — see `05_drift_findings_2026-05-14.md` Phase 2 |
| `_docs/02_document/tests/*` (Phase 2 — next session) | environment.md (JWKS mock), test-data.md, blackbox-tests.md (case-insensitive + ordering), security-tests.md (full NFT-SEC revision), resilience-tests.md (NFT-RES-05 + NFT-RES-07), traceability-matrix.md — see drift findings Phase 2 |
**Root cause** (recorded in `_autodev_state.md` for the retrospective): the prior verification step did doc-vs-doc consistency checks for these areas instead of opening the actual `.cs` files. The docs were internally consistent describing a stale HS256 / shared-secret / permissive-CORS / dev-fallback world that no longer exists in code. Subsequent verification passes (Step 4 prep, this reissue) must open source files for any flow whose verdict is "matches exactly" and explicitly note which files were read.
## 5. Stale-folder check (resolved)
@@ -142,9 +164,9 @@ The git status snapshot at session start showed 11 untracked component folders u
## 7. Summary
- The forward-looking documentation is **internally consistent** with respect to the rename + GPS-Denied removal it describes (B5B12).
- It is **consistent with the actual pre-rename code** when read through the rename mapping documented in § 0 — every counted symbol, signature, route, and flow reconciles.
- One **systematic doc-internal inconsistency** was found and fixed: the global error envelope's wire-shape case-style was misstated as PascalCase across 8 files when the middleware actually emits camelCase. The unrelated divergences (missing `errors` field, dead `ErrorResponse` DTO) remain as carry-forward concerns and are now stated correctly.
- It is **consistent with the actual pre-rename code** when read through the rename mapping documented in § 0 — every counted symbol, signature, route, and flow reconciles, after the 2026-05-14 reissue corrected the F5 (JWT) and F6 (Startup) flow descriptions to match actual code.
- One **systematic doc-internal inconsistency** was found and fixed in the initial pass: the global error envelope's wire-shape case-style was misstated as PascalCase across 8 files when the middleware actually emits camelCase.
- One **doc-vs-code drift** was found and fixed in the 2026-05-14 reissue: the JWT model (ECDSA + JWKS + iss/aud + 30s skew + alg pin, fail-fast on missing env), the configuration model (`ResolveRequiredOrThrow` — no hardcoded fallbacks), the CORS model (gated; Production hard-fail), and the DB schema details (TIMESTAMP, REFERENCES, DEFAULTs). The downstream test-spec re-issue is queued for the next autodev session (Phase 2 in `05_drift_findings_2026-05-14.md`).
- No hallucinated entities or methods. No missing module or component coverage.
- Two minor editorial concerns (F1, F2) are flagged but not auto-fixed — confirm with user.
**Outcome**: docs are accurate as the spec for B5B12. Ready to proceed to Step 4.5 (Glossary & Architecture Vision).
**Outcome**: docs are now accurate as the spec for B5B12 AND faithful to the actual current behavior of the JWT / config / CORS / DB-schema surfaces. The next autodev pass continues from Phase 2 (test-spec scoped re-issue), then Phase 3 (resume Step 4 — Code Testability Revision).