---
phase: 08-oauth2-1-authorization-server
plan: 06
type: execute
wave: 6
depends_on: [08-05]
files_modified:
- wristband/phase08_coverage_test.go
- ../fonoteka.go/plugins/golem15/fonoteka/phase08_coverage_test.go
- ../fonoteka.go/parity/oauth_audit_test.go
- scripts/check-phase8.sh
- .planning/phases/08-oauth2-1-authorization-server/08-PHP-TEST-MAP.md
- .planning/phases/08-oauth2-1-authorization-server/08-SECURITY-REVIEW.md
- .planning/phases/08-oauth2-1-authorization-server/08-VALIDATION.md
autonomous: false
requirements: [AUTH-05, AUTH-06, AUTH-07]
must_haves:
truths:
- "Every PHP OAuth functional/security test method maps to a named passing Go test or subtest, and both repositories pass vet/test/race."
- "Every T-08 threat maps to a failing-when-broken test with zero open high-severity findings."
- "The phase gate refuses missing tests, route parity, secret scans, unchanged-client evidence, or an unverified security review."
artifacts:
- path: ".planning/phases/08-oauth2-1-authorization-server/08-PHP-TEST-MAP.md"
provides: "Auditable one-to-one map of all 103 PHP methods to Go evidence"
- path: ".planning/phases/08-oauth2-1-authorization-server/08-SECURITY-REVIEW.md"
provides: "ASVS L1 threat disposition and executed evidence"
- path: ".planning/phases/08-oauth2-1-authorization-server/08-VALIDATION.md"
provides: "Nyquist-complete task/status and gate sign-off"
key_links:
- from: "08-SECURITY-REVIEW.md"
to: "named Go tests"
via: "file:TestName evidence for every mitigated threat"
pattern: "T-08-"
- from: "scripts/check-phase8.sh"
to: "08-SECURITY-REVIEW.md"
via: "fail-closed verified/zero-open audit check"
pattern: "08-SECURITY-REVIEW"
---
Close Phase 8 with complete unit/security coverage, an independent security-review agent pass, and one fail-closed verification gate.
Purpose: Demonstrate that the exact OAuth implementation is not merely functional but resistant to every identified high-severity replay, redirect, timing, scope, ownership, leakage, flooding, and surface threat.
Output: Coverage tests, 103-method audit map, verified security review, signed validation strategy, and final gate.
## Phase Goal
**As a** Płytarium operator, **I want to** rely on independently reviewed OAuth behavior and complete regression evidence, **so that** unchanged connectors can be enabled without accepting an unproven high-severity security risk.
@/home/jin/.codex/get-shit-done/workflows/execute-plan.md
@/home/jin/.codex/get-shit-done/templates/summary.md
@.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-VALIDATION.md
@.planning/phases/08-oauth2-1-authorization-server/08-05-SUMMARY.md
@.planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-SECURITY-REVIEW.md
Security-review evidence contract:
- One register row per `T-08-*` threat with category, component, disposition, mitigation, and exact `file:TestName` evidence.
- Frontmatter reports total/closed/open and status; completion requires `status: verified`, `threats_open: 0`, and no unmitigated HIGH.
PHP test inventory contract:
- 103 methods: authorize 11, client-command 8, metadata 2, migration 7, register 10, token 10, consent/scope 7, refresh rotation 10, revocation 8, surface isolation 30.
Task 1: Close the 103-method PHP audit and Phase 8 coverage gaps
wristband/phase08_coverage_test.go, ../fonoteka.go/plugins/golem15/fonoteka/phase08_coverage_test.go, ../fonoteka.go/parity/oauth_audit_test.go, .planning/phases/08-oauth2-1-authorization-server/08-PHP-TEST-MAP.md
.planning/phases/08-oauth2-1-authorization-server/08-CONTEXT.md
.planning/phases/08-oauth2-1-authorization-server/08-VALIDATION.md
wristband/registration_test.go
wristband/authorize_test.go
wristband/token_test.go
../fonoteka.go/plugins/golem15/fonoteka/controllers/api/oauth_consent_controller_test.go
../fonoteka.go/plugins/golem15/fonoteka/controllers/api/connected_app_controller_test.go
../fonoteka.go/plugins/golem15/fonoteka/oauth_registration_test.go
../fonoteka.go/plugins/golem15/fonoteka/oauth_connect_test.go
../fonoteka.go/plugins/golem15/fonoteka/oauth_lifecycle_test.go
../fonoteka.go/plugins/golem15/fonoteka/oauth_tools_test.go
/media/nvme/dev/golem15/fonoteka/plugins/golem15/fonoteka/tests/functional/OAuthAuthorizeTest.php
/media/nvme/dev/golem15/fonoteka/plugins/golem15/fonoteka/tests/functional/OAuthClientCommandTest.php
/media/nvme/dev/golem15/fonoteka/plugins/golem15/fonoteka/tests/functional/OAuthMetadataTest.php
/media/nvme/dev/golem15/fonoteka/plugins/golem15/fonoteka/tests/functional/OAuthMigrationTest.php
/media/nvme/dev/golem15/fonoteka/plugins/golem15/fonoteka/tests/functional/OAuthRegisterTest.php
/media/nvme/dev/golem15/fonoteka/plugins/golem15/fonoteka/tests/functional/OAuthTokenTest.php
/media/nvme/dev/golem15/fonoteka/plugins/golem15/fonoteka/tests/security/OAuthConsentScopeCeilingTest.php
/media/nvme/dev/golem15/fonoteka/plugins/golem15/fonoteka/tests/security/OAuthRefreshRotationTest.php
/media/nvme/dev/golem15/fonoteka/plugins/golem15/fonoteka/tests/security/OAuthRevocationTest.php
/media/nvme/dev/golem15/fonoteka/plugins/golem15/fonoteka/tests/security/TokenSurfaceIsolationTest.php
- Every PHP method is listed once with its source class, behavior, and a named Go test/subtest that actually runs.
- Coverage tests exercise error branches, encoding failures, nil/misconfigured dependencies, clock/entropy errors, parser edges, and route/config drift not already covered.
- Audit fails if a mapped Go test is renamed/missing or if any PHP method is unmapped/duplicated.
Per D-18 and the repository rule that unit coverage is the last plan, enumerate all 103 PHP methods into `08-PHP-TEST-MAP.md`, map each to existing Phase 8 tests, and add focused coverage tests only where no named evidence exists. Add an executable audit that parses the inventory/map and Go test list so counts alone cannot hide missing or duplicate mappings. Close framework handler/store branches, app boot/config/route/controller/command branches, parity projections, and every exact response/header path. Do not replace behavior assertions with coverage-only calls or map one broad test to methods whose distinct assertions are absent.
go test ./wristband -count=1 && cd ../fonoteka.go && go test ./plugins/golem15/fonoteka/... ./parity -run 'Test(OAuth|Phase08|PHPTestMap|TokenSurface|MeToken)' -count=1
- The map contains exactly 103 unique PHP method rows distributed 11/8/2/7/10/10/7/10/8/30 by source suite.
- The executable audit confirms every mapped Go `TestName[/subtest]` exists and executes; missing or duplicate rows make it fail.
- Both repositories pass full `go vet ./...`, `go test ./...`, and `go test -race ./...`, including nested plugin modules.
- Coverage additions retain exact byte/header/concurrency assertions for security branches.
All PHP OAuth behavior has one-to-one named Go evidence and the phase's code paths are covered by meaningful regression tests.
Task 2: Run the mandated security-review agent and close every high-severity finding
.planning/phases/08-oauth2-1-authorization-server/08-SECURITY-REVIEW.md, .planning/phases/08-oauth2-1-authorization-server/08-VALIDATION.md, scripts/check-phase8.sh
.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-PHP-TEST-MAP.md
.planning/phases/08-oauth2-1-authorization-server/08-VALIDATION.md
.planning/phases/06-http-routing-auth-groups-and-rate-limiting/06-SECURITY-REVIEW.md
scripts/check-phase8.sh
wristband/server.go
wristband/authorize.go
wristband/token.go
wristband/register.go
wristband/crypto.go
../fonoteka.go/plugins/golem15/fonoteka/classes/auth/oauth_store.go
../fonoteka.go/plugins/golem15/fonoteka/controllers/api/oauth_consent_controller.go
../fonoteka.go/plugins/golem15/fonoteka/controllers/api/connected_app_controller.go
../fonoteka.go/plugins/golem15/fonoteka/routes.go
Invoke the `gsd-security-auditor` security-review agent against all Phase 8 production/test changes and the locked threat map, explicitly requiring OWASP ASVS L1 review of T-08-PKCE, CODE-REPLAY, REFRESH-REPLAY, OPEN-REDIRECT, SECRET-TIMING, SCOPE-CEILING, CROSS-USER, REQUEST-LEAK, DCR-FLOOD, SURFACE, and supply-chain status. Write `08-SECURITY-REVIEW.md` in the Phase 6 format with trust boundaries, complete STRIDE register, severity, disposition, mitigation, and executed `file:TestName` evidence. If the agent finds any HIGH issue, stop sign-off, implement the narrow fix and failing regression in the owning Phase 8 file, rerun the focused and full gates, and re-run the auditor until no HIGH remains. Then update VALIDATION task IDs/statuses, set `nyquist_compliant: true` and `wave_0_complete: true`, and add a fail-closed verified/zero-open security-review check to `check-phase8.sh`.
scripts/check-phase8.sh
- `08-SECURITY-REVIEW.md` has `status: verified`, `threats_open: 0`, and one evidence-backed disposition for every named T-08 threat plus T-08-SC.
- Every HIGH finding is mitigated by a named failing-when-broken test; no HIGH is accepted, deferred, or omitted.
- Static evidence finds `crypto/subtle.ConstantTimeCompare` for client secret and PKCE, row locks for code/refresh, committed replay kill, 64 KiB register cap, raw/JWT/personal route isolation, and no sensitive-value logging.
- `08-VALIDATION.md` maps final plan/task IDs, all required test/gate files exist, all statuses are green, and both Nyquist flags are true.
- `scripts/check-phase8.sh` exits nonzero if the review is missing, unverified, has a nonzero open count, or lacks any required T-08 row.
An independent security agent has reviewed the implemented phase, all high-severity findings are closed with executable evidence, and the final gate enforces the review.
Task 3: Approve the OAuth security and unchanged-client evidence
.planning/phases/08-oauth2-1-authorization-server/08-SECURITY-REVIEW.md, .planning/phases/08-oauth2-1-authorization-server/08-VALIDATION.md
.planning/phases/08-oauth2-1-authorization-server/08-SECURITY-REVIEW.md
.planning/phases/08-oauth2-1-authorization-server/08-PHP-TEST-MAP.md
.planning/phases/08-oauth2-1-authorization-server/08-VALIDATION.md
.planning/phases/08-oauth2-1-authorization-server/08-05-SUMMARY.md
Present the completed automated evidence after the security-review agent has produced zero open high-severity findings. Do not ask the user to rerun automation; show the exact gate result, threat totals, 103-method audit result, nine-route parity result, real-MCP lifecycle result, and unchanged Nuxt/MCP worktree checks. Block completion if any displayed result is missing or non-green.
scripts/check-phase8.sh
Direct standard-library OAuth authorization server with DCR, S256 PKCE, JWT consent, authorization-code and rotating-refresh grants, connected-app revocation, operator client command, MCP bootstrap endpoint, PHP parity, and unchanged real-MCP proof.
1. Review `08-SECURITY-REVIEW.md`; expect `status: verified`, zero open threats, and named test evidence for every T-08 row.
2. Review the recorded gate transcript; expect both repositories' vet/test/race, 103/103 PHP method map, nine OAuth route replays, secret scan, and real MCP lifecycle to be green.
3. Confirm the Nuxt and fonoteka-mcp repositories have no Phase 8 source diff.
- Human approval occurs only after zero open HIGH findings and a passing `scripts/check-phase8.sh` result are shown.
- The evidence explicitly includes exact Basic `WWW-Authenticate` at backend invalid-client, unchanged no-challenge token 401, and MCP-owned rich Bearer/resource-metadata behavior.
- Rejection includes the failing threat/test/gate identifier so remediation is deterministic.
Type "approved" to close Phase 8, or provide the failed threat/test/gate identifier.
The user has accepted the complete automated OAuth compatibility and security evidence.
## Trust Boundaries
| Boundary | Description |
|----------|-------------|
| Phase implementation → independent auditor | Claims must be supported by executable evidence, not implementation intent. |
| Test inventory → completion status | Missing/renamed tests or unmapped PHP methods must fail closed. |
| Security report → phase gate | Stale, missing, or open findings must prevent sign-off. |
## STRIDE Threat Register
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|-----------|----------|-----------|-------------|-----------------|
| T-08-PKCE | Spoofing/Elevation | authorize/exchange | mitigate | Independent audit plus missing/plain/wrong/syntax/constant-time tests. |
| T-08-CODE-REPLAY | Spoofing | code transaction | mitigate | Sequential/concurrent single-winner tests and row-lock source evidence. |
| T-08-REFRESH-REPLAY | Spoofing/Elevation | refresh transaction | mitigate | Branch-concurrency and post-error persisted lineage-kill evidence. |
| T-08-OPEN-REDIRECT | Spoofing/Disclosure | redirect construction | mitigate | Exact allow-list/validation-order and no-Location tests. |
| T-08-SECRET-TIMING | Information Disclosure | crypto/client auth | mitigate | `subtle.ConstantTimeCompare` source gate and invalid-secret behavior tests. |
| T-08-SCOPE-CEILING | Elevation | authorize/consent/refresh | mitigate | End-to-end requested/submitted/ceiling/mintable and server-derived tenant proofs. |
| T-08-CROSS-USER | Elevation | consent/connected apps | mitigate | Foreign ownership tests with indistinguishable 404s. |
| T-08-REQUEST-LEAK | Information Disclosure | logs/fixtures/output | mitigate | Log capture, source scan, fixture secret scan, positive output allow-lists. |
| T-08-DCR-FLOOD | Denial of Service | register | mitigate | 64 KiB cap, limiter, atomic client cap, sweep, concurrency evidence. |
| T-08-SURFACE | Elevation | route/MCP boundary | mitigate | Assembled route table and real client header-ownership gate. |
| T-08-SC | Tampering | package supply chain | mitigate | No added package; module-diff and package-audit checks. |
- `go vet ./... && go test ./... && go test -race ./...`
- `cd ../fonoteka.go && go vet ./... && go test ./... && go test -race ./...`
- `scripts/check-phase8.sh`
- Human approval after independent security review reports zero open HIGH findings.
- All 103 PHP methods map uniquely to named passing Go tests/subtests.
- All T-08 threats have explicit dispositions and executable evidence; zero high-severity findings remain open.
- Nyquist validation, parity, secret scan, and unchanged real-MCP lifecycle are green in the final gate.
- The blocking human security checkpoint is approved.