Files
Oleksandr Bezdieniezhnykh 9cfd80babe
ci/woodpecker/push/01-test Pipeline was successful
ci/woodpecker/push/02-build-push Pipeline was successful
[AZ-495] [AZ-496] Cycle 3 batch 1: doc convention + AspNetCore 8.0.25
AZ-495 (1 SP): formalize the modules-only documentation convention for
the WebApi component. _docs/02_document/module-layout.md now carries an
explicit Documentation Layout section anchoring WebApi docs at
modules/api_program.md; the components/06_web_api/ folder is
intentionally absent. .cursor/skills/new-task/SKILL.md Step 4 directs
future agents at the correct path. Cycle-1 + cycle-2 F1 findings in the
two batch-review files are marked RESOLVED with back-reference to
AZ-495. Cycle-2 retrospective decision-item list F1 updated.

AZ-496 (2 SP): bump Microsoft.AspNetCore.OpenApi and JwtBearer in
SatelliteProvider.Api.csproj from 8.0.21 to 8.0.25, closing CVE-
2026-26130 (SignalR DoS - not reachable in this app, but the runtime
patch is the recommended hardening per cycle-1 D1 + cycle-2 D3).
SatelliteProvider.Tests.csproj has no direct JwtBearer reference - it
consumes JwtBearer transitively via ProjectReference to Api, so no
edit needed there. Dockerfiles use floating mcr.microsoft.com/
dotnet/aspnet:8.0 / sdk:8.0 / runtime:8.0 tags which auto-resolve to
>= 8.0.25 on rebuild. Security artifacts (dependency_scan.md,
security_report.md) and current-state docs (module-layout.md,
architecture.md, modules/api_program.md, modules/tests_unit.md)
updated to reflect 8.0.25.

Batch report + code review report (verdict PASS_WITH_WARNINGS with 2
Low findings, neither blocking) written under _docs/03_implementation.

Test suite gate deferred to Step 16 (Final Test Run) per implement
skill convention. Patch-level bump within .NET 8 LTS; regression risk
very low.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 01:24:48 +03:00

6.2 KiB

Code Review Report — Batch 01 cycle 2

Batch: AZ-487 (JWT validation baseline) Date: 2026-05-11 Verdict: PASS_WITH_WARNINGS

Findings

# Severity Category File:Line Title
1 Low Style _docs/02_document/components/01_web_api/description.md Task spec referenced a doc path that does not exist in the codebase
2 Low Security SatelliteProvider.Api/appsettings.Development.json Dev-only JWT secret placeholder is committed (intentional per spec)

Finding Details

