docs(08): create OAuth authorization server plans

This commit is contained in:
Jakub Zych
2026-09-23 13:38:58 +02:00
parent 716d0ea40d
commit 241af16ba7
11 changed files with 1451 additions and 11 deletions

View File

@@ -306,7 +306,7 @@ Plans:
### Phase 8: OAuth2.1 authorization server
**Goal**: An RFC 8414/6749/7591-compliant OAuth2.1 server on zitadel/oidc serves fonoteka-mcp and the ChatGPT connector unchanged, including exact `WWW-Authenticate` and protected-resource-metadata headers. Security-load-bearing — bearer tokens, PKCE and constant-time secret comparison all live here; apply the security-review agent.
**Goal**: A direct standard-library OAuth2.1-style authorization server (`wristband`) implements the RFC 8414/6749/7591/8707 contract needed by fonoteka-mcp and the ChatGPT connector unchanged. The backend preserves its exact Basic invalid-client challenge and existing personal-token 401, while fonoteka-mcp retains ownership of RFC 9728 protected-resource metadata and its rich Bearer challenge. Security-load-bearing — bearer tokens, PKCE, replay-family revocation, and constant-time secret comparison all live here; apply the security-review agent.
**Mode:** mvp
**Depends on**: Phase 6, Phase 7
**Repos:** summercms.go, fonoteka.go
@@ -315,12 +315,38 @@ Plans:
1. RFC 8414 metadata is served unenveloped at its well-known path; authorize with PKCE and a consent screen works, and the token endpoint issues/refreshes authorization_code and refresh_token flows, all as unwrapped RFC 6749 bodies with the PHP cache headers (`Cache-Control: no-store`, `Pragma: no-cache`).
2. RFC 7591 dynamic client registration and RFC 8707 resource parameter tolerance both work against a real client registration call.
3. A 401 on a protected route carries the exact `WWW-Authenticate` and protected-resource-metadata header contract, verified against fonoteka-mcp's actual discovery flow, not just a Go unit test.
3. The token endpoint returns exactly `WWW-Authenticate: Basic realm="OAuth"` on `invalid_client`, the backend personal-token 401 remains unchanged with no added challenge, and fonoteka-mcp's own rich Bearer challenge plus protected-resource metadata are verified through its actual discovery flow, not just a Go unit test.
4. Connected apps can be listed and revoked; `OAuthClient`/`OAuthAuthCode`/`OAuthRefreshToken` models persist correctly; fonoteka-mcp completes its install and auth flow unchanged; client-secret comparison uses `crypto/subtle.ConstantTimeCompare`.
**Plans**: TBD
**Plans**: 6 plans
**Research flag:** yes
Plans:
**Wave 1**
- [ ] 08-01-PLAN.md — Discover and dynamically register clients through the real app and corrected OAuth schema
**Wave 2** *(blocked on 08-01)*
- [ ] 08-02-PLAN.md — Complete S256 authorize, JWT consent, and atomic authorization-code exchange
**Wave 3** *(blocked on 08-02)*
- [ ] 08-03-PLAN.md — Rotate refresh grants, kill replayed lineages, and manage connected apps
**Wave 4** *(blocked on 08-03)*
- [ ] 08-04-PLAN.md — Provision confidential clients and serve the MCP personal-token bootstrap
**Wave 5** *(blocked on 08-04)*
- [ ] 08-05-PLAN.md — Replay PHP OAuth flows and run the unchanged real MCP lifecycle
**Wave 6** *(blocked on 08-05; blocking security checkpoint)*
- [ ] 08-06-PLAN.md — Close 103-method coverage, independent security review, and final phase gate
### Phase 9: Backend admin authentication and schema pipeline
**Goal**: Backend admin users with roles are separate from frontend users and gate navigation and controller access; `fields.yaml`/`columns.yaml` drive a JSON form/list schema, including a first-class relation-manager schema replacing the one `partial` field. Security-load-bearing — separate admin authentication and permissions registry live here; apply the security-review agent. This is also the least-precedented design surface in the research (one real relation-manager usage in the PHP source, no direct library equivalent).