The security review no longer claims zero open threats until all four corrective plans and both repositories' complete `go test ./... -count=1 -race -short` gates pass
T-06-24 records the anonymous key as exactly `inline:domainless|<ClientIP>` and explicitly excludes the throttle parameter, `r.Host`, `Forwarded` host, and `X-Forwarded-Host` from bucket selection
T-06-23 through T-06-27 map atomic admission, domainless inline keys, transition-address SSRF rejection, clean partial-write panic recovery, and exact InvScope bytes to named passing tests
T-06-24 cites the named Plan 06-07 Host-rotation, cross-inline-parameter shared-budget, and authenticated `u:<id>` isolation regressions
The review's verdict, scope, totals, accepted-risk count, and audit trail agree with the post-fix code and evidence
Any failed corrective test leaves the review open/blocked rather than documenting a false verified state
T-06-23/T-06-24 cite the coordinated concurrency plus the named `TestFixedWindowLimiterInlineThrottleKeys` Host-rotation, cross-inline-parameter shared-budget, and authenticated-principal isolation cases
Refresh the Phase 6 ASVS L1 security review only after all corrective code and tests are green, replacing the stale zero-open conclusion with a complete post-gap threat map and auditable evidence.
Purpose: the review is itself a required phase artifact. Its verdict must describe the current code, not the pre-review snapshot that missed four security/contract failures.
Output: an updated 06-SECURITY-REVIEW.md covering Plans 06-01 through 06-10 plus the Plan 06-11 review refresh, with all five new threats accurately closed or the phase explicitly blocked.
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/REQUIREMENTS.md
@.planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-CONTEXT.md
@.planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-VERIFICATION.md
@.planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-REVIEW.md
@.planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-SECURITY-REVIEW.md
@.planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-07-SUMMARY.md
@.planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-08-SUMMARY.md
@.planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-09-SUMMARY.md
@.planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-10-SUMMARY.md
Task 1: Re-run Phase 6 security gates and publish the post-gap threat verdict
.planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-SECURITY-REVIEW.md
.planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-SECURITY-REVIEW.md (current stale header, threat register, findings, accepts, and audit trail; preserve all still-valid evidence)
.planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-VERIFICATION.md (authoritative four code gaps plus stale-review gap)
.planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-REVIEW.md (CR-01 through CR-04 and WR-11 source evidence)
.planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-07-PLAN.md and 06-07-SUMMARY.md (T-06-23/T-06-24 and actual test names/results)
.planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-08-PLAN.md and 06-08-SUMMARY.md (T-06-25 and actual transition tests/results)
.planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-09-PLAN.md and 06-09-SUMMARY.md (T-06-26 and actual recovery tests/results)
.planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-10-PLAN.md and 06-10-SUMMARY.md (T-06-27 and actual byte-contract tests/results)
surf/limiter.go, surf/limiter_store.go, surf/limiter_test.go (executed atomic admission and stable-key code/evidence)
fetchguard/ip.go, fetchguard/ip_test.go, fetchguard/fetch_test.go (executed transition classifier and dial-time evidence)
surf/router.go, surf/router_test.go (executed buffer/discard recovery and partial-write evidence)
../fonoteka.go/plugins/golem15/fonoteka/middleware/token_scope.go and token_scope_test.go (executed no-newline writer and exact-byte evidence)
Before editing the review, run the repository-level verification commands below. The authoritative suite gates are exactly `go test ./... -count=1 -race -short` from summercms.go and the same command from sibling fonoteka.go; package-targeted race runs or full suites without `-race` are not substitutes. If any command fails, do not set `status: verified`, do not set `threats_open: 0`, and do not add a zero-open audit row; stop and report the failing threat/test as blocking. High-severity T-06-23 through T-06-26 may not be accepted or deferred.
After all gates pass, update `06-SECURITY-REVIEW.md` frontmatter date/status/threat count and scope so it explicitly covers Plans 06-01 through 06-10 and the Plan 06-11 review refresh. Preserve every existing T-06-01..18, T-06-21, T-06-22, and T-06-SC row and its disposition unless the new code invalidates the old evidence; do not erase accepted-risk rationales or prior audit-trail rows.
Add five mitigate rows and matching detailed `Findings by Threat` sections using the actual executed test names from the four summaries: T-06-23 for atomic threshold check+increment and coordinated Max=1 evidence; T-06-24 for the server-controlled `inline:domainless|<ClientIP>` key; T-06-25 for RFC 6052 well-known/local-use NAT64 plus 6to4 embedded loopback/RFC1918/metadata rejection, public controls, and dialControl proof; T-06-26 for buffer/discard recovery with both raw and house partial-write-then-panic exact response assertions; T-06-27 for `wire.WriteJSON` and raw-byte 401/403 assertions with no trimming. For T-06-24, state explicitly that the anonymous key excludes the throttle `param`, `r.Host`, the `Forwarded` host parameter, and `X-Forwarded-Host`. Cite the exact executed names recorded by Plan 06-07's summary/source for all three inline-key regressions under `TestFixedWindowLimiterInlineThrottleKeys`: the Host-rotation subtest, the same-IP shared-budget subtest spanning different inline throttle parameters, and the authenticated-principal subtest proving independent `u:<id>` buckets. Copy the complete slash-qualified names from the executed test source/summary rather than describing unnamed cases. Do not reduce this to a Host-rotation citation or claim that a throttle parameter selects any portion of the anonymous key. Cite concrete source identifiers and named tests, not only plan numbers.
Update the trust-boundary table for concurrent limiter admission, IPv6 transition decoding, buffered response commit, and token-scope serialization. Update summary prose, accepted-risk count, closed/open totals, and Security Audit Trail consistently. With the existing 21 reviewed IDs plus five new mitigations, the successful review total is 26 threats, 26 closed, zero open; T-06-SC remains one of the 26 and no new accepted risk is introduced. Do not change `06-VERIFICATION.md`; re-verification remains the verifier's next step.
cd /media/nvme/dev/golem15/summercms.io/summercms/summercms.go && go test ./... -count=1 -race -short && go vet ./... && cd ../fonoteka.go && go test ./... -count=1 -race -short && go vet ./... && cd ../summercms.go && test "$(awk -F'|' '/^\| T-06-(23|24|25|26|27) / {c++} END {print c+0}' .planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-SECURITY-REVIEW.md)" -eq 5 && rg -n '26 \| 26 \| 0|threats_open: 0|Plans 06-01 through 06-10' .planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-SECURITY-REVIEW.md && rg -n 'inline:domainless\|<ClientIP>' .planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-SECURITY-REVIEW.md && rg -n 'TestFixedWindowLimiterInlineThrottleKeys/.+(Host|host)' .planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-SECURITY-REVIEW.md && rg -n 'TestFixedWindowLimiterInlineThrottleKeys/.+(param|policy)' .planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-SECURITY-REVIEW.md && rg -n 'TestFixedWindowLimiterInlineThrottleKeys/.+(principal|authenticated|user)' .planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-SECURITY-REVIEW.md && rg -n 'u:<id>' .planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-SECURITY-REVIEW.md && ! rg -n 'inline:<param>\|<ClientIP>|param\+ClientIP|anonymous (bucket|key).*(uses|includes|contains|combines).*(throttle )?param' .planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-SECURITY-REVIEW.md
- The review update occurs after all four plan summaries exist and `go test ./... -count=1 -race -short` plus `go vet ./...` exit 0 in both summercms.go and fonoteka.go.
- The Threat Register contains exactly one row each for T-06-23, T-06-24, T-06-25, T-06-26, and T-06-27, all disposition `mitigate`, each naming executed source/test evidence.
- Findings by Threat contains substantive sections for all five new IDs: coordinated concurrency; exact `inline:domainless|` construction; named Host-rotation, cross-inline-parameter shared-budget, and authenticated `u:` isolation regressions; all three transition prefixes; both partial-write route kinds; and raw exact 401/403 bytes.
- T-06-24 says the anonymous signature excludes throttle `param`, `r.Host`, `Forwarded` host, and `X-Forwarded-Host`; the source/verification grep rejects stale `inline:|`, `param+ClientIP`, or equivalent parameter-selected anonymous-key claims.
- Frontmatter, summary, accepted-risk log, threat totals, and the newest audit-trail row agree on 26 total, 26 closed, zero open only when every gate passed.
- Every earlier threat row and audit-trail history remains present; no high-severity gap is silently accepted, deferred, or omitted.
- `06-VERIFICATION.md` is not edited by this plan.
The Phase 6 security review truthfully reflects the corrected code and supplies auditable, named test evidence for every previously unresolved security/contract gap.
<threat_model>
Trust Boundaries
Boundary
Description
implementation evidence -> security verdict
A stale or optimistic review can falsely release security-load-bearing primitives to dependent phases
test gates -> documentation state
Zero-open status is allowed only when the exact adversarial tests and both repository suites pass
STRIDE Threat Register
Threat ID
Category
Component
Disposition
Mitigation Plan
T-06-23
Denial of Service
concurrent limiter admission
mitigate
Require atomic Attempt implementation and coordinated Max=1 passing evidence before review closure
T-06-24
Denial of Service
anonymous inline key selection
mitigate
Require exact `inline:domainless
T-06-25
Elevation of Privilege / Information Disclosure
transition-address SSRF classification
mitigate
Require NAT64 /96, local-use NAT64 /48, and 6to4 embedded-private plus dialControl tests
T-06-26
Information Disclosure
raw/house panic recovery
mitigate
Require partial-write status/header/body discard tests for both route kinds
T-06-27
Tampering
personal-token denial serialization
mitigate
Require wire.WriteJSON and exact untrimmed 401/403 byte comparisons
T-06-SC
Tampering
package supply chain
accept
Gap plans add no dependencies; retain the existing Phase 6 package-legitimacy disposition
</threat_model>
<source_coverage_audit>
Source
ID
Feature / Requirement
Plan
Status
Notes
GOAL
Phase 6
Secure shared auth groups, 1:1 rate limiting, raw OAuth boundary, and SSRF guard
06-07..06-11
COVERED
Four defects fixed in parallel; review refresh follows all code/test plans
REQ
HTTP-03
Mutually exclusive groups share handlers
06-11
COVERED (existing + regression gate)
Implemented by 06-01/06-05; full suite confirms no regression
REQ
HTTP-04
Named/inline rate limits and stacking
06-07, 06-11
COVERED
Atomic admission and exact `inline:domainless
REQ
HTTP-05
Unified guard registry/current-user accessor
06-10, 06-11
COVERED
Existing registry retained; exact personal-token denial contract is verified
REQ
HTTP-06
Response conventions and raw exemption
06-09, 06-10, 06-11
COVERED
Clean partial-write recovery and no-newline TokenScope bytes
REQ
HTTP-07
Guarded outbound fetch
06-08, 06-11
COVERED
Transition addresses receive embedded IPv4 classification at dial time
REQ
HTTP-08
OpenAPI/type generation
06-11
COVERED (existing + regression gate)
Implemented by 06-03; no authoritative current gap requests replanning
REQ
HTTP-09
CORS/body limits
06-11
COVERED (existing + regression gate)
Implemented by 06-03; no authoritative current gap requests replanning
RESEARCH
Fixed-window semantics
First-hit fixed window and PHP headers/body
06-07
COVERED
Atomic API preserves the established sequential contract
RESEARCH
SSRF dial-time guard
Actual connected address is classified
06-08
COVERED
Transition extraction feeds the existing dial-time classifier
CONTEXT
D-01..D-05
Five buckets, fixed-window parity, stdlib store, trusted ClientIP, parameterized names
06-07
COVERED
No bucket limit/key ownership or middleware syntax is reduced
CONTEXT
D-06..D-10
Guard registry, real token guard, exact InvScope bodies, no OAuth stub, unchanged JWT
Transition forms added without changing caller scope or limits
CONTEXT
D-15..D-18
Group subsets, raw bare recovery, response conventions/OpenAPI, CORS/body limits
06-09, 06-11
COVERED
D-16 is upheld after partial writes; unrelated existing outputs regression-tested
CONTEXT
Deferred Ideas
Later route handlers/call sites
—
EXCLUDED
Explicitly out of Phase 6 and absent from authoritative gaps:
REVIEW
Warnings outside verifier gaps
WR-01..WR-10 except promoted WR-11
—
EXCLUDED
Gap-closure mode plans only authoritative 06-VERIFICATION.md gaps; these remain review backlog, not silently claimed fixed
</source_coverage_audit>
Run `go test ./... -count=1 -race -short` and `go vet ./...` in both repositories before documentation can claim verified/zero-open. Validate five new unique threat rows, matching detailed findings, consistent 26/26/0 totals, preserved prior evidence, and a scope statement covering the corrective plans. Assert positively that T-06-24 names `inline:domainless|` and the three Plan 06-07 inline-key regressions, and fail if the review contains `inline:|`, `param+ClientIP`, or an equivalent parameter-selected anonymous-key claim. If any command or assertion fails, leave the verdict open and stop.
<success_criteria>
The stale Phase 6 security verdict is replaced by evidence matching the post-gap code.
T-06-23 through T-06-27 are each closed by concrete named tests, never by assertion alone.
T-06-24 documents only inline:domainless|<ClientIP>, explicitly excludes throttle param and all request/forwarded Host input, and cites the named Host-rotation, cross-inline-parameter shared-budget, and authenticated u:<id> isolation tests.
The successful audit is internally consistent at 26 total / 26 closed / 0 open with no new accepted risk.
A failed full-repository -race suite, vet gate, or anonymous-key source assertion in either repository cannot produce a verified/zero-open document.
All four source categories are fully covered without planning deferred items or non-authoritative warnings.
</success_criteria>
Create `.planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-11-SUMMARY.md` when done.