[AZ-500] Cycle 4 Steps 12-15 sync (test-spec / docs / security / perf)
ci/woodpecker/push/01-test Pipeline was successful
ci/woodpecker/push/02-build-push Pipeline was successful

Step 12 (Test-Spec Sync) - cycle-update mode
  - traceability-matrix: 8 AZ-500 AC rows + .NET 10 runtime
    restriction supersession + Cycle-4 coverage shape note
    (no new tests; ACs verified by re-running existing 78-test
    suite + build pipeline + manifest grep)

Step 13 (Update Docs) - task mode
  - FINAL_report, 00_discovery, architecture, module-layout,
    api_program, tests_unit: .NET 8 -> .NET 10 / C# 12 -> 14 /
    Swashbuckle 6.6.2 -> 10.1.7 + Microsoft.OpenApi 2.x
    refactor note in api_program; Serilog.AspNetCore 8.0.3
    fallback documented inline per AZ-500 Risk #4
  - deployment/{containerization, ci_cd_pipeline}: Docker
    aspnet/sdk:8.0 -> :10.0
  - ripple_log_cycle4: empty import-graph ripple recorded
    (Program.cs is entry point; ParameterDescriptionFilter only
    consumed by Program.cs; csproj/global.json/Dockerfile have
    no import edges)

Step 14 (Security Audit) - resume mode
  - dependency_scan_cycle4: AZ-500 19-package delta scanned;
    cycle-3 D1+D3 (CVE-2026-26130) closed by major-version
    bump; cycle-3 D2 (Test.Sdk 17.8.0 NuGet.Frameworks flag)
    carried over - explicitly out of AZ-500 scope
  - security_report_cycle4: PASS_WITH_WARNINGS (only carry-over
    Medium open; AZ-500 introduced 0 new Critical/High); cycle-3
    static_analysis/owasp_review/infrastructure_review carried
    forward unchanged (AZ-500 made no source-level edits to
    those surfaces)

Step 15 (Performance Test) - perf mode, full default-param run
  - perf_2026-05-12_cycle4: 7 Pass + 1 Unverified (PT-08 hit
    pre-existing scripts/run-performance-tests.sh:417 grep-
    pipefail bug, NOT a .NET 10 regression)
  - PT-07 warm p95 = 301ms (7.7x improvement vs cycle-3 short
    variant - .NET 10 pipeline + N=20 dilution); cold p95 =
    2782ms (-14%); PT-06 90ms (-49%)
  - AZ-500 NFR (Performance) MET for 7/8 scenarios
  - Cycle-3 perf-harness leftover updated with replay #3
    results; STAYS OPEN per AZ-500 Constraint (deletes only on
    fully clean run)

