Introducing Gram by Speakeasy. Gram is everything you
need to power integrations for Agents and LLMs. Easily create, curate and host
MCP servers for internal and external use. Build custom tools and remix
toolsets across 1p and 3p APIs. Get on the
waitlist today!
What is MCP authorization?
Imagine giving an AI assistant the keys to your database, customer records, or financial systems. Since the Model Context Protocol (MCP) allows agentic clients to access various parts of your systems as tools and resources, how do you ensure that only the right agents can access the right tools?
This is where authorization comes in.
Authorization determines:
Who can access your MCP server
What specific tools and resources they can use
When their access is valid
How they need to be authenticated
What is the difference between authorization and authentication?
Before diving deeper, let’s clarify an important distinction:
Authentication verifies identity, which is to say it confirms who or what is making the request.
Authorization determines permissions, which is to say it decides what the authenticated entity can access.
Why is authorization important?
Suppose you have a powerful MCP server that can perform various tasks, like accessing sensitive data or executing critical operations. In this case, you need to ensure that only authorized agents can perform these actions.
Without proper authorization, you risk an agent accessing sensitive data it’s not supposed to or, even worse, executing destructive commands .
OAuth 2.1 within MCP
MCP uses a subset of the OAuth 2.1 framework for authorization. OAuth 2.1 is mandatory, and the MCP Specification establishes specific requirements for implementing it in your server.
Mandatory PKCE implementation: All MCP clients must use Proof Key for Code Exchange (PKCE) to prevent authorization code interception attacks.
Metadata discovery support: MCP servers should support RFC8414 for automatic endpoint discovery.
Dynamic client registration: MCP servers should support RFC7591 to enable seamless client onboarding.
Standardized error handling: MCP servers must respond with specific HTTP status codes (401, 403, 400) for different authorization scenarios.
Implementing OAuth in MCP
Here are a few ways you can implement OAuth when building your MCP server:
Self-contained OAuth: Your MCP server acts as both the resource provider and the authorization provider.
Third-party OAuth provider: Your MCP server integrates with established providers like Auth0.
Custom OAuth provider: You use your existing OAuth infrastructure behind your own API infrastructure to provide authorization for your MCP server.
Each approach has its own trade-offs, so you’ll need to choose the one that best fits your needs.
How does MCP authorization work in real-world applications?
Let’s walk through an example to understand how you’d implement authorization in a real-world MCP server.
Scenario: A document management system
Suppose you’ve built a document management MCP server that exposes these tools:
createDocument
readDocument
updateDocument
deleteDocument
shareDocument
You need to make sure different users have appropriate access levels:
When an agent tries to access this system through an MCP client, the following flow occurs:
Initial request: An MCP client tries to call the deleteDocument tool without an access token.
Challenge response: The MCP server responds with a 401 Unauthorized status.
Authentication initiation: The client redirects the agent to an authorization URL.
User consent: The client is authenticated and granted the requested permissions, for example, for an editor role.
Token exchange: After consent, the authorization server issues an access token.
Authorized request: The client includes this token in subsequent requests and can access only the tools allowed by the role.
For example, a client with the editor role can call readDocument, createDocument, and updateDocument, but not deleteDocument.
Permission verification: The MCP server validates not just the token’s authenticity but also the specific permissions it grants.
Here’s how you can implement authorization checks in a real MCP server:
In this example, the deleteDocument tool checks whether the user has the admin role before allowing the deletion of a document. If not, it raises a PermissionError.
Authorization patterns
There are a few authorization patterns you can implement to enhance the security of your MCP server.
1. Role-based access control (RBAC)
Define roles (like viewer, editor, and admin) and assign permissions to these roles. Depending on the context, clients can then be assigned roles rather than individual permissions.
2. Attribute-based access control (ABAC)
Base authorization decisions on attributes (or claims) about the user, resource, action, and environment.
3. Third-party authorization
Instead of building your own authorization system from scratch, integrate your MCP server with existing identity providers like Auth0, Okta, GitHub, or even the authentication layer of your own API. This lets you use the established identity infrastructure and avoid duplicating user management.
In this flow:
The MCP server acts as a bridge between your MCP client and the identity provider.
The identity provider handles user authentication and consent.
The MCP server exchanges tokens with the provider and maintains the mapping.
Your tools can use the provider’s APIs without exposing tokens to clients.
Let’s see how this works with the Sentry MCP server, which uses Sentry’s OAuth service as its identity provider:
Initial connection: Your MCP client connects to a Sentry MCP server.
OAuth initiation: The server responds with a 401 Unauthorized, triggering the OAuth flow.
First OAuth step: The client redirects to the MCP server’s OAuth endpoint.
Server-side OAuth: The MCP server shows its own consent screen first.
Provider authentication: After approving this first step, the server redirects to Sentry’s OAuth service.
Provider consent: You’ll see Sentry’s consent screen showing which permissions the MCP server is requesting.
Double token exchange:
Sentry issues an OAuth token to the MCP server (not to your client).
The MCP server creates its own session token for your client.
The Sentry token stays secure on the server side.
Using tools: When you call a tool like list_organizations, the following flow begins.
The server validates your MCP session token.
It uses its Sentry token to call the Sentry API.
You get the results without ever handling Sentry credentials.
This setup creates a secure proxy pattern - the MCP server mediates interactions between clients and the identity provider. There are actually two OAuth flows happening:
One occurs between your client and the MCP server.
The other occurs between the MCP server and Sentry.
This double-layer approach provides extra security by keeping the provider’s tokens isolated from clients.
For more details on how this works, see the remote-servers page.
Authorization Code Flow with PKCE
For browser-based applications and most MCP clients, the specification recommends the Authorization Code Flow with PKCE (Proof Key for Code Exchange). This is for public clients that cannot keep secrets.
The PKCE extension prevents authorization code interception attacks by requiring the client to generate a secret “code verifier” and its transformed value (the “code challenge”). This ensures that only the original requester can exchange the authorization code for tokens.
Note
Authorization in MCP is tightly integrated with the transport
layer. During the transport initialization handshake, the
MCP server can immediately communicate its authorization requirements to the
client.
Authorization and root boundaries
MCP roots can be used in tandem with authorization to provide an additional layer of access control. While authorization determines which actions a user can perform, roots determine which resources are visible to the client.
For example, you might implement both in a tool like readDocument to make sure that a client can read only the documents within their authorized roots and only if they have the right permissions:
Best practices for secure MCP authorization
Here are a few best practices to keep in mind when implementing authorization in your MCP server:
Apply the principle of least privilege: Grant only the permissions necessary for the intended function.
Implement short-lived tokens: Set reasonable expiration times for access tokens.
Validate tokens properly: Check signature, expiration, issuer, and audience claims.
Provide clear permission errors: Help users understand why access was denied.
Use TLS for all communications: Encrypt all authorization-related traffic.
Implement rate limiting: Protect against brute-force and denial-of-service attacks.