94 lines
6.1 KiB
Markdown
94 lines
6.1 KiB
Markdown
---
|
|
phase: 06-http-routing-auth-groups-and-rate-limiting
|
|
verified: 2026-09-21T16:00:00Z
|
|
status: passed
|
|
score: 12/12 must-haves verified
|
|
overrides_applied: 0
|
|
mvp_mode_note: "ROADMAP mode is mvp but the technical goal is not a valid User Story (user-story.validate valid=false); this re-verification retains the technical goal contract."
|
|
re_verification:
|
|
previous_status: gaps_found
|
|
previous_score: 8/12
|
|
gaps_closed:
|
|
- "Body limit now wraps all named/factory middleware (surf/router.go wrap: bodyLimit applied after the middleware loop, inside recovery); TestBodyLimitBoundsBodyConsumingMiddleware and TestBodyLimitBoundsNamedMiddleware exist and pass."
|
|
- "RegisterBucket rejects nil store, nil Key, Max<1, Decay<=0; resolve() overflow-checks minute conversion; Middleware fails closed (500) instead of pass-through; TestRegisterBucketRejectsInvalidDefinitions, TestValidateThrottleRejectsOverflowAndNilStore, TestMiddlewareFailsClosed pass."
|
|
- "fetchguard/ip.go carries full IANA special-use IPv4/IPv6 tables (198.18.0.0/15, 192.0.0.0/24, 240.0.0.0/4, ...); dialControl rejects zoned addresses with errPrivateIP; TestDialControlRejectsZonedAndSpecialUse and IANA boundary tests pass."
|
|
- "06-SECURITY-REVIEW.md reopened and re-closed with T-06-28..35 (34/34 closed) backed by passing tests."
|
|
- "Warnings also fixed: ServeMux conflict returns an error (handleRoute), factories built once (r.built cache), bad body config fails boot."
|
|
gaps_remaining: []
|
|
regressions: []
|
|
deferred:
|
|
- truth: "Public/onboarding groups have reachable unauthenticated handlers."
|
|
addressed_in: "Phase 13"
|
|
evidence: "Phase 13 ports onboarding/public/invitation routes with public buckets."
|
|
- truth: "Unknown and malformed ids on ownership-scoped resources both return 404."
|
|
addressed_in: "Phase 12"
|
|
evidence: "Phase 12 owns Collections and Albums; Phase 6 supplies the constraint primitive."
|
|
- truth: "A production OAuth/RFC route exists in the raw group."
|
|
addressed_in: "Phase 8"
|
|
evidence: "Phase 8 owns the OAuth2.1 endpoints; Phase 6 supplies the raw-group contract."
|
|
- truth: "Manual-cover and Discogs production callers use fetchguard."
|
|
addressed_in: "Phase 12 / Phase 14"
|
|
evidence: "Cover handling and Discogs integration are owned there."
|
|
---
|
|
|
|
# Phase 6: HTTP routing, auth groups and rate limiting Verification Report
|
|
|
|
**Phase Goal:** The three mutually exclusive auth groups share handlers with correct subsets, rate-limit buckets are ported 1:1, OAuth/RFC routes are structurally raw, and the auth registry, limiter, and SSRF fetch helper form secure shared infrastructure.
|
|
**Verified:** 2026-09-21
|
|
**Status:** passed
|
|
**Re-verification:** Yes, after gap-closure plans 06-12..06-14
|
|
|
|
## Goal Achievement
|
|
|
|
### Observable Truths
|
|
|
|
| # | Truth | Status | Evidence |
|
|
| --- | --- | --- | --- |
|
|
| 1 | JWT and token groups share the genres handler; subsets mutually exclusive | VERIFIED (public groups deferred) | Unchanged from prior verification; tests pass. |
|
|
| 2 | Five named buckets and inline throttles enforce live limits/keys, including stacking | VERIFIED | Valid definitions plus now-rejected invalid ones. |
|
|
| 3 | Response conventions and raw/house panic behavior | VERIFIED | wire tests and recovery tests pass. |
|
|
| 4 | Fetch helper is an SSRF boundary (allow-list, non-public IP rejection incl. special-use and zoned, cap, timeout) | VERIFIED | `fetchguard/ip.go` IANA tables; `dialControl` rejects zone; tests `TestDialControlRejectsZonedAndSpecialUse`, `TestIsReservedOrPrivateIANABoundaries`, `TestIsReservedOrPrivateIgnoresZone`. |
|
|
| 5 | OpenAPI, path CORS, and body limits enforce the deployment contract | VERIFIED | Body cap now outermost of named middleware (router.go wrap, cap applied after loop, before locale/recover); body-consuming middleware test passes. |
|
|
| 6 | Guard registry unifies users, exact error contracts | VERIFIED | Unchanged; typed-nil now rejected (8a9449d). |
|
|
| 7 | `name:param` middleware via factories | VERIFIED | Factories cached in `r.built`, built once. |
|
|
| 8 | Fixed-window limiter is a safe primitive | VERIFIED | Invalid definitions fail boot; runtime fail-closed. |
|
|
| 9 | Raw routes refuse house middleware, bare recovery | VERIFIED | Unchanged. |
|
|
| 10 | Route-table auth-group isolation | VERIFIED | Unchanged. |
|
|
| 11 | Security review accurate | VERIFIED | 34/34 closed, mapped to existing passing tests; contradicting code paths independently confirmed fixed. |
|
|
| 12 | Packages and regressions run cleanly | VERIFIED | `go vet ./...` clean and `go test ./... -count=1 -race -short` pass in summercms.go and fonoteka.go. |
|
|
|
|
**Score:** 12/12
|
|
|
|
### Requirements Coverage
|
|
|
|
All seven IDs (HTTP-03..HTTP-09) appear in PLAN frontmatter and in REQUIREMENTS.md mapped to Phase 6; none orphaned.
|
|
|
|
| Requirement | Status | Evidence |
|
|
| --- | --- | --- |
|
|
| HTTP-03 | SATISFIED (public handlers deferred to Phase 13) | Shared handler, exclusivity tests. |
|
|
| HTTP-04 | SATISFIED | Five buckets, stacking, invalid definitions rejected. |
|
|
| HTTP-05 | SATISFIED | Single accessor, exact denial bodies. |
|
|
| HTTP-06 | SATISFIED (OAuth routes deferred to Phase 8) | wire helpers, raw infrastructure. |
|
|
| HTTP-07 | SATISFIED | Allow-list, cap, timeout, full non-public/zoned rejection. |
|
|
| HTTP-08 | SATISFIED (warning: OpenAPI covers one live route) | Generation/validation script and artifact. |
|
|
| HTTP-09 | SATISFIED | CORS values and body cap enforced over named middleware. |
|
|
|
|
Note: REQUIREMENTS.md traceability still shows HTTP-04 and HTTP-06 as "In Progress" while their checklist boxes are checked. This is metadata only; it should be updated to Complete.
|
|
|
|
### Anti-Patterns Found
|
|
|
|
No unreferenced TBD/FIXME/XXX in phase files. All previously listed blockers and warnings (body cap order, limiter fail-open, overflow, IP table, ServeMux panic, typed-nil guard, factories built twice, zero body config) verified fixed in source.
|
|
|
|
### Human Verification Required
|
|
|
|
None.
|
|
|
|
### Gaps Summary
|
|
|
|
All four gaps from the prior verification are closed in code and covered by regression tests; no regressions found. Remaining items are deferred by roadmap to Phases 8, 12, 13, 14.
|
|
|
|
---
|
|
|
|
_Verified: 2026-09-21_
|
|
_Verifier: Claude (gsd-verifier)_
|