MCP Authorization — OAuth 2.0 + Tier-Based API Gating
As of 2026-10-05
What is MCP Authorization?
MCP's authorization model, first formalized in the 2025-06-18 spec and refined through 2026-07-28, requires OAuth 2.1 whenever a server chooses to support authorization over HTTP transport (authorization itself remains protocol-optional) — but identity alone doesn't gate access — commercial servers need a tier-gating layer that returns -32601, never -32603, to avoid leaking which paid tools exist.
What it is
The MCP specification revision of June 2025 first shipped a formal authorization model for the Streamable HTTP transport; the mechanics below have since been carried forward and refined, most recently in the 2026-07-28 revision (see the AI angle section). The stdio transport runs in-process and trusts the operating-system process boundary, so it needs no external authentication layer at all. The HTTP model is built on OAuth 2.1, the consolidated and security-hardened profile of OAuth 2.0, with PKCE mandatory for every client and resource indicators per RFC 8707 binding a token to one server. Client registration itself has since moved on: as of the 2026-07-28 revision, OAuth Client ID Metadata Documents (an HTTPS URL used directly as the client_id) are the preferred mechanism, and RFC 7591 dynamic client registration is retained only as a deprecated fallback for authorization servers that do not yet support metadata documents. A server exposes a discovery document at a well-known path that points clients at its authorization server; clients run the authorization-code flow with PKCE and present a bearer token on every JSON-RPC request. Resource indicators bind a token to one specific MCP server, which is what stops a token issued for one service being replayed against another.
Why it matters
- stdio needs no auth (OS boundary), but any network-exposed MCP server must run OAuth 2.1 with PKCE, dynamic client registration (RFC 7591) and resource indicators (RFC 8707) to bind tokens to one server.
- Tier gating translates identity into a tool subset: a free Discover tier sees find_firms public fields only, Buyer adds full profiles, Practice adds search_news, Recruiter adds opportunity tools.
- Returning -32603 instead of -32601 for an out-of-tier tool call leaks the existence of premium tools to an unauthenticated caller.
Key points
- OAuth 2.1 + PKCE for HTTP transport (stdio is in-process, OS-trusted); spec rev 2025-06-18 mandates PKCE for public clients.
- Discovery — /.well-known/oauth-protected-resource points clients at authorization server; dynamic client reg via RFC 7591.
- Bearer token in Authorization header on every JSON-RPC request; resource indicators (RFC 8707) bind tokens to a specific MCP server.
- Tier-gating layer — translate token identity into tool subset; non-entitled calls return -32601 method not found, not -32603 (leakage risk).
- Stripe Meters + rate-limit Worker — usage billing layered on top of OAuth (the platform charter Year-2 model; §20.5 Cloudflare substrate).
- Authorization is protocol-optional (spec 2026-07-28) — a server MAY run unauthenticated over HTTP; when it does support authorization it MUST follow the spec. stdio servers SHOULD NOT layer OAuth on at all.
- RFC 7591 dynamic client registration is now deprecated (spec 2026-07-28) — OAuth Client ID Metadata Documents (an HTTPS URL as client_id) are the preferred registration path; DCR is a backward-compatibility fallback only.
- Mix-up attack protection — clients must validate the `iss` value in the authorization response against the recorded issuer (RFC 9207), a requirement added since the 2025-06-18 revision.
Terms used on this page
- OAuth 2.1 with PKCE
- The consolidated OAuth profile MCP HTTP transport adopts; PKCE (Proof Key for Code Exchange) is mandatory for public clients and replaces the implicit and password grants, eliminating two long-standing classes of token-theft vulnerability.
- Resource indicator (RFC 8707)
- An OAuth extension that binds an access token to a specific protected resource (the MCP server URL); a token issued for server A cannot be replayed against server B even if both share an authorization server.
- Tier-gating layer
- The server-side check, layered above OAuth, that maps an authenticated identity to the subset of tools that the user's paid tier is entitled to call; non-entitled calls return -32601 (method not found), never -32603 (which would leak the existence of paid tools).
- Dynamic client registration (RFC 7591)
- The OAuth extension that lets an MCP client register itself with the authorization server programmatically at first contact. As of the MCP spec revision 2026-07-28 this is explicitly deprecated and retained only for authorization servers that do not yet support OAuth Client ID Metadata Documents.
- OAuth Client ID Metadata Document
- The registration mechanism preferred since MCP spec 2026-07-28: the client's client_id is itself an HTTPS URL; the authorization server fetches a JSON metadata document from that URL to learn the client's redirect URIs and properties, removing the need for a separate registration round-trip (RFC 7591) or manual pre-registration.
- OAuth 2.0 Protected Resource Metadata (RFC 9728)
- The discovery mechanism an MCP server MUST implement (spec 2026-07-28): a well-known document that tells a client which authorization server(s) protect it and which scopes it supports, so the client can locate the authorization server before requesting a token.
- Issuer validation (RFC 9207)
- A mix-up-attack defense added to MCP's authorization flow: the client records the authorization server's issuer identifier before redirecting the user, then validates the `iss` value returned in the authorization response against that recorded value before ever sending the authorization code to a token endpoint.
- Step-up authorization / insufficient_scope
- The formalized runtime flow (spec 2026-07-28) for when a token's scopes are too narrow for an operation: the server returns HTTP 403 with `error="insufficient_scope"` and the required scopes; the client re-authorizes with the union of previously granted and newly required scopes rather than losing prior permissions.
Sources
- MCP specification — Authorization
- IETF OAuth 2.1 draft
- RFC 7591 OAuth Dynamic Client Registration
- Model Context Protocol — Authorization specification, revision 2026-07-28
- Model Context Protocol — Client Registration (spec 2026-07-28)
- Model Context Protocol — Authorization Security Considerations (spec 2026-07-28)
- Model Context Protocol — Authorization Server Discovery (spec 2026-07-28)
- Model Context Protocol — Specification changelog, 2026-07-28
- IETF — OAuth 2.0 Protected Resource Metadata, RFC 9728
- IETF — OAuth 2.0 Authorization Server Issuer Identification, RFC 9207
- IETF — OAuth 2.0 Authorization Server Metadata, RFC 8414
- RFC 8707 — Resource Indicators for OAuth 2.0 (binds a token to one MCP server)
- RFC 7636 — Proof Key for Code Exchange (PKCE) by OAuth Public Clients (why PKCE is required for all clients)
- RFC 6750 — OAuth 2.0 Bearer Token Usage (WWW-Authenticate challenge and 403 insufficient_scope used for step-up)
- IETF OAuth WG — OAuth Client ID Metadata Document draft (HTTPS URL as client_id; MCP's preferred registration mechanism)
- MCP specification 2026-07-28 — Security Best Practices (confused-deputy, token passthrough, session risks)
- Cloudflare Agents docs — MCP authorization (vendor documentation, OAuth for remote MCP servers)
Full card available to members. What the full card adds: the full decision framework · the SAP vs Snowflake / Databricks / Fabric comparison · the common pitfalls and their fix · the cheat sheet · the architecture schemas · the code blocks · the facts worth quoting.