This guide is written by the team that builds Casdoor and describes the standards as published (listed under Sources), with notes on how Casdoor implements them as of October 20, 2026. Spotted a mistake? Tell us.
AI agents need to call APIs and tools on someone's behalf: read a calendar, open a pull request, query a database through an MCP server. The question "how does the agent get a credential?" has a standard answer now, and it's OAuth. Not one spec, though: a stack of them, each closing a specific gap.
This guide walks through that stack in the order an agent meets it.
The problem with API keys
The easy way to give an agent access is to paste an API key into its configuration. That key:
- usually has all of the user's permissions, or more,
- doesn't expire,
- works from anywhere if it leaks (agents put a lot of text into logs and prompts), and
- can't tell you which agent, acting for which user, made a call.
OAuth fixes each of these: short-lived tokens, scoped to what the user approved, issued per client, and revocable.
1. OAuth 2.1 with PKCE: the base
OAuth 2.1 consolidates OAuth 2.0 and a decade of security advice into one spec. For agents, the parts that matter:
- Authorization code flow with PKCE is required for every client. The agent opens a browser, the user signs in and approves scopes, and the agent exchanges the code for tokens. PKCE ties the code to the client that started the flow, so an intercepted code is useless.
- No implicit flow and no password grant. The agent never sees the user's password.
- Exact redirect URI matching and refresh token rotation for public clients.
The MCP authorization spec builds directly on OAuth 2.1: an MCP server is an OAuth resource server, and an identity provider acts as the authorization server.
2. Discovery: finding the authorization server
An agent connecting to a new MCP server knows only its URL. Two metadata documents get it the rest of the way:
- Protected Resource Metadata (RFC 9728): the MCP server answers an unauthenticated request with
401and a pointer to/.well-known/oauth-protected-resource, which names its authorization server. - Authorization Server Metadata (RFC 8414):
/.well-known/oauth-authorization-serveron the IdP lists the authorization and token endpoints, supported grants and PKCE methods.
3. Client registration without a human
In classic OAuth, a developer registers each app in a console and copies a client ID. That doesn't work when any user can point any AI client at any MCP server. Two options:
- Dynamic Client Registration (RFC 7591): the client POSTs its metadata to a registration endpoint and gets a client ID back. Widely supported, but it creates a new client record for every installation.
- Client ID Metadata Documents (CIMD): the client ID is an HTTPS URL where the client publishes its metadata (name, logo, redirect URIs). The authorization server fetches it when it first sees the client. This is what the current MCP spec prefers, because it needs no registration step and the client's identity is tied to a domain.
4. Resource indicators: one token, one server
Without care, a token issued for MCP server A could be replayed against MCP server B by whoever holds it, including a malicious server. Resource indicators (RFC 8707) let the client name the server it wants a token for (resource=https://mcp.example.com), and the authorization server puts that in the token's audience. Server B rejects a token meant for A.
5. DPoP: tokens that only work for their owner
A normal access token is a bearer token: anyone holding it can use it. Agents copy context around a lot, so tokens leak into logs, traces and prompts. DPoP (RFC 9449) binds the token to a key pair the client generates:
- The client sends a signed DPoP proof (a small JWT with the HTTP method, URL and a timestamp) with the token request, and the authorization server binds the token to that key.
- Every API call carries a fresh proof. A leaked token without the private key is useless.
6. Token exchange: agents acting for users, and for other agents
When an agent calls a downstream service, it shouldn't forward the user's token as-is. Token exchange (RFC 8693) lets it trade the token it has for a new one: narrower scope, a different audience, and an act claim recording who is acting for whom. That gives you a clean audit trail through chains of agents.
7. The device flow: agents without a browser
A CLI agent on a server, or a coding agent in a terminal, may have no browser to redirect. The device authorization grant (RFC 8628) shows the user a short code and a URL; the user approves on their phone or laptop, and the agent polls for the token.
Machine-only agents
Agents that act for an organization rather than a user (a nightly batch job, a monitoring bot) use the client credentials grant, ideally with a signed JWT for client authentication instead of a shared secret. Give each agent its own client so its calls are attributable and revocable.
Putting it together
| Concern | Standard |
|---|---|
| User login and consent | OAuth 2.1 authorization code + PKCE |
| Finding the authorization server | RFC 9728, RFC 8414 |
| Registering the client | CIMD, or Dynamic Client Registration (RFC 7591) |
| Limiting a token to one server | Resource indicators (RFC 8707) |
| Making stolen tokens useless | DPoP (RFC 9449) |
| Delegation through agent chains | Token exchange (RFC 8693) |
| Agents without a browser | Device authorization grant (RFC 8628) |
| Agents with no user | Client credentials |
Doing this with Casdoor
Casdoor is an open-source identity provider that implements this stack: OAuth 2.1-style authorization code with PKCE, authorization server and protected resource metadata, Dynamic Client Registration, client ID metadata documents (added in October 2026), resource indicators, DPoP-bound tokens, token exchange, the device flow and client credentials. On top of the specs, it keeps a registry of your MCP servers and their tools, lets users approve individual tools rather than whole servers, and logs agent sign-ins next to people's.
Read more on the AI agents page, compare providers in Top 5 OAuth authorization servers for MCP, or try it on Casdoor Cloud from $24/month billed yearly.
FAQ
Do I need all of this to ship an MCP server? The minimum for the MCP spec is OAuth 2.1 with PKCE, the two metadata documents and a way to register clients (CIMD or DCR). Resource indicators are strongly recommended. DPoP and token exchange matter once agents handle sensitive data or call each other.
Is OAuth 2.1 final? It's still an IETF draft, but it doesn't add new mechanisms; it removes insecure options from OAuth 2.0 and makes PKCE mandatory. Implementations that follow it work with OAuth 2.0 clients that use the code flow with PKCE.
What is AuthZEN? A separate OpenID Foundation effort that standardizes how an application asks a policy engine "may this subject do this action on this resource?". It's about authorization decisions inside your services, and complements, rather than replaces, OAuth tokens.
Sources
- MCP specification: authorization
- OAuth 2.1 (draft)
- OAuth client ID metadata document (draft)
- RFC 7591: Dynamic Client Registration
- RFC 8414: Authorization Server Metadata
- RFC 9728: Protected Resource Metadata
- RFC 8707: Resource Indicators
- RFC 9449: DPoP
- RFC 8693: Token Exchange
- RFC 8628: Device Authorization Grant
- Casdoor docs: MCP authorization
Product names are trademarks of their respective owners.