From 7f627961b1d9101a4125ba0cbe60bb165e8ff172 Mon Sep 17 00:00:00 2001 From: Jakub Zych Date: Sun, 20 Sep 2026 13:31:41 +0200 Subject: [PATCH] docs(06-06): complete personal-token rate-limit gap plan --- .../06-06-SUMMARY.md | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 .planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-06-SUMMARY.md diff --git a/.planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-06-SUMMARY.md b/.planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-06-SUMMARY.md new file mode 100644 index 0000000..b3fa023 --- /dev/null +++ b/.planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-06-SUMMARY.md @@ -0,0 +1,114 @@ +--- +phase: 06-http-routing-auth-groups-and-rate-limiting +plan: 06 +subsystem: api-security +tags: [rate-limiting, middleware-order, personal-token, security-review, httptest] + +requires: + - phase: 06-http-routing-auth-groups-and-rate-limiting + provides: inv_token guard, InvScope, FixedWindowLimiter, fonoteka-api-token bucket, assembled route tests +provides: + - personal-token route order that rate-limits unauthenticated deny traffic before InvScope + - assembled-router proof of 401 through request 60 and exact 429 on request 61 + - T-06-21 and T-06-22 security evidence with 21 threats closed and zero open +affects: [phase-07-user-plugin, phase-08-oauth, personal-token-routes, security-review] + +tech-stack: + added: [] + patterns: + - personal-token middleware order is inv_token -> throttle: -> inv.scope: + - deny-path limiter regressions use one fresh surf.Assemble handler and stable RemoteAddr + +key-files: + created: [] + modified: + - plugins/golem15/fonoteka/routes.go + - plugins/golem15/fonoteka/routes_isolation_test.go + - .planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-SECURITY-REVIEW.md + +key-decisions: + - "Keep inv_token outermost so valid credentials populate bouncer.Credential before the limiter selects tok:" + - "Place throttle before InvScope so missing and invalid credentials consume the per-IP deny-path budget" + +patterns-established: + - "Any live route combining inv_token, a named throttle, and inv.scope declares them in that exact source order" + - "Rate-limit exhaustion tests exercise the real plugin set and production route rather than hand-composed middleware" + +requirements-completed: [HTTP-04] + +duration: 1h 29m +completed: 2026-09-20 +--- + +# Phase 6 Plan 06: Personal-token deny-path rate-limit gap closure Summary + +**Personal-token genres now preserves per-token keying while bounding unauthenticated 401 traffic at 60 requests per minute, with assembled-route and security-review evidence** + +## Performance + +- **Duration:** 1h 29m +- **Started:** 2026-09-20T10:01:25Z +- **Completed:** 2026-09-20T11:30:57Z +- **Tasks:** 2 +- **Files modified:** 3 + +## Accomplishments + +- Reordered the live personal-token genres middleware to `inv_token`, `throttle:fonoteka-api-token`, `inv.scope:read`, preserving valid-token `tok:` keys while limiting unauthenticated fallback traffic by client IP. +- Added `TestPersonalTokenGenresUnauthenticatedRequestsAreRateLimited`, which drives 61 same-IP requests through one fresh handler returned by `surf.Assemble`: requests 1-60 retain the PHP-compatible 401 body and request 61 receives the exact 429 body and exhausted-limit headers. +- Extended `06-SECURITY-REVIEW.md` through Plan 06-06 with T-06-21/T-06-22, 21 closed threats, zero open, and no new accepted risk. +- Passed the targeted regression, `go vet ./...`, and repository-wide `go test ./... -short` in `fonoteka.go`. + +## Task Commits + +Each task was committed atomically: + +1. **Task 1: Repair personal-token middleware order and prove deny-path throttling** - `33f721d` (fix, fonoteka.go) +2. **Task 2: Extend the Phase 6 security review through gap closure** - `3423da2` (docs, summercms.go) + +**Plan metadata:** (this commit) + +## Files Created/Modified + +- `plugins/golem15/fonoteka/routes.go` - Declares the live personal-token middleware in credential, limiter, then scope order. +- `plugins/golem15/fonoteka/routes_isolation_test.go` - Proves the assembled production route returns 401 through request 60 and exact 429 on request 61. +- `.planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-SECURITY-REVIEW.md` - Maps T-06-21/T-06-22 to the runtime-order invariant and regression evidence. + +## Decisions Made + +- `inv_token` remains before the limiter so valid credentials populate `bouncer.Credential` before the bucket closure resolves `tok:`. +- `throttle:fonoteka-api-token` remains before `inv.scope:read` so missing and invalid credentials consume the per-IP fallback bucket before the scope gate returns 401. + +## Deviations from Plan + +None - plan executed exactly as written. + +## Issues Encountered + +- The delegated executor stopped returning progress after partially editing the sibling `fonoteka.go` repository. After the configured stall threshold and user-approved recovery, execution switched inline; the partial diff was inspected, retained, validated, and committed without duplication. +- The sandboxed full test run could not access the Docker daemon used by the parity harness. The same required command passed after rerunning with approved Docker access. + +## User Setup Required + +None - no external service configuration required. + +## Next Phase Readiness + +- HTTP-04's verification blocker and code-review CR-01 are directly closed. +- Phase 6 is ready for re-verification; no Plan 06-06 implementation blockers remain. + +## Self-Check: PASSED + +- FOUND: `../fonoteka.go/plugins/golem15/fonoteka/routes.go` +- FOUND: `../fonoteka.go/plugins/golem15/fonoteka/routes_isolation_test.go` +- FOUND: `.planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-SECURITY-REVIEW.md` +- FOUND: `33f721d` in `fonoteka.go` +- FOUND: `3423da2` in `summercms.go` +- PASS: targeted assembled-router regression +- PASS: `go vet ./...` in `fonoteka.go` +- PASS: `go test ./... -short` in `fonoteka.go` +- PASS: T-06-21/T-06-22 evidence and audit total 21 closed / 0 open + +--- +*Phase: 06-http-routing-auth-groups-and-rate-limiting* +*Completed: 2026-09-20*