feat(api): add scoped MCP OAuth consent
MCP OAuth connections previously inherited access across the signed-in account's organizations. The consent page now lets the user choose one organization, all or selected websites, and a subset of the client's requested permissions. Read permissions start selected; write permissions require an explicit choice. Connected apps shows the approved access.
The auth configuration delegates codes, consent, tokens, and refresh to Better Auth. A focused grant module validates the selection and binds it to the native consent reference; access tokens carry its hash. Shared MCP and RPC authorization checks enforce that grant alongside scopes and current organization roles, including cached discovery and ID-only actions. Disconnecting an app removes its grants and revokes its refresh tokens; reconnecting creates a fresh grant so old JWTs cannot regain access.
No new database tables, migrations, or dependencies. Existing unscoped OAuth connections must reconnect after deployment. Short-link permissions remain organization-wide and the selector explains this.
Validation:
bun run lintandbun run check-typespassed across the repository.bun run testpassed through the repository pre-push hook (all 31 tasks succeeded).- 89 focused MCP/RPC authorization, native OAuth round-trip, and schema tests passed, including narrowing, refresh, disconnect/reconnect, invalid selections, cross-organization access, and deleted websites.
- Chromium selector regression passed for organization changes, selected websites, requested permissions, and denial.
- Dashboard production build passed.
- Independent native integration and authorization review completed.
Dependencies: none. Other open auth work (#692) concerns Redis session initialization; this slice changes MCP OAuth consent and grant enforcement.
Implementation and review assisted by Codex.
Summary by cubic
Adds scoped consent to MCP OAuth connections so approvals no longer inherit access across all the signed-in account's organizations. Users now pick one organization, all or selected websites, and which requested permissions to approve, with read permissions pre-selected and write permissions requiring an explicit choice.
New Features
- Connected apps shows the approved organization, websites, and permissions per connection.
- Access tokens carry a hash of the consent grant, and MCP and RPC authorization enforce it alongside the token scopes and the current organization role.
- Disconnecting an app removes its grants and revokes its refresh tokens; reconnecting creates a fresh grant so old JWTs cannot regain access.
- Short-link permissions stay organization-wide, and the selector explains that.
Migration
- Existing unscoped OAuth connections must reconnect after deployment.
- No new database tables, migrations, or dependencies.