Recommended follow-up PBIs (out of cycle-4 scope, surfaced for
the backlog):
  - 1 SP fix scripts/run-performance-tests.sh:416-417 grep-
    pipefail (replace grep -o ... | wc -l with grep -c ... ||
    true) - unblocks PT-08 + closes the cycle-3 perf leftover
  - 3 SP migrate WithOpenApi(...) callsites to ASP.NET Core 10
    minimal-API metadata extensions (clears 8 ASPDEPR002
    warnings; recorded in batch_01_cycle4_review.md)
  - 1 SP Microsoft.OpenApi 2.x nullable cleanup (CS8604 in
    ParameterDescriptionFilter.cs:25)
  - 1 SP bump Microsoft.NET.Test.Sdk 17.8.0 -> 17.13.0+
    (closes cycle-3 D2 NuGet.Frameworks transitive flag)

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Oleksandr Bezdieniezhnykh
2026-05-12 06:05:29 +03:00
parent de609cffa1
commit af4219fce6
15 changed files with 331 additions and 22 deletions
@@ -0,0 +1,72 @@
# Phase 1 — Dependency Scan (Cycle 4)
**Date**: 2026-05-12
**Scope**: Cycle-4 delta over `_docs/05_security/dependency_scan.md` (cycle 3, dated 2026-05-11)
**Trigger**: AZ-500 .NET 8 LTS → .NET 10 migration bumped 19+ NuGet references in one coordinated commit; AZ-500 Security NFR requires a fresh dependency-scan pass after the bump.
**Method**: Manual inventory diff against cycle-3 scan + targeted advisory search (WebSearch against GHSA / NVD / NuGet ReversingLabs / Sonatype).
**Reason for manual mode**: `dotnet list package --vulnerable` is on the project's "do not run from agent" list (AGENTS.md — these commands hang in this environment). Same posture as cycle 3.
## Cycle-4 dependency delta (vs. cycle-3 scan)
| Project | Package | Cycle-3 version | Cycle-4 version | Bumped by |
|---------|---------|-----------------|-----------------|-----------|
| Api | Microsoft.AspNetCore.Authentication.JwtBearer | 8.0.25 | **10.0.7** | AZ-500 |
| Api | Microsoft.AspNetCore.OpenApi | 8.0.25 | **10.0.7** | AZ-500 |
| Api | Swashbuckle.AspNetCore | 6.6.2 | **10.1.7** | AZ-500 |
| Api | Microsoft.OpenApi (transitive via Swashbuckle 10.1.7) | 1.x (transitive) | **2.3.x (transitive)** | AZ-500 (indirect) |
| Api | Serilog.AspNetCore | 8.0.3 | **8.0.3 (unchanged)** | — (AZ-500 Risk #4 fallback: no 10.x line published as of cycle 4; restores cleanly on .NET 10 via netstandard 2.0) |
| Tests | Microsoft.AspNetCore.Authentication.JwtBearer | 8.0.25 (transitive) | **10.0.7 (transitive)** | AZ-500 |
| Tests | Microsoft.Extensions.Caching.Memory | 9.0.10 | **10.0.7** | AZ-500 |
| Tests | Microsoft.Extensions.Configuration.Json | 9.0.10 | **10.0.7** | AZ-500 |
| Tests | Microsoft.Extensions.DependencyInjection | 9.0.10 | **10.0.7** | AZ-500 |
| Tests | Microsoft.Extensions.Http | 9.0.10 | **10.0.7** | AZ-500 |
| Tests | Microsoft.Extensions.Logging.Abstractions | 9.0.10 | **10.0.7** | AZ-500 |
| Tests | Microsoft.Extensions.Logging.Console | 9.0.10 | **10.0.7** | AZ-500 |
| Tests | Microsoft.Extensions.Options | 9.0.10 | **10.0.7** | AZ-500 |
| DataAccess | Microsoft.Extensions.Configuration.Abstractions | 9.0.10 | **10.0.7** | AZ-500 |
| DataAccess | Microsoft.Extensions.Logging.Abstractions | 9.0.10 | **10.0.7** | AZ-500 |
| TileDownloader | Microsoft.Extensions.Caching.Memory | 9.0.10 | **10.0.7** | AZ-500 |
| TileDownloader | Microsoft.Extensions.Http | 9.0.10 | **10.0.7** | AZ-500 |
| TileDownloader | Microsoft.Extensions.Logging.Abstractions | 9.0.10 | **10.0.7** | AZ-500 |
| TileDownloader | Microsoft.Extensions.Options.ConfigurationExtensions | 9.0.10 | **10.0.7** | AZ-500 |
| RegionProcessing | Microsoft.Extensions.DependencyInjection.Abstractions | 9.0.10 | **10.0.7** | AZ-500 |
| RegionProcessing | Microsoft.Extensions.Hosting.Abstractions | 9.0.10 | **10.0.7** | AZ-500 |
| RegionProcessing | Microsoft.Extensions.Logging.Abstractions | 9.0.10 | **10.0.7** | AZ-500 |
| RegionProcessing | Microsoft.Extensions.Options.ConfigurationExtensions | 9.0.10 | **10.0.7** | AZ-500 |
| RouteManagement | Microsoft.Extensions.DependencyInjection.Abstractions | 9.0.10 | **10.0.7** | AZ-500 |
| RouteManagement | Microsoft.Extensions.Hosting.Abstractions | 9.0.10 | **10.0.7** | AZ-500 |
| RouteManagement | Microsoft.Extensions.Logging.Abstractions | 9.0.10 | **10.0.7** | AZ-500 |
| RouteManagement | Microsoft.Extensions.Options.ConfigurationExtensions | 9.0.10 | **10.0.7** | AZ-500 |
**Runtime image**: `mcr.microsoft.com/dotnet/aspnet:10.0` (was `:8.0` in cycle 3 — bumped by AZ-500 in `SatelliteProvider.Api/Dockerfile`). Same auto-resolve-to-latest-10.0.x posture cycle-3 noted for the `:8.0` floating tag — first build picks up Microsoft's most recent .NET 10 patch automatically.
**Unchanged from cycle 3** (carried-over inventory; cycle-3 dispositions still apply): `Newtonsoft.Json 13.0.4`, `SixLabors.ImageSharp 3.1.11`, `Dapper 2.1.35`, `Npgsql 9.0.2`, `dbup-postgresql 6.0.3`, `Serilog.Sinks.File 6.0.0`, `Serilog.AspNetCore 8.0.3`, `Microsoft.IdentityModel.Tokens 7.0.3`, `System.IdentityModel.Tokens.Jwt 7.0.3`, `coverlet.collector 6.0.0`, `FluentAssertions 8.8.0`, `Microsoft.NET.Test.Sdk 17.8.0`, `Moq 4.20.72`, `xunit 2.5.3`, `xunit.runner.visualstudio 2.5.3`. None of these were touched by AZ-500 (Constraint: "do not silently fold in unrelated package bumps"). `Microsoft.NET.Test.Sdk 17.8.0` retains the cycle-3 NuGet.Frameworks transitive CVE flag (D2) — disposition unchanged.
## Findings
| # | Severity | Package | Version | Advisory | Disposition |
|---|----------|---------|---------|----------|-------------|
| D1-cy4 | Low (informational) | Microsoft.AspNetCore.Authentication.JwtBearer | 10.0.7 | None as of 2026-05-12 (Sonatype + ReversingLabs both report 0 known vulnerabilities for the 10.0.7 line). The cycle-3 D1 finding (CVE-2026-26130 SignalR DoS, 8.0.21 → 8.0.25 patch) is now superseded — the 10.0.7 line incorporates that fix and continues forward; SignalR remains unused in this codebase. | **CLOSED** by the major-version bump (AZ-500). |
| D2-cy4 | **Medium** (production-risk: **Low**, exposure: test-runtime only — same as cycle-3 D2) | Microsoft.NET.Test.Sdk → NuGet.Frameworks | 17.8.0 | Cycle-3 D2 disposition reproduced verbatim: transitive `NuGet.Frameworks` flagged for moderate severity in some scanners. AZ-500 did not bump `Microsoft.NET.Test.Sdk` (out of scope per the AZ-500 Constraint "do not silently fold in unrelated package bumps"). | **OPEN — carried over from cycle 3.** Same disposition: not loaded at runtime in the production container; test-runtime exposure only. Recommend a separate PBI (post cycle 4) to bump `Microsoft.NET.Test.Sdk` 17.8.0 → 17.13.0+ when the team next touches the test infrastructure. |
| D3-cy4 | Low (informational) | Microsoft.AspNetCore.OpenApi | 10.0.7 | None as of 2026-05-12. The cycle-3 D3 finding (which paired with D1 — same supply-chain CVE-2026-26130 advisory) is now superseded by the major-version bump. | **CLOSED** by AZ-500. |
| D4-cy4 | Low (informational) | Swashbuckle.AspNetCore | 10.1.7 | None as of 2026-05-12 (ReversingLabs scan of the 10.1.5/10.1.7 line reports 0 known vulnerabilities). The major bump (6.6.2 → 10.1.7) was driven by the Microsoft.OpenApi 2.x compat requirement of ASP.NET Core 10, not by an active CVE. | **NEW LINE — clean.** Recorded for traceability. |
| D5-cy4 | Low (informational) | Microsoft.OpenApi (transitive) | 2.3.x (latest patch on the 2.3 line at restore time) | None as of 2026-05-12. The major bump from 1.x to 2.x is breaking-API but advisory-clean. The `Microsoft/OpenAPI.NET` GitHub Security tab shows zero published advisories for the 2.x line. | **NEW LINE — clean.** Drove the `Program.cs` Swashbuckle setup refactor (3 internal edits — see `_docs/02_document/modules/api_program.md` "Microsoft.OpenApi 2.x refactor note"). |
| D6-cy4 | Low (informational) | Microsoft.Extensions.* | 10.0.7 (across 11 distinct package IDs, ~20 csproj references) | None as of 2026-05-12 against the 10.0.7 line. Historical `Microsoft.Extensions.Caching.Memory` CVE-2024-43483 (DoS via hash flooding) affected ≤ 6.0.1 / ≤ 8.0.0 / ≤ 9.0.0-rc.1 — the cycle-3 9.0.10 baseline was already past that cutoff, and 10.0.7 carries the fix forward. | **CLOSED transitively** — historical CVE was already not applicable in cycle 3; cycle 4 maintains that posture. |
| D7-cy4 | Low (informational — operational risk noted, not security) | Serilog.AspNetCore | 8.0.3 (unchanged) | None published. AZ-500 Risk #4 fallback: no 10.x line published as of cycle 4; the package targets `netstandard 2.0` so it restores cleanly against `net10.0`. | **DEFERRED** — re-check at the start of every subsequent cycle. If a 10.x line ships, bump as a single-PBI hygiene task. No security exposure today. |
**No Critical or High findings introduced by AZ-500.** Cycle-4 verdict (dependency-scan dimension only): **PASS_WITH_WARNINGS** — the only OPEN item (D2-cy4) is a cycle-3 carry-over that AZ-500 explicitly excluded from scope.
## Self-verification
- [x] All package manifests scanned (9 csproj files, post-AZ-500 state).
- [x] Each finding has a CVE/advisory reference or an explicit "no published advisory as of [date]" note.
- [x] Upgrade paths identified for the only OPEN item (D2-cy4 → bump `Microsoft.NET.Test.Sdk` to 17.13.0+ in a separate PBI).
- [x] Cross-checked against AZ-500 Risk #1 (JwtBearer behavioral change): the Step 11 full integration suite passed including SEC-05..SEC-09 + AZ-494 AC-1/AC-2 wrong-iss/aud — JWT validation contract preserved exactly.
- [x] Cross-checked against AZ-500 Risk #2 (OpenApi Swagger UI breakage): post-build manual probe of `http://localhost:18980/swagger` returned 200; `SwaggerDocument_AdvertisesBearerSecurityScheme` programmatic test passed in the cycle-4 Step 11 run.
- [x] Cross-checked against AZ-500 Risk #3 (M.E.* 10.0.x cascade conflicting with `Microsoft.IdentityModel.Tokens 7.0.3`): no NU1605 / NU1107 conflicts at restore time in the cycle-4 Step 11 build path.
## Out of scope for this scan (covered elsewhere)
- **Static analysis** (SAST): cycle-3 `_docs/05_security/static_analysis.md` carries forward unchanged. AZ-500 made no source-level edits to authentication, authorization, input validation, crypto, deserialization, or data-exposure paths. The only C# edits were `Program.cs` Swashbuckle DI registration (internal wiring, no external surface change) and `Swagger/ParameterDescriptionFilter.cs` `using` directive — neither category in the SAST checklist.
- **OWASP Top 10 review**: cycle-3 `_docs/05_security/owasp_review.md` carries forward unchanged. AZ-500 introduced no new endpoints, no new permission policies, no new user-input paths, no new external integrations, no new crypto, and no new data exposure surface — all 10 OWASP categories are unchanged in posture.
- **Infrastructure review**: cycle-3 `_docs/05_security/infrastructure_review.md` carries forward unchanged with one delta: Docker base/build/runtime images and CI image moved from the `:8.0` floating tag to `:10.0`. Microsoft publishes the `:10.0` images as multi-arch (amd64 + arm64); the runtime image still uses a non-root user via the cycle-1 `USER app` directive (verified in `SatelliteProvider.Api/Dockerfile`); no secrets were added to build args. **Net infrastructure security posture: unchanged.**
+101
View File
@@ -0,0 +1,101 @@
# Security Audit Report (Cycle 4)
**Date**: 2026-05-12
**Scope**: Cycle-4 delta over the cycle-3 audit (`_docs/05_security/security_report.md`)
**Trigger**: AZ-500 .NET 8 LTS → .NET 10 migration; AZ-500 Security NFR requires a fresh dependency-scan pass after the bump
**Mode**: Resume (per user choice at the prerequisite gate) — only Phase 1 (dependency scan) was re-executed; Phases 24 carried forward from cycle 3 because AZ-500 made no source-level edits to the surfaces those phases cover (auth/authorization, input validation, crypto, deserialization, data exposure, infrastructure beyond the image-tag bump)
**Verdict**: **PASS_WITH_WARNINGS**
## Summary
| Severity | Count (cycle 4 delta) | Count (cumulative — incl. cycle-3 carry-overs) |
|----------|-----------------------|--------------------------------------------------|
| Critical | 0 | 0 |
| High | 0 | 0 |
| Medium | 0 NEW | 1 (D2-cy4 — `Microsoft.NET.Test.Sdk 17.8.0` transitive `NuGet.Frameworks` flag, **carried over from cycle 3**, test-runtime exposure only, AZ-500 explicitly out-of-scope) |
| Low | 5 NEW (informational only — all are "no published advisory" confirmations on the bumped lines) | 5 NEW + cycle-3 carry-overs |
## OWASP Top 10 Assessment
**Carried forward unchanged from cycle 3** (`_docs/05_security/owasp_review.md`). AZ-500 introduced no new endpoints, no new permission policies, no new user-input paths, no new external integrations, no new crypto, and no new data-exposure surface — all 10 OWASP categories retain their cycle-3 posture. Cycle-3 status table is the authoritative reference.
## Cycle-4 NEW Findings
| # | Severity | Category | Location | Title |
|---|----------|----------|----------|-------|
| F1-cy4 | Low (informational) | Vulnerable Components | `SatelliteProvider.Api/SatelliteProvider.Api.csproj` (Microsoft.AspNetCore.Authentication.JwtBearer 10.0.7) | No published advisories — bump closes cycle-3 D1 (CVE-2026-26130) |
| F2-cy4 | Low (informational) | Vulnerable Components | `SatelliteProvider.Api/SatelliteProvider.Api.csproj` (Microsoft.AspNetCore.OpenApi 10.0.7) | No published advisories — bump closes cycle-3 D3 |
| F3-cy4 | Low (informational) | Vulnerable Components | `SatelliteProvider.Api/SatelliteProvider.Api.csproj` (Swashbuckle.AspNetCore 10.1.7) | New major-line; clean per ReversingLabs scan |
| F4-cy4 | Low (informational) | Vulnerable Components | Transitive via Swashbuckle (Microsoft.OpenApi 2.3.x) | New major-line; clean per Microsoft/OpenAPI.NET GitHub Security tab (zero published advisories) |
| F5-cy4 | Low (informational) | Vulnerable Components | All 11 `Microsoft.Extensions.*` package IDs across 6 csproj files (10.0.7) | No published advisories — historical CVE-2024-43483 was already not applicable in cycle 3 (9.0.10 baseline post-rc.1 cutoff); 10.0.7 carries the fix forward |
### Finding Details
**F1-cy4: Microsoft.AspNetCore.Authentication.JwtBearer bumped to 10.0.7 — no known vulnerabilities** (Low / Vulnerable Components)
- Location: `SatelliteProvider.Api/SatelliteProvider.Api.csproj` (and `SatelliteProvider.Tests/SatelliteProvider.Tests.csproj` transitively)
- Description: AZ-500 bumped this package from 8.0.25 → 10.0.7 as part of the .NET 10 migration. The 10.0.7 line is reported as having 0 known vulnerabilities by Sonatype Guide and ReversingLabs Spectra Assure as of 2026-05-12.
- Impact: None — this is an informational confirmation. The bump SUPERSEDES the cycle-3 D1 finding (CVE-2026-26130 SignalR DoS) because the 10.x line incorporates that fix and continues forward; SignalR is still unused in this codebase.
- Remediation: None required. AZ-500 NFR (Security) is satisfied for this package.
- Verification cross-reference: AZ-487/AZ-494 integration tests (SEC-05..SEC-09 + AZ-494 AC-1/AC-2) — all green in the cycle-4 Step 11 full run, confirming JWT validation contract preservation across the major bump.
**F2-cy4: Microsoft.AspNetCore.OpenApi bumped to 10.0.7 — no known vulnerabilities** (Low / Vulnerable Components)
- Location: `SatelliteProvider.Api/SatelliteProvider.Api.csproj`
- Description: AZ-500 bumped this package from 8.0.25 → 10.0.7. Same supply-chain advisory family as F1; bump supersedes cycle-3 D3.
- Impact: None.
- Remediation: None required.
**F3-cy4: Swashbuckle.AspNetCore bumped to 10.1.7 — no known vulnerabilities** (Low / Vulnerable Components)
- Location: `SatelliteProvider.Api/SatelliteProvider.Api.csproj`
- Description: AZ-500 bumped this package from 6.6.2 → 10.1.7 specifically to land Microsoft.OpenApi 2.x compat (required by ASP.NET Core 10's `Microsoft.AspNetCore.OpenApi 10.x`). ReversingLabs scan of the 10.1.x line reports 0 known vulnerabilities.
- Impact: None — bump was driven by compat, not by an active CVE. Note that the major bump introduced a breaking-API change (Microsoft.OpenApi 1.x → 2.x), which drove three internal `Program.cs` setup edits (using-directive, `AddSecurityRequirement``Func<OpenApiDocument, OpenApiSecurityRequirement>` + `OpenApiSecuritySchemeReference("Bearer")`, `MapType<UavTileBatchUploadRequest>``JsonSchemaType` + `IDictionary<string, IOpenApiSchema>`). The Swagger document shape (paths, Bearer Authorize button, multipart-batch upload schema) is preserved exactly; `SwaggerDocument_AdvertisesBearerSecurityScheme` programmatic test passed.
- Remediation: None required for security. Eight `ASPDEPR002` `WithOpenApi(...)` deprecation warnings remain in `Program.cs` — recorded as a follow-up PBI in `_docs/03_implementation/reviews/batch_01_cycle4_review.md`.
**F4-cy4: Microsoft.OpenApi 2.3.x (transitive) — no known vulnerabilities** (Low / Vulnerable Components)
- Location: Transitive dependency of `Swashbuckle.AspNetCore 10.1.7` and `Microsoft.AspNetCore.OpenApi 10.0.7`
- Description: AZ-500's Swashbuckle bump pulled in Microsoft.OpenApi 2.x as a transitive replacement for the 1.x previously in scope. The microsoft/OpenAPI.NET GitHub Security tab shows zero published advisories for the 2.x line.
- Impact: None for security. Code-impact handled in F3 (the API rewrite was small and contained).
- Remediation: None required.
**F5-cy4: Microsoft.Extensions.* coordinated bump to 10.0.7 — no known vulnerabilities** (Low / Vulnerable Components)
- Location: 6 csproj files: `SatelliteProvider.Api`, `SatelliteProvider.Tests`, `SatelliteProvider.DataAccess`, `SatelliteProvider.Services.TileDownloader`, `SatelliteProvider.Services.RegionProcessing`, `SatelliteProvider.Services.RouteManagement`. ~20 PackageReference rows across 11 distinct package IDs (Caching.Memory, Configuration.Abstractions, Configuration.Json, DependencyInjection, DependencyInjection.Abstractions, Hosting.Abstractions, Http, Logging.Abstractions, Logging.Console, Options, Options.ConfigurationExtensions).
- Description: AZ-500 bumped all M.E.* references from 9.0.10 → 10.0.7 as a coordinated cycle-4 move (per AZ-500 Constraint: "TFM, SDK pin, Docker images, CI images, and M.E.* package versions ALL move in the same commit"). Historical `Microsoft.Extensions.Caching.Memory` CVE-2024-43483 (DoS via hash flooding) affected only 6.x ≤ 6.0.1 / 8.x ≤ 8.0.0 / 9.x ≤ 9.0.0-rc.1 — the cycle-3 9.0.10 baseline was already past that cutoff; 10.0.7 carries the fix forward.
- Impact: None.
- Remediation: None required. The `Microsoft.IdentityModel.Tokens 7.0.3` / `System.IdentityModel.Tokens.Jwt 7.0.3` packages remain pinned (AZ-500 Constraint kept them out of scope); restore against `net10.0` succeeded with no NU1605/NU1107 conflicts (Risk #3 verified clean in the cycle-4 Step 11 build path).
## Cycle-3 carry-overs (still OPEN)
| # | Severity | Title | Why still OPEN | Cycle-4 disposition |
|---|----------|-------|----------------|---------------------|
| D2 (cycle 3) | Medium (production-risk: Low, exposure: test-runtime only) | `Microsoft.NET.Test.Sdk 17.8.0` transitive `NuGet.Frameworks` advisory flag | AZ-500 explicitly excluded `Microsoft.NET.Test.Sdk` from scope (Constraint: "do not silently fold in unrelated package bumps") | **Continue to defer.** Recommend a separate PBI (post-cycle-4) to bump 17.8.0 → 17.13.0+ when the team next touches test infrastructure. Test-runtime-only exposure; not loaded in the production container. |
All cycle-3 SAST findings (`_docs/05_security/static_analysis.md`), OWASP findings (`_docs/05_security/owasp_review.md`), and infrastructure findings (`_docs/05_security/infrastructure_review.md`) carry forward at their cycle-3 dispositions. AZ-500 made no source-level changes that would alter any of those.
## Recommendations
### Immediate (Critical / High)
- **None.** No Critical or High findings introduced by AZ-500.
### Short-term (Medium)
- (Carried over from cycle 3) PBI: bump `Microsoft.NET.Test.Sdk` 17.8.0 → 17.13.0+ to close D2-cy4 / D2 (cycle 3). Estimated 1 SP. Test-only impact.
### Long-term (Low / Hardening)
- Re-check `Serilog.AspNetCore` at the start of every subsequent cycle. If a 10.x line ships, bump as a single-PBI hygiene task to remove the AZ-500 Risk #4 fallback note from `AGENTS.md` / `_docs/02_document/00_discovery.md` / `_docs/02_document/modules/api_program.md`.
- (From cycle-4 review) Migrate the 8 `WithOpenApi(...)` callsites in `Program.cs` to the ASP.NET Core 10 minimal-API metadata extensions to clear the `ASPDEPR002` deprecation warnings (3 SP, recommended PBI from `_docs/03_implementation/reviews/batch_01_cycle4_review.md`). Not a security item — quality/maintainability — but worth tracking alongside the AZ-500 follow-ups.
## Verdict justification
- **PASS** would require zero findings of any severity. Cycle-3 D2 carry-over (Medium) prevents PASS.
- **PASS_WITH_WARNINGS** is the correct verdict because the only OPEN item is a Medium with mitigations in place (test-runtime-only exposure, not loaded in production container) and AZ-500 explicitly scoped it out per its Constraints. AZ-500 itself introduced zero new findings above Low.
- **FAIL** would require Critical or High. AZ-500 introduced none.
## Self-verification
- [x] All findings from the executed phase (Phase 1 — `dependency_scan_cycle4.md`) included.
- [x] No duplicate findings.
- [x] Every finding has remediation guidance ("None required" is acceptable for informational confirmations on clean lines).
- [x] Verdict matches severity logic (PASS_WITH_WARNINGS — only Medium open is a cycle-3 carry-over with documented mitigations).
- [x] Cycle-3 phases that were intentionally not re-executed (Phases 2/3/4) are explicitly cited as "carried forward" with the rationale recorded.
- [x] AZ-500's three named risks (Risk #1 JwtBearer behavioral change, Risk #2 OpenApi Swagger UI breakage, Risk #3 M.E.* cascade conflict) are each cross-referenced against an in-cycle verification.