F1: Task spec referenced a doc path that does not exist in the codebase (Low / Style) — RESOLVED in cycle 3 (AZ-495)

  • Location: _docs/02_document/components/01_web_api/description.md (referenced; does not exist)
  • Description: The AZ-487 task spec lists _docs/02_document/components/01_web_api/description.md as a doc to update. The codebase's component-doc folders are 01_common, 02_data_access, 03_tile_downloader, 04_region_processing, 05_route_management — there is no 01_web_api folder. The WebApi component's documentation lives in _docs/02_document/modules/api_program.md.
  • Suggestion: Either (a) create the missing folder with a brief stub that defers to api_program.md, or (b) update the task spec for AZ-488 to point at modules/api_program.md and acknowledge that WebApi has no components/* folder. This batch chose (b) — updated architecture.md § Architecture Vision + § Security Architecture and modules/api_program.md. Surface to user for a doc-organization decision.
  • Task: AZ-487
  • Resolution (AZ-495, cycle 3): Option B formalized as canonical convention. _docs/02_document/module-layout.md § Documentation Layout now explicitly states WebApi has no components/* folder; documentation anchor is modules/api_program.md. The .cursor/skills/new-task/SKILL.md Step 4 (Codebase Analysis) directs future agents at the correct path. Finding will not recur.

F2: Dev-only JWT secret placeholder is committed (Low / Security)

  • Location: SatelliteProvider.Api/appsettings.Development.json
  • Description: The dev placeholder DEV-ONLY-DO-NOT-USE-IN-PROD-replace-with-real-secret-via-JWT_SECRET-env-var (78 bytes) is committed to the repo. Anyone with read access could mint a token signed with that secret. The mitigations (per task spec) are: (i) only loaded when ASPNETCORE_ENVIRONMENT=Development, (ii) the JWT_SECRET env var overrides it whenever set, (iii) the placeholder text itself signals it must be replaced.
  • Suggestion: Accept as-is for dev ergonomics; production environments must set JWT_SECRET (validated in scripts/run-tests.sh and at startup). Document on the README that this dev placeholder is intentional.
  • Task: AZ-487

Phase Notes

Phase 1 — Context Loading

  • Task spec read: _docs/02_tasks/todo/AZ-487_jwt_validation_baseline.md
  • Suite contract referenced: suite/_docs/10_auth.md (consumed via implementation, not modified)
  • Module layout, architecture doc, existing test patterns reviewed.

Phase 2 — Spec Compliance

All 8 acceptance criteria have at least one automated test:

AC Description Test
AC-1 Anonymous → 401 JwtIntegrationTests.AnonymousRequest_To_AnyEndpoint_Returns401
AC-2 Expired → 401 JwtIntegrationTests.ExpiredToken_Returns401
AC-3 Invalid signature → 401 JwtIntegrationTests.InvalidSignature_Returns401
AC-4 Valid token reaches handler JwtIntegrationTests.ValidToken_Returns200_OnHealthyEndpoint
AC-5 Missing/short secret → fail fast AuthenticationServiceCollectionExtensionsTests.AddSatelliteJwt_ThrowsOnMissingSecret/Empty/Short
AC-6 HttpContext.User exposes claims JwtTokenFactoryTests.Create_WithExtraClaims_PropagatesClaimsThroughValidation (exercises same JwtSecurityTokenHandler.ValidateToken path JwtBearer uses to populate HttpContext.User)
AC-7 Swagger Authorize button JwtIntegrationTests.SwaggerDocument_AdvertisesBearerSecurityScheme (OpenAPI document declares Bearer security scheme)
AC-8 All existing tests pass Verified at Step 11 (test-run gate); shared HttpClient attaches default Bearer token in IntegrationTests/Program.cs

Contract verification: AZ-487 is a consumer of suite/_docs/10_auth.md. The implementation matches the consumed contract (HS256, ≥32-byte HMAC key, no issuer/audience validation, expiration required).

Phase 3 — Code Quality

  • New code follows SRP (AuthenticationServiceCollectionExtensions does one thing).
  • Tests follow AAA pattern with explicit comments (matches project style).
  • No bare catches introduced. The pre-existing empty catch in IntegrationTests/Program.cs::WaitForApiReady is out of scope (pre-existing, not modified).
  • No comments narrating obvious code.

Phase 4 — Security Quick-Scan

  • No SQL/command-injection vectors introduced.
  • No sensitive data in logs (error messages mention secret length, not value).
  • Dev placeholder secret: see F2.

Phase 5 — Performance Scan

  • JWT validation per request is microsecond-scale HMAC + claims parsing; no I/O, no caching needed (per NFR).
  • No N+1, no unbounded fetches, no new blocking calls.

Phase 6 — Cross-Task Consistency

Single-task batch; not applicable.

Phase 7 — Architecture Compliance

  • All new code in SatelliteProvider.Api/Authentication/ — owned by the WebApi component per module-layout.md.
  • Imports stay within the allowed dependency table (Microsoft.AspNetCore.Authentication.JwtBearer, Microsoft.IdentityModel.Tokens are external NuGet packages, not other components).
  • Test code lives under SatelliteProvider.Tests/ and SatelliteProvider.IntegrationTests/ (separate test projects per layout rule 5).
  • No new cross-sibling ProjectReferences. No new cyclic dependencies. No duplicate cross-component symbols.

Baseline Delta

_docs/02_document/architecture_compliance_baseline.md is not present in the repo; baseline delta section omitted.

Verdict Rationale

Two Low findings, both already accepted in the task spec or surfacable as doc-organization decisions. No Critical, High, or Medium findings. Verdict: PASS_WITH_WARNINGS — proceed to commit per implement skill Step 10.