Files
summercms/.planning/phases/08-oauth2-1-authorization-server/08-04-PLAN.md
2026-09-23 17:13:47 +02:00

6.6 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
phase plan type wave depends_on files_modified autonomous requirements must_haves
08-oauth2-1-authorization-server 04 execute 4
08-03
wristband/authorize.go
wristband/token.go
wristband/authorize_test.go
wristband/token_test.go
../fonoteka.go/plugins/golem15/fonoteka/classes/auth/oauth_store.go
../fonoteka.go/plugins/golem15/fonoteka/classes/auth/oauth_token_issuer.go
../fonoteka.go/plugins/golem15/fonoteka/classes/auth/api_token_manager.go
true
AUTH-05
AUTH-06
truths artifacts key_links
D-02: Authorize reads query only and token rejects JSON before ParseForm body-over-query parsing.
D-04: S256/client-secret comparisons are constant-time and code replay has one winner.
D-05: Wristband owns authorize, PKCE, scope/resource policy, and atomic code exchange.
D-11: Issued access tokens retain the configured inv_ prefix.
path provides
wristband/authorize.go Ordered validation, redirects, PKCE, resource and scope policy
path provides
wristband/token.go Client authentication and atomic authorization-code exchange
from to via pattern
wristband/token.go oauth_token_issuer.go single transaction-bound Tx WithinTx
Implement the protocol core from authorize validation through one atomic authorization-code exchange.

Purpose: Prove PKCE, redirect, parser, scope, client-auth, and code-replay rules independently of the browser controller. Output: Authorize/token handlers, issuer adapter, store transitions, and deterministic/concurrent tests.

<execution_context> @/home/jin/.codex/get-shit-done/workflows/execute-plan.md @/home/jin/.codex/get-shit-done/templates/summary.md </execution_context>

@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/08-oauth2-1-authorization-server/08-CONTEXT.md @.planning/phases/08-oauth2-1-authorization-server/08-RESEARCH.md @.planning/phases/08-oauth2-1-authorization-server/08-03-SUMMARY.md Task 1: Specify authorize and code exchange with executable RED tests wristband/authorize.go, wristband/token.go, wristband/authorize_test.go, wristband/token_test.go, ../fonoteka.go/plugins/golem15/fonoteka/classes/auth/oauth_store.go, ../fonoteka.go/plugins/golem15/fonoteka/classes/auth/oauth_token_issuer.go - Unknown client/unregistered redirect are local 400 without Location; later errors use exact ordered RFC3986 redirects. - S256 is mandatory; parser precedence, Basic override, cache headers, and exact challenge are tested. - Tests compile and fail only through `PHASE8_RED:authorize-token`. D-18: extend the existing interfaces with compiling authorize/token stubs and add deterministic unit plus real-store adapter tests. Use explicit `PHASE8_RED:authorize-token` assertions for absent behavior. Reject syntax/build/setup/missing-test failures through the shared RED verifier. Cover T-08-PKCE, CODE-REPLAY, OPEN-REDIRECT, SECRET-TIMING, SCOPE-CEILING, and REQUEST-LEAK, including synchronized concurrent code exchange. scripts/check-phase8-red.sh authorize-token go test ./wristband -run 'Test(Authorize|Token|PKCE|Code)' -count=1 Named tests compile and execute, with the verifier accepting only the intended missing-behavior marker. Task 2: Implement ordered authorize and atomic code exchange wristband/authorize.go, wristband/token.go, wristband/authorize_test.go, wristband/token_test.go, ../fonoteka.go/plugins/golem15/fonoteka/classes/auth/oauth_store.go, ../fonoteka.go/plugins/golem15/fonoteka/classes/auth/oauth_token_issuer.go, ../fonoteka.go/plugins/golem15/fonoteka/classes/auth/api_token_manager.go - Validation order is usable client, exact redirect, response type, S256 method/challenge, scope ceiling, resource, pending creation. - Code lock/consume, access-token mint/stamp, and refresh creation commit atomically once. D-02: implement endpoint-specific parsing and reject JSON token calls before ParseForm. D-03: apply configured TTL/resource. D-04: compare fixed transforms with `subtle.ConstantTimeCompare`. D-05 and D-06: keep state/policy and exact raw responses in wristband. D-07: exchange under one app transaction/row lock. Build redirects from ordered pairs, never `url.Values.Encode`. D-11: make the app adapter prefix config-backed while retaining `inv_`. D-17: run expired-only sweep on token entry. Preserve exact `Basic realm="OAuth"`, no-store, and no-cache headers. go test ./wristband -run 'Test(Authorize|Token|PKCE|Code)' -count=1 && cd ../fonoteka.go && go test ./plugins/golem15/fonoteka/classes/auth -run 'TestOAuth(Code|Issuer)' -count=1 One exact PKCE-bound code produces one inv_ access/refresh grant, and all validation/parser/replay failures are exact and tested.

<threat_model>

Trust Boundaries

Boundary Description
Connector → authorize/token Untrusted query/form/Basic input requests or redeems authority.
Tx → access-token store One-time code state becomes durable credentials.

STRIDE Threat Register

Threat ID Category Component Disposition Mitigation Plan
T-08-PKCE Spoofing/Elevation authorize/token mitigate Mandatory S256 syntax and constant-time comparison.
T-08-CODE-REPLAY Spoofing exchange mitigate Row lock, single transaction, concurrent one-winner test.
T-08-OPEN-REDIRECT Spoofing/Disclosure authorize mitigate Exact redirect validation before any redirect.
T-08-SECRET-TIMING Information Disclosure client auth mitigate Fixed transforms and constant-time compare.
T-08-SCOPE-CEILING Elevation authorize mitigate Requested ∩ client ceiling before persistence.
T-08-SC Tampering dependencies mitigate Standard library and existing app services only.
</threat_model>
- Focused wristband and issuer/store tests pass. - `go test -race ./wristband` passes at wave boundary.

<success_criteria>

  • Authorize and token protocol behavior is exact, concurrency-safe, and app-agnostic.
  • The configured personal-token issuer produces the unchanged inv_ wire format. </success_criteria>
Create `.planning/phases/08-oauth2-1-authorization-server/08-04-SUMMARY.md` when done.