Skip to content

Prototype room-scoped Mindmap OAuth with PKCE - #594

Draft
nhyiramante1 wants to merge 1 commit into
mainfrom
agent/oauth-rooms-pkce-poc
Draft

Prototype room-scoped Mindmap OAuth with PKCE#594
nhyiramante1 wants to merge 1 commit into
mainfrom
agent/oauth-rooms-pkce-poc

Conversation

@nhyiramante1

Copy link
Copy Markdown
Contributor

What

This is a working vertical-slice proof of concept for replacing Mindmap's
launcher grant with a durable room plus Better Auth's OAuth Provider
Authorization Code/PKCE flow.

  • Adds @better-auth/oauth-provider 1.6.22 and the Better Auth JWT plugin.
  • Adds durable owner-scoped document rooms and a short-lived OAuth room-selection
    table.
  • Uses the provider's postLogin + consentReferenceId hooks so the chosen room
    follows consent, authorization code, and access token.
  • Issues one-hour access tokens with openai:chat / doc:read scopes and a
    signed room_id claim.
  • Verifies signature, issuer, audience, scope, subject, ownership, and exact room
    binding at the protected resource.
  • Changes the taskpane Mindmap launch to create a room and open Mindmap with a
    non-secret room hint.
  • Changes Mindmap to register as a public OAuth client, generate/store its own
    PKCE verifier, exchange the code, and load the authorized room.
  • Keeps the existing /api/handoff flow in place for comparison and other tools.

The detailed mental model and sequence are in
docs/oauth-rooms-pkce-poc.md.

Security shape

PKCE protects the authorization code because the verifier is generated and
retained by Mindmap; it is never passed by the launcher. The room id is an
identifier, not a credential. The backend makes the room selection authoritative
and refuses a valid token against a different room.

This does not claim that browser JavaScript can identify itself
cryptographically, nor that PKCE makes a stolen bearer access token unusable.
Origin checks can remain defense-in-depth for the old flow but are not treated as
client authentication here.

Relationship to #579 and #593

  • This flow does not accept a launcher-controlled wt_api; Mindmap uses its
    deploy-time backend URL, addressing the attacker-selected proxy concern on Include backend API URL in tool launches #579
    for this path.
  • The PKCE verifier is not placed beside the grant in a fragment.
  • Deploy the mindmap to GitHub Pages #593 remains useful for the Pages deployment and production
    VITE_BACKEND_URL; its skipped wt_api smoke should become an OAuth
    launch/config smoke after integration.
  • This branch is based directly on current main (ea6138d6) in a separate
    clean worktree. It does not include or disturb the dirty/ahead local Mindmap
    worktrees.

Deliberate PoC limits

  • One owner and one snapshot per room; no room membership table, multi-document
    rooms, live sync, or update endpoint yet.
  • Public dynamic client registration is enabled so the branch is runnable without
    provisioning. Production should pre-provision the known Mindmap client (or
    tightly constrain registration) and disable open registration.
  • No refresh tokens; access expires after one hour.
  • No DPoP or other sender-constrained access tokens.
  • The browser login/consent sequence was endpoint-smoked in process, but a full
    Google interactive Playwright run is still needed in a configured deployment.

Validation

  • Backend build: passed
  • Backend tests: 113/113 passed
  • Frontend build: passed
  • Frontend tests: 222/222 passed
  • Mindmap build: passed
  • Mindmap tests: 366/366 passed
  • Better Auth application + OAuth schema migration: passed on a fresh database
  • OAuth smoke: public client registration returns a public client; a PKCE
    authorize request redirects to the configured login page with provider-signed
    state

Total: 701 tests passed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant