fix(08): revise plans based on checker feedback
This commit is contained in:
110
.planning/phases/08-oauth2-1-authorization-server/08-08-PLAN.md
Normal file
110
.planning/phases/08-oauth2-1-authorization-server/08-08-PLAN.md
Normal file
@@ -0,0 +1,110 @@
|
||||
---
|
||||
phase: 08-oauth2-1-authorization-server
|
||||
plan: 08
|
||||
type: execute
|
||||
wave: 7
|
||||
depends_on: [08-06]
|
||||
files_modified:
|
||||
- ../fonoteka.go/plugins/golem15/fonoteka/controllers/api/me_token_controller.go
|
||||
- ../fonoteka.go/plugins/golem15/fonoteka/controllers/api/me_token_controller_test.go
|
||||
- ../fonoteka.go/plugins/golem15/fonoteka/routes.go
|
||||
- ../fonoteka.go/plugins/golem15/fonoteka/oauth_tools_test.go
|
||||
autonomous: true
|
||||
requirements: [AUTH-07]
|
||||
must_haves:
|
||||
truths:
|
||||
- "D-20: The unchanged fonoteka-mcp receives exact scopes, collection_ids, user_id, and name from personal-token GET /me."
|
||||
- "D-12: Invalid personal tokens retain exact Invalid token bytes and no backend Bearer/resource-metadata challenge."
|
||||
artifacts:
|
||||
- path: "../fonoteka.go/plugins/golem15/fonoteka/controllers/api/me_token_controller.go"
|
||||
provides: "Minimal MCP bootstrap endpoint"
|
||||
key_links:
|
||||
- from: "me_token_controller.go"
|
||||
to: "bouncer.Credential"
|
||||
via: "reuse matched ApiToken without reparsing bearer input"
|
||||
pattern: "Credential"
|
||||
---
|
||||
|
||||
<objective>
|
||||
Serve the exact personal-token bootstrap needed by the unchanged MCP process.
|
||||
|
||||
Purpose: Deliver the approved D-20 prerequisite as an isolated auth-surface slice that can execute in parallel with operator provisioning.
|
||||
Output: `/api/v1/fonoteka/me`, route isolation, and assembled tests.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
@/home/jin/.codex/get-shit-done/workflows/execute-plan.md
|
||||
@/home/jin/.codex/get-shit-done/templates/summary.md
|
||||
</execution_context>
|
||||
|
||||
<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-UI-SPEC.md
|
||||
@.planning/phases/08-oauth2-1-authorization-server/08-06-SUMMARY.md
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto" tdd="true">
|
||||
<name>Task 1: Specify exact MCP bootstrap and token-surface behavior in RED</name>
|
||||
<files>../fonoteka.go/plugins/golem15/fonoteka/controllers/api/me_token_controller_test.go, ../fonoteka.go/plugins/golem15/fonoteka/oauth_tools_test.go</files>
|
||||
<behavior>
|
||||
- Valid read-scoped inv_ token returns exactly four fields; arrays are never null.
|
||||
- Missing/invalid/wrong-scope tokens preserve existing exact 401/403 bytes and headers.
|
||||
- Tests compile and fail only through `PHASE8_RED:mcp-me`.
|
||||
</behavior>
|
||||
<action>D-18 and D-20: use the assembled surf router and existing inv_token guard, not direct controller injection. Add exact positive/negative payload and route-isolation tests; mark only missing `/me` behavior with `PHASE8_RED:mcp-me` and reject syntax/setup/missing-test failures via the shared verifier.</action>
|
||||
<verify>
|
||||
<automated>scripts/check-phase8-red.sh mcp-me bash -lc "cd ../fonoteka.go && go test ./plugins/golem15/fonoteka/... -run 'Test(MeToken|TokenSurface|OAuthTools)' -count=1"</automated>
|
||||
</verify>
|
||||
<done>The assembled RED tests run through the real guard and fail only on absent `/me` behavior.</done>
|
||||
</task>
|
||||
|
||||
<task type="auto" tdd="true">
|
||||
<name>Task 2: Mount exact personal-token MCP bootstrap</name>
|
||||
<files>../fonoteka.go/plugins/golem15/fonoteka/controllers/api/me_token_controller.go, ../fonoteka.go/plugins/golem15/fonoteka/controllers/api/me_token_controller_test.go, ../fonoteka.go/plugins/golem15/fonoteka/routes.go, ../fonoteka.go/plugins/golem15/fonoteka/oauth_tools_test.go</files>
|
||||
<behavior>
|
||||
- Handler reads matched ApiToken and principal, emits only exact four fields, and performs no second lookup.
|
||||
- Route inherits inv_token, throttle, inv.scope:read in order and appears nowhere else.
|
||||
</behavior>
|
||||
<action>D-20: implement the exact handler using `bouncer.Credential` and `bouncer.User`, initialize arrays, preserve nullable name, and emit only locked fields through wire.WriteJSON. Mount GET `/me` in the existing personal-token group after its three middleware. D-12: leave invalid-token bytes/headers unchanged and add no RFC 9728 or Bearer challenge.</action>
|
||||
<verify>
|
||||
<automated>cd ../fonoteka.go && go test ./plugins/golem15/fonoteka/... -run 'Test(MeToken|TokenSurface|OAuthTools)' -count=1</automated>
|
||||
</verify>
|
||||
<done>The unchanged MCP process can bootstrap from an issued inv_ token without profile-surface expansion or header drift.</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<threat_model>
|
||||
## Trust Boundaries
|
||||
|
||||
| Boundary | Description |
|
||||
|----------|-------------|
|
||||
| Bearer header → personal-token /me | Untrusted bearer input crosses existing token and scope guards. |
|
||||
|
||||
## STRIDE Threat Register
|
||||
|
||||
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|
||||
|-----------|----------|-----------|-------------|-----------------|
|
||||
| T-08-SCOPE-CEILING | Elevation | /me | mitigate | Existing inv.scope:read middleware. |
|
||||
| T-08-REQUEST-LEAK | Information Disclosure | response | mitigate | Four-field positive allow-list. |
|
||||
| T-08-SURFACE | Elevation | routes | mitigate | Personal-token-only route-table proof. |
|
||||
| T-08-SC | Tampering | dependencies | mitigate | No install. |
|
||||
</threat_model>
|
||||
|
||||
<verification>
|
||||
- Focused `/me` and token-surface tests pass.
|
||||
- Route table shows exact middleware order and no JWT/raw duplicate.
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- Real MCP bootstrap payload is exact and token failures remain unchanged.
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
Create `.planning/phases/08-oauth2-1-authorization-server/08-08-SUMMARY.md` when done.
|
||||
</output>
|
||||
Reference in New Issue
Block a user