docs(16.3-01): complete framework personal API tokens plan

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-11 01:56:03 +02:00
parent e24e03c47d
commit 3019ab188b

View File

@@ -0,0 +1,189 @@
---
phase: 16.3-backend-admin-personal-api-tokens-with-scopes
plan: 01
subsystem: auth
tags: [api-tokens, scopes, cabana, bouncer, pact, party, lagoon, admin-cli, openapi, g15]
requires:
- phase: 16.2-plugin-provided-field-types-and-the-blog-editor-formwidget
provides: cabana Activate, admin OpenAPI inventories, BackendAdminMigrations, My account routes
provides:
- "pact.TokenScope and pact.HasTokenScopes"
- "bouncer.ScopeLimit and Principal.Scope"
- "backend_api_tokens migration and cabana.BackendAPIToken / APITokenPrefix"
- "composite backend guard, interactiveOnly, tokenRouteGate, ResolveBackend, ErrUnauthenticated, ErrTokenScope"
- "account token API (list/create/revoke/scopes) with OpenAPI and phrase keys"
- "admin:token:* CLI via party.Activated and summer delegates"
- "framework READMEs and docs for tokens, scopes, ResolveBackend and CLI"
affects: [16.3-02, 16.3-03, 16.3-04, sm-journal-plugin]
actuals:
tokens: 40262
tasks: 4
commits: 5
plan_head_before: 4d107f4ccb3ed00bf12b680b07c2e7874b345198
plan_head_after: e24e03c47d84f854b6c66c1b317940492b60f441
tech-stack:
added: []
patterns:
- "Composite backend guard: Bearer g15_ → token branch; else unchanged JWT+cookie path"
- "party.Activated published at Activate for CLI catalog without changing RuntimeCommands(app)"
- "Scope before superuser/empty-list in Allows; interactive_only and token_scope reasons"
key-files:
created:
- modules/cabana/api_tokens.go
- modules/cabana/token_scopes.go
- modules/cabana/token_guard.go
- modules/cabana/account_tokens.go
- modules/cabana/token_commands.go
- modules/cabana/token_smoke_test.go
- modules/cabana/token_postgres_smoke_test.go
- docs/examples/blog/token_scopes.go
modified:
- modules/pact/capabilities.go
- modules/bouncer/context.go
- modules/lagoon/backend_admin_migrations.go
- modules/cabana/contracts.go
- modules/cabana/http.go
- modules/cabana/registry.go
- modules/cabana/admin_openapi.go
- modules/party/registry.go
- cmd/summer/runtime.go
- admin/openapi/admin.json
- admin/src/api/schema.d.ts
- modules/phrasebook/backend/lang/en/lang.yaml
- modules/phrasebook/backend/lang/pl/lang.yaml
- docs/backend/users-and-permissions.md
- docs/services/authentication.md
- docs/console/setup-and-maintenance.md
- docs/console/introduction.md
- docs/plugins/registration.md
key-decisions:
- "D-03 literal: one method-allowed scope must match every required code; ScopeLimit keeps per-scope pattern slices"
- "CLI uses party.Activated at Run time; cabana.RuntimeCommands(app) signature unchanged (Option A)"
- "ResolveBackend is Bearer-only (cookie-less JWT guard) so plugin writes cannot be CSRF-driven by summer_admin"
- "Exported names match the plan Interfaces section; no as-built renames"
patterns-established:
- "Personal API token: g15_+40 hex, sha256+hint stored, plaintext once on create/CLI stdout"
- "Plugin scopes via HasTokenScopes; framework * and admin:read; boot fails loud on bad registration"
requirements-completed: [SC-1, SC-2, SC-3, SC-5]
coverage:
- id: D1
description: "g15_ token authenticates through the composite backend guard as its owner, scoped by Allows"
requirement: SC-1
verification:
- kind: unit
ref: modules/cabana/token_smoke_test.go#TestTokenTracerSmoke
status: pass
- kind: integration
ref: modules/cabana/token_postgres_smoke_test.go#TestTokenTracerPostgres
status: pass
human_judgment: false
- id: D2
description: "Out-of-scope and non-Allows routes refuse tokens; interactive-only routes refuse all personal tokens; ResolveBackend and last_used debounce work"
requirement: SC-2
verification:
- kind: unit
ref: modules/cabana/token_smoke_test.go#TestTokenGatesSmoke
status: pass
human_judgment: false
- id: D3
description: "Account token API list/create/revoke/scopes with OpenAPI, inventories and phrase keys"
requirement: SC-3
verification:
- kind: integration
ref: modules/cabana/token_postgres_smoke_test.go#TestAccountTokensSmoke
status: pass
- kind: other
ref: bash scripts/check-admin-openapi.sh --check
status: pass
human_judgment: false
- id: D4
description: "admin:token:* CLI with party.Activated, summer delegates, READMEs and docs"
requirement: SC-5
verification:
- kind: integration
ref: modules/cabana/token_postgres_smoke_test.go#TestTokenCommandsSmoke
status: pass
- kind: unit
ref: cmd/summer/runtime_test.go#TestDelegateCommandsHelp
status: pass
- kind: other
ref: go run ./cmd/summer docs:build --check
status: pass
human_judgment: false
duration: 95min
completed: 2026-10-11
status: complete
---
# Phase 16.3 Plan 01: Framework personal API tokens Summary
**Scoped g15_ personal API tokens through a composite backend guard, account API, admin:token CLI and docs — owner ∩ scope, interactive-only gates, ResolveBackend for plugins.**
## Performance
- **Duration:** 95 min
- **Started:** 2026-10-10T23:41:00Z
- **Completed:** 2026-10-11T00:00:00Z
- **Tasks:** 4
- **Files modified:** 43
## Accomplishments
- Tracer path: mint → hash store → composite guard → ScopeLimit → Allows (scope before superuser)
- Deny-by-default gates: interactiveOnly, field-types/markdown tokenRouteGate, published ResolveBackend, debounced last_used_at
- Account token API with OpenAPI/TS types, inventories and backend::lang.api_tokens phrase keys
- admin:token:* CLI via party.Activated, summer delegates, blog HasTokenScopes example, five module READMEs and five docs pages
## Task Commits
Each task was committed atomically:
1. **Task 1: Tracer** - `b9273c1` (feat)
2. **Task 2: Gates, ResolveBackend, stamp** - `183583e` (feat)
3. **Task 3: Account token API + OpenAPI** - `ffdb5d0` (feat)
4. **Task 4: CLI, party.Activated, READMEs/docs** - `e24e03c` (feat)
**Plan metadata:** (this commit)
## Exported API as built
Matches the plan Interfaces section: `pact.TokenScope` / `HasTokenScopes`; `bouncer.ScopeLimit` / `Principal.Scope`; `party.Activated`; `cabana.BackendAPIToken`, `APITokenPrefix`, `ResolveBackend`, `ErrUnauthenticated`, `ErrTokenScope`; OpenAPI types and swag stubs; CLI `admin:token:create|list|revoke|scopes`. No name differs from the plan.
## Decisions Made
- Followed locked D-01–D-20 and Option A for CLI plugin access (`party.Activated`).
- `validateTokenRequest` + `validateTokenScopes` helper; `compilePermissionCatalog` shared by `compileContributions` and `compileTokenCatalog`.
## Deviations from Plan
None - plan executed as written.
## Issues Encountered
None
## Postgres verify status
All Docker-host Postgres lines from this plan were **RUN** and passed on this host:
- Task 1: `TestTokenTracerPostgres`, `TestBackendAdminMetadataColumn`, `TestPhase09MigrationsFreshRollback`
- Task 2: `TestTokenTracerPostgres`, `TestAdminAuthLifecycle`, `TestAdminLogoutRevokesExpiredRefreshableToken`
- Task 3: `TestAccountTokensSmoke`, `TestPhase10OpenAPIConformance`
- Task 4: `TestTokenCommandsSmoke`, `TestAdminCreateCommand`
## User Setup Required
None - no external service configuration required.
## Next Phase Readiness
Ready for 16.3-02 (admin SPA API tokens card on My account). Framework half of SC-1/SC-2/SC-3/SC-5 is in place for Journal (16.3-03) and unit tests (16.3-04).
---
*Phase: 16.3-backend-admin-personal-api-tokens-with-scopes*
*Completed: 2026-10-11*