MCP Authorization Server: Complete OAuth Guide
An MCP Authorization Server controls how MCP clients obtain permission to access protected MCP servers.
It may:
- authenticate a human user
- authenticate a confidential client
- collect user consent
- register previously unknown MCP clients
- validate PKCE challenges
- issue authorization codes
- issue and refresh Access Tokens
- bind tokens to a specific MCP Resource Server
- publish OAuth discovery metadata
- expose token revocation or introspection endpoints
- enforce organizational access policies
The Authorization Server does not normally execute MCP tools.
That is the responsibility of the MCP server acting as a protected OAuth Resource Server.
User
│
▼
MCP Client
│
├──── Authorization Request ────► Authorization Server
│ │
│ ├── Authenticate User
│ ├── Evaluate Consent
│ └── Issue Token
│
└──── Bearer Access Token ──────► MCP Resource Server
│
├── Validate Token
├── Validate Audience
├── Validate Scopes
└── Execute MCP Tool
Quick Answer
An MCP Authorization Server is the OAuth service responsible for authenticating users or clients and issuing Access Tokens for a protected MCP server. The MCP client discovers it through Protected Resource Metadata, retrieves its authorization metadata, performs a secure OAuth flow with PKCE, requests a token for the MCP server using the
resourceparameter, and presents that token to the MCP server on every protected HTTP request.
The Three Core OAuth Roles in MCP
A secure MCP authorization architecture separates three primary roles.
MCP Client
The MCP client wants to call protected MCP tools, resources, or prompts.
It is an OAuth client.
Its responsibilities include:
- discovering the Authorization Server
- registering or identifying itself
- initiating authorization
- generating PKCE values
- handling the redirect
- exchanging the authorization code
- storing tokens securely
- refreshing tokens
- attaching the Access Token to MCP requests
Authorization Server
The Authorization Server grants authorization and issues tokens.
Its responsibilities include:
- authenticating the resource owner
- validating the OAuth client
- displaying or evaluating consent
- enforcing requested scopes
- verifying PKCE
- issuing authorization codes
- issuing Access Tokens
- issuing and rotating Refresh Tokens
- publishing metadata
- maintaining token lifecycle
MCP Resource Server
The MCP server protects tools and resources.
Its responsibilities include:
- advertising Protected Resource Metadata
- returning an appropriate
WWW-Authenticatechallenge - accepting Bearer Access Tokens
- validating the token
- validating issuer and audience
- checking scopes and permissions
- rejecting invalid or insufficient tokens
- executing only authorized operations
OAuth Client:
MCP application
Authorization Server:
OAuth / identity service
Resource Server:
Protected MCP endpoint
The current MCP authorization architecture explicitly classifies MCP servers as OAuth Resource Servers. The Authorization Server may be colocated with the MCP server or hosted separately.
MCP Authorization Server vs MCP Server
The two systems should not be confused.
| Responsibility | Authorization Server | MCP Server |
|---|---|---|
| Authenticates the user | Yes | Usually no |
| Presents consent | Yes | No |
| Issues Access Tokens | Yes | No |
| Issues authorization codes | Yes | No |
| Publishes Authorization Server Metadata | Yes | No |
| Publishes Protected Resource Metadata | No | Yes |
| Executes MCP tools | No | Yes |
| Validates Access Tokens | May support introspection | Yes |
| Enforces tool-level authorization | Provides claims and scopes | Yes |
| Stores MCP business data | Usually no | Possibly |
An MCP implementation may deploy both roles inside one product or domain, but the protocol responsibilities remain distinct.
Same Organization
│
├── auth.example.com
│ Authorization Server
│
└── mcp.example.com
MCP Resource Server
A colocated deployment might use:
https://example.com/oauth/*
https://example.com/mcp
Colocation does not permit the server to skip OAuth role separation, metadata requirements, audience binding, or independent token validation.
Want to analyze your API security?
Import your OpenAPI spec and generate a Security Report automatically.
When Does an MCP Server Need Authorization?
Authorization should be used when the MCP server exposes data or operations that must not be available to every caller.
Examples include:
- private documents
- customer records
- source repositories
- cloud resources
- email accounts
- issue trackers
- internal databases
- financial operations
- administrative tools
- user-specific SaaS data
An MCP server serving only public, non-sensitive information may not require OAuth.
However, authentication alone is not enough when different users should receive different permissions.
Authenticated User
│
▼
Authorization Policy
│
├── May read project A
├── May not read project B
└── May not delete resources
Authorization determines not merely whether the caller has logged in, but what the caller may access and perform.
High-Level MCP Authorization Flow
A typical flow begins when the MCP client contacts a protected MCP server without a token.
1. MCP Client → MCP Server
Request without token
2. MCP Server → MCP Client
HTTP 401 + WWW-Authenticate
3. MCP Client → Protected Resource Metadata
Discover Authorization Server
4. MCP Client → Authorization Server Metadata
Discover OAuth endpoints
5. MCP Client → Authorization Endpoint
User authenticates and approves
6. Authorization Server → MCP Client
Authorization code
7. MCP Client → Token Endpoint
Code + PKCE verifier + resource
8. Authorization Server → MCP Client
Access Token
9. MCP Client → MCP Server
Authorization: Bearer <token>
10. MCP Server
Validates token and executes request
The current specification requires MCP servers to implement OAuth Protected Resource Metadata and MCP clients to use it to discover the appropriate Authorization Server.
Step 1: The MCP Server Returns HTTP 401
When the client requests a protected MCP endpoint without valid authorization, the MCP server should return:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource"
The resource_metadata value points to the MCP server's Protected Resource Metadata document.
The MCP specification requires clients to understand this challenge and use it to continue discovery.
This is different from redirecting the client immediately to a login page.
The Resource Server first tells the MCP client where authoritative metadata for the protected resource can be found.
Protected Resource Metadata
Protected Resource Metadata describes the MCP Resource Server and identifies the Authorization Servers that may issue tokens for it.
A simplified document may look like:
{
"resource": "https://mcp.example.com",
"authorization_servers": [
"https://auth.example.com"
],
"scopes_supported": [
"documents:read",
"documents:write"
],
"bearer_methods_supported": [
"header"
]
}
Important fields may include:
resourceauthorization_serversscopes_supported- supported Bearer Token methods
- resource documentation
- resource signing information
- additional authorization capabilities
The resource identifier represents the protected MCP service.
The client should not automatically trust an arbitrary Authorization Server merely because an untrusted endpoint returned its URL. Discovery must follow the security rules in OAuth Protected Resource Metadata, including careful selection and validation of advertised Authorization Servers.
Why Protected Resource Metadata Matters
Without Protected Resource Metadata, an MCP client might have to:
- guess the Authorization Server
- ask users to enter OAuth endpoints manually
- assume the MCP server hosts OAuth itself
- use unsafe fallback conventions
- trust an arbitrary login URL
Protected Resource Metadata creates an explicit relationship:
MCP Resource:
https://mcp.example.com
Authorized Issuer:
https://auth.example.com
This allows the MCP client to discover the correct OAuth infrastructure while keeping the MCP Resource Server and Authorization Server as separate systems.
It also supports architectures where one identity platform protects many MCP services.
One Authorization Server, Multiple MCP Servers
A single Authorization Server may issue tokens for several MCP Resource Servers.
Authorization Server
auth.example.com
/ | \
/ | \
▼ ▼ ▼
Finance MCP Docs MCP GitHub MCP
The Authorization Server may know about resources such as:
{
"protected_resources": [
"https://finance-mcp.example.com",
"https://docs-mcp.example.com",
"https://github-mcp.example.com"
]
}
RFC 9728 defines an optional protected_resources Authorization Server metadata field that can enumerate resources associated with the Authorization Server. Where both sides publish allowlists, clients can cross-check the relationship for consistency.
The Access Token must still be issued for a specific intended resource.
A token for the documentation MCP server must not automatically work at the finance MCP server.
Authorization Server Metadata
After identifying the Authorization Server, the MCP client retrieves its metadata.
OAuth Authorization Server Metadata is normally available through a well-known HTTPS endpoint.
For an issuer such as:
https://auth.example.com
the metadata may be retrieved from a location such as:
https://auth.example.com/.well-known/oauth-authorization-server
A simplified metadata response may look like:
{
"issuer": "https://auth.example.com",
"authorization_endpoint": "https://auth.example.com/authorize",
"token_endpoint": "https://auth.example.com/token",
"jwks_uri": "https://auth.example.com/.well-known/jwks.json",
"registration_endpoint": "https://auth.example.com/register",
"scopes_supported": [
"documents:read",
"documents:write"
],
"response_types_supported": [
"code"
],
"grant_types_supported": [
"authorization_code",
"refresh_token"
],
"code_challenge_methods_supported": [
"S256"
]
}
RFC 8414 defines this standardized metadata document so OAuth clients can discover endpoint locations and server capabilities.
Important Authorization Server Metadata Fields
issuer
The canonical identifier of the Authorization Server.
{
"issuer": "https://auth.example.com"
}
Clients and Resource Servers should validate the expected issuer exactly.
Issuer confusion can result in tokens from one security domain being trusted in another.
authorization_endpoint
The endpoint where the client directs the user's browser to begin authorization.
{
"authorization_endpoint": "https://auth.example.com/authorize"
}
token_endpoint
The endpoint used to exchange:
- authorization codes
- Refresh Tokens
- supported machine credentials
for tokens.
{
"token_endpoint": "https://auth.example.com/token"
}
jwks_uri
The HTTPS location of the Authorization Server's public JSON Web Key Set.
{
"jwks_uri": "https://auth.example.com/.well-known/jwks.json"
}
An MCP Resource Server may use these public keys to verify JWT signatures.
RFC 8414 requires jwks_uri, when used, to be an HTTPS URL.
registration_endpoint
The endpoint used for OAuth Dynamic Client Registration when supported.
{
"registration_endpoint": "https://auth.example.com/register"
}
scopes_supported
A list of OAuth scopes the Authorization Server advertises.
{
"scopes_supported": [
"documents:read",
"documents:write",
"documents:delete"
]
}
The Authorization Server may support scopes that are not advertised, so clients should not treat this field as an exhaustive security policy unless the deployment explicitly defines it that way. RFC 8414 defines it as recommended metadata.
code_challenge_methods_supported
Indicates supported PKCE methods.
For secure MCP authorization, the expected method is:
{
"code_challenge_methods_supported": [
"S256"
]
}
OpenID Connect Discovery
Newer MCP authorization specifications can also support OpenID Connect Discovery as a mechanism for retrieving Authorization Server information.
The MCP changelog for the November 2025 revision identifies expanded discovery support through OpenID Connect Discovery.
This is useful when an existing identity platform already publishes:
/.well-known/openid-configuration
An MCP client must still distinguish between:
- user authentication
- OAuth authorization
- Access Tokens intended for the MCP resource
- identity claims intended for the client
An ID Token is not a substitute for an MCP Access Token.
Discovery Validation
Metadata discovery is security-sensitive because it determines where the client sends users, authorization codes, and possibly client credentials.
A malicious MCP server may try to advertise an attacker-controlled Authorization Server.
Malicious MCP Server
│
▼
Protected Resource Metadata
authorization_servers:
https://fake-login.example
│
▼
MCP Client Redirects User
│
▼
Credential Phishing
Required Defensive Principles
- require HTTPS for remote Authorization Server endpoints
- validate the issuer
- reject unexpected schemes
- compare metadata relationships
- protect metadata retrieval against SSRF
- revalidate redirect destinations
- avoid trusting manually entered endpoints without warning
- cache metadata carefully
- detect unexpected issuer changes
- allow enterprise administrators to restrict approved issuers
The official MCP security guidance treats OAuth discovery as an SSRF and phishing-sensitive process because discovered URLs may cause backend connections or browser redirects.
HTTPS Requirements
Authorization Server endpoints must use HTTPS.
The MCP authorization specification requires all Authorization Server endpoints to be served over HTTPS. Redirect URIs must use HTTPS except for permitted localhost callbacks used by local clients.
Allowed:
https://client.example.com/oauth/callback
Local development:
http://127.0.0.1:43123/callback
Unsafe remote callback:
http://client.example.com/callback
HTTPS protects:
- credentials
- authorization codes
- tokens
- consent data
- metadata
- client authentication
- session cookies
TLS does not prove that the endpoint is the correct Authorization Server, so issuer and endpoint validation remain necessary.
Authorization Code Flow
The Authorization Code flow is the primary OAuth flow when an MCP client acts on behalf of a human user.
MCP Client
│
▼
Authorization Endpoint
│
▼
User Authentication
│
▼
User Consent
│
▼
Authorization Code
│
▼
Token Endpoint
│
▼
Access Token
The browser receives only a short-lived authorization code.
The Access Token is returned through a direct request from the MCP client to the token endpoint.
Authorization Request
A simplified MCP authorization request may look like:
GET /authorize?
response_type=code&
client_id=https%3A%2F%2Fclient.example.com%2Foauth-client.json&
redirect_uri=https%3A%2F%2Fclient.example.com%2Fcallback&
scope=documents%3Aread&
state=7f3a...&
code_challenge=Y2hh...&
code_challenge_method=S256&
resource=https%3A%2F%2Fmcp.example.com
Host: auth.example.com
Important parameters include:
response_typeclient_idredirect_uriscopestatecode_challengecode_challenge_methodresource
Each serves a different security or interoperability purpose.
The Resource Parameter
The resource parameter identifies the MCP Resource Server for which the client wants a token.
resource=https://mcp.example.com
The MCP client must include the resource parameter in authorization and token requests.
The Authorization Server should use it to issue a token whose audience is the intended MCP server.
Authorization Request
resource = docs-mcp
Authorization Server
│
▼
Access Token
aud = docs-mcp
The MCP Resource Server then validates:
Does token audience equal me?
The current MCP authorization specification requires clients to send the resource parameter and requires MCP servers to validate that tokens were specifically issued for their use.
Why Resource Binding Is Critical
Without resource binding, a malicious or compromised MCP server might obtain a token intended for another service.
User Authorizes:
Low-Risk MCP Server
│
▼
Broad Access Token
│
▼
Token Reused at High-Value API
With resource-bound tokens:
Token A:
aud = low-risk-mcp
High-Value MCP:
Expected aud = high-value-mcp
Result:
Reject
Resource Indicators reduce token substitution and cross-service token abuse.
Scopes alone cannot provide this protection because two different Resource Servers may use similar scope names.
PKCE
PKCE protects the authorization code from being redeemed by an attacker who intercepts it.
The client creates:
- a random
code_verifier - a derived
code_challenge
code_verifier
│
SHA-256 + Encoding
│
▼
code_challenge
The authorization request contains the challenge:
code_challenge=...
code_challenge_method=S256
The token request contains the original verifier:
code_verifier=...
The Authorization Server recomputes the challenge and compares it with the original value.
Stored Challenge
│
▼
Compare
▲
Hash Received Verifier
If they do not match, the token request must fail.
The MCP specification requires MCP clients to implement PKCE, and current draft guidance requires clients to confirm that the Authorization Server supports it before continuing.
Why MCP Clients Are Often Public Clients
Desktop applications, command-line tools, editor extensions, and locally installed AI applications cannot reliably protect a shared Client Secret.
An attacker may extract a secret from:
- application binaries
- package contents
- source maps
- local configuration
- memory
- distributed scripts
Therefore, many MCP clients should be treated as public OAuth clients.
Public Client:
Cannot safely keep a permanent shared secret
Primary code protection:
PKCE
A value embedded in every copy of a desktop application is not meaningfully confidential.
The Authorization Server should not treat possession of such a value as proof that the client is trusted.
The State Parameter
The client should generate a high-entropy state value before redirecting the user.
state=random-unpredictable-value
After authorization, the client verifies that the returned value matches the original request.
This helps protect the client's redirect flow against:
- login CSRF
- authorization response injection
- request confusion
- binding the wrong browser response to the wrong local session
PKCE and state protect different parts of the flow and should not be treated as substitutes.
Redirect URI Validation
The Authorization Server must validate redirect URIs strictly.
A vulnerable server might allow:
Registered:
https://client.example.com/callback
Requested:
https://attacker.example/callback
or weak prefix matching:
Registered:
https://client.example.com/callback
Accepted incorrectly:
https://client.example.com/callback.attacker.example
Secure Validation
- use exact matching
- allow only preregistered redirect URIs
- do not permit arbitrary wildcards
- reject unapproved schemes
- prevent open redirects
- distinguish
localhostfrom attacker-controlled hostnames - validate ports according to the client model
- do not trust redirect URIs supplied only during authorization
A stolen authorization code may still be protected by PKCE, but redirect validation remains necessary to prevent phishing, response leakage, and flow manipulation.
Loopback Redirect URIs
Local MCP clients may use a temporary HTTP listener on the loopback interface.
Example:
http://127.0.0.1:43123/callback
The browser redirects to the locally running client after authorization.
A secure local client should:
- bind only to loopback
- use an unpredictable callback state
- validate PKCE
- accept only one authorization response
- close the listener after completion
- avoid binding to
0.0.0.0 - display a clear completion page
- reject unexpected callback paths
The MCP authorization requirements allow localhost redirect URIs as an exception to the normal HTTPS rule.
Authorization Code Issuance
After authentication and consent, the Authorization Server issues a short-lived, single-use code.
The code should be bound to:
- client identity
- redirect URI
- user authorization
- approved scopes
- intended resource
- PKCE challenge
- creation time
Authorization Code
│
├── Client A
├── Redirect URI A
├── Resource A
├── Scope Set A
├── PKCE Challenge A
└── Short Expiration
The Authorization Server must reject attempts to redeem the code when any required binding does not match.
Token Request
The MCP client exchanges the authorization code at the token endpoint.
POST /token HTTP/1.1
Host: auth.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&
code=SplxlOBeZQQYbYS6WxSbIA&
redirect_uri=https%3A%2F%2Fclient.example.com%2Fcallback&
client_id=https%3A%2F%2Fclient.example.com%2Foauth-client.json&
code_verifier=dBjftJeZ4CVP...&
resource=https%3A%2F%2Fmcp.example.com
The Authorization Server verifies:
- the code exists
- the code has not expired
- the code has not been used
- the client matches
- the redirect URI matches
- the PKCE verifier matches
- the requested resource matches
- the authorization remains valid
Only then should it issue tokens.
Access Token Response
A simplified token response may look like:
{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 900,
"refresh_token": "def50200...",
"scope": "documents:read"
}
Important fields include:
access_tokentoken_typeexpires_inrefresh_tokenscope
The response should be protected from caching and must be sent over HTTPS.
The token should grant only the access approved for the intended MCP Resource Server.
Bearer Token Use
The MCP client sends the Access Token in the HTTP Authorization header:
POST /mcp HTTP/1.1
Host: mcp.example.com
Authorization: Bearer eyJhbGciOiJSUzI1NiIs...
Content-Type: application/json
The current MCP authorization specification requires authorization to be included on every protected HTTP request, even when several requests belong to the same logical MCP session. Tokens must not be placed in URI query strings.
Unsafe:
https://mcp.example.com/mcp?access_token=secret
Query strings may leak through:
- browser history
- logs
- analytics
- referrer headers
- monitoring tools
- proxy records
Access Token Formats
MCP does not require one specific token representation.
An Authorization Server may issue:
Self-Contained JWT Access Tokens
The MCP server validates the token locally using public keys.
JWT
│
├── Header
├── Claims
└── Signature
Typical claims may include:
isssubaudexpiatscope- tenant or organization claims
Opaque Access Tokens
The token contains no client-readable authorization information.
The MCP server may validate it through:
- token introspection
- a shared authorization data store
- a gateway
- another secure backend channel
Opaque Token
│
▼
Introspection or Auth Service
│
▼
Active + Claims
The security requirement is reliable validation, not a particular token format.
JWT Validation by the MCP Server
When the Access Token is a JWT, the MCP Resource Server should validate at least:
- signature
- allowed signing algorithm
- issuer
- audience
- expiration
- not-before time where used
- required scopes
- authorization claims
- key status
JWT Received
│
├── Signature valid?
├── Issuer trusted?
├── Audience equals this MCP server?
├── Token unexpired?
├── Required scope present?
└── User permitted?
The server must not merely decode the JWT and trust its claims.
Decoding is not signature verification.
JWKS and Signing-Key Rotation
The Authorization Server may publish public signing keys through its jwks_uri.
{
"keys": [
{
"kty": "RSA",
"kid": "2026-07-key-1",
"use": "sig",
"alg": "RS256",
"n": "...",
"e": "AQAB"
}
]
}
The MCP Resource Server may select the correct key using the token's kid.
Safe Key Rotation
A typical rotation sequence is:
1. Publish new public key
2. Begin signing new tokens with it
3. Keep old key available
4. Wait for old tokens to expire
5. Remove old key
Removing the old key immediately can invalidate legitimate tokens still within their lifetime.
Keeping compromised keys active for too long allows forged tokens to remain usable.
Opaque Token Introspection
An MCP Resource Server using opaque tokens may call an introspection endpoint.
POST /introspect HTTP/1.1
Host: auth.example.com
Authorization: Basic <resource-server-credentials>
Content-Type: application/x-www-form-urlencoded
token=2YotnFZFEjr1zCsicMWpAA
A response may look like:
{
"active": true,
"iss": "https://auth.example.com",
"sub": "user-123",
"aud": "https://mcp.example.com",
"scope": "documents:read",
"exp": 1784549700
}
The MCP server must still validate:
active- issuer
- audience
- expiration
- scopes
- user and tenant permissions
Introspection introduces a network dependency on the Authorization Server and should use authenticated, protected communication.
Short-Lived Access Tokens
Short token lifetimes limit the window in which a stolen Access Token can be used.
Example:
Access Token Lifetime:
15 minutes
Refresh Token Lifetime:
Longer, controlled separately
The official MCP authorization guidance recommends short-lived Access Tokens to reduce the impact of token leakage.
The exact lifetime depends on:
- operation sensitivity
- client type
- revocation capabilities
- network exposure
- user experience
- token-binding controls
- incident-response requirements
A shorter lifetime is not a substitute for secure storage.
Refresh Tokens
Refresh Tokens allow the MCP client to obtain a new Access Token without requiring the user to repeat the full authorization flow.
Refresh Token
│
▼
Token Endpoint
│
▼
New Access Token
Refresh Tokens are usually more sensitive than short-lived Access Tokens because they may provide long-term access.
They should be:
- stored securely
- scoped narrowly
- bound to the client
- revocable
- rotated for public clients
- protected from logs
- removed after logout
- invalidated after suspicious reuse
Refresh Token Rotation
Under rotation, every successful refresh returns a new Refresh Token and invalidates the previous one.
Refresh Token A
│
▼
New Access Token
Refresh Token B
Token A becomes invalid
If an old token is later reused, the Authorization Server can detect possible theft.
Legitimate Client uses Token B
Attacker later uses Token A
│
▼
Reuse Detected
│
▼
Revoke Token Family
The MCP specification requires rotation for public clients according to OAuth 2.1 requirements.
Scopes
Scopes express the categories of access requested by the MCP client.
Examples:
documents:read
documents:write
documents:delete
projects:admin
A client that only searches documents should not request:
documents:write
documents:delete
projects:admin
The Authorization Server should:
- define scopes clearly
- grant the minimum required access
- display understandable consent
- support incremental authorization
- prevent silent scope escalation
- include granted scopes in token state
- reject unsupported scope requests
The MCP Resource Server remains responsible for enforcing scopes and finer-grained object permissions.
Scopes Are Not Complete Authorization
A token may contain:
scope = documents:read
That does not mean the user may read every document.
The MCP server may still need to enforce:
- tenant membership
- project membership
- document ownership
- regional restrictions
- classification level
- role
- contractual policy
- object-specific access
OAuth Scope:
documents:read
│
▼
MCP Authorization:
May this user read this document?
The Authorization Server provides authorization context.
The Resource Server enforces access to its actual resources.
Incremental Authorization
An MCP server may expose both low-risk and high-risk tools.
The client may initially request:
documents:read
Later, when the user attempts an editing tool, the server can require:
documents:write
Initial Consent:
Read documents
Later Action:
Edit document
Additional Consent:
Write documents
The November 2025 MCP specification added guidance for incremental scope consent through WWW-Authenticate.
This avoids requesting every possible permission during initial setup.
Insufficient Scope Responses
When a valid token lacks the required scope, the MCP Resource Server can return a challenge indicating what is missing.
Conceptually:
HTTP/1.1 403 Forbidden
WWW-Authenticate: Bearer error="insufficient_scope",
scope="documents:write"
The client may then initiate an additional authorization flow.
The server must not silently treat missing scope as permission to perform a reduced or different high-impact action unless that behavior is explicit and safe.
Consent
Consent communicates what the client wants to access and what actions it may perform.
A useful consent screen should identify:
- MCP client
- MCP Resource Server
- requested permissions
- requesting organization
- affected account
- sensitive or destructive capabilities
- duration where relevant
Application:
Example AI Desktop
Requests access to:
Documentation MCP
Permissions:
✓ Read internal documents
✗ Modify documents
✗ Delete documents
Avoid vague consent such as:
Allow access to your data
Users cannot make a meaningful decision without understanding the requested capability.
Authentication vs Consent
The Authorization Server may authenticate the user without displaying a consent screen every time.
Consent may be:
- collected on first authorization
- remembered for previously approved scopes
- administered by an organization
- required again after scope expansion
- required again after client changes
- bypassed for a first-party application under policy
Authentication answers:
Who is the user?
Consent and authorization answer:
May this client receive this access
to this MCP resource?
They are separate decisions.
Client Identification Options
An Authorization Server must determine which MCP client is requesting access.
Current MCP authorization models may support several approaches:
- Client ID Metadata Documents
- Dynamic Client Registration
- Preregistered client credentials
The supported method should be advertised through metadata and enforced consistently.
Client ID Metadata Documents
Client ID Metadata Documents address the common MCP scenario where a client and Authorization Server have no previous relationship.
The client uses an HTTPS URL as its client_id:
https://client.example.com/oauth-client.json
That URL hosts metadata such as:
{
"client_id": "https://client.example.com/oauth-client.json",
"client_name": "Example MCP Client",
"redirect_uris": [
"https://client.example.com/oauth/callback"
],
"grant_types": [
"authorization_code"
],
"response_types": [
"code"
],
"token_endpoint_auth_method": "none"
}
The newer MCP authorization specification supports this approach and requires the document's client_id value to match its URL exactly.
Advantages
- no prior registration transaction
- stable HTTPS client identity
- inspectable client metadata
- suitable for distributed MCP clients
- avoids issuing a permanent Client Secret to public clients
Security Requirements
- HTTPS
- exact URL matching
- strict redirect URI validation
- SSRF-safe metadata retrieval
- size and timeout limits
- careful cache handling
- protection against metadata changes
Dynamic Client Registration
Dynamic Client Registration allows an MCP client to register itself programmatically.
MCP Client
│
▼
Registration Endpoint
│
▼
Client Metadata Validation
│
▼
Client ID Issued
A request may include:
{
"client_name": "Example MCP Client",
"redirect_uris": [
"http://127.0.0.1:43123/callback"
],
"grant_types": [
"authorization_code",
"refresh_token"
],
"response_types": [
"code"
],
"token_endpoint_auth_method": "none"
}
A response may include:
{
"client_id": "mcp-client-7f42",
"client_id_issued_at": 1784540000,
"redirect_uris": [
"http://127.0.0.1:43123/callback"
],
"token_endpoint_auth_method": "none"
}
RFC 8414 can advertise a registration_endpoint, while RFC 7591 defines the registration protocol.
Dynamic Registration Security
An unrestricted registration endpoint may be abused to:
- create large numbers of clients
- register deceptive names
- submit malicious redirect URIs
- trigger SSRF through metadata URLs
- consume database resources
- bypass administrative approval
- impersonate legitimate applications
Mitigations
- rate-limit registration
- validate redirect URIs
- restrict URI schemes
- verify metadata URLs safely
- limit field sizes
- reject deceptive names
- require initial access tokens where appropriate
- separate public and confidential client policies
- log registration activity
- expire unused registrations
- support client revocation
- require administrative approval for sensitive resources
Dynamic registration means automated onboarding, not automatic trust.
Preregistered Clients
An Authorization Server may use static client registration.
Administrator
│
Registers Client
│
▼
Client ID
Optional Client Credentials
This is appropriate when:
- the client population is known
- the deployment is internal
- enterprise approval is required
- high-risk MCP servers allow only selected clients
- operational simplicity matters more than open discovery
The MCP specification recommends that clients support static credentials or configuration where preregistration is required.
Preregistration provides stronger administrative control but requires a client onboarding process.
Public and Confidential Clients
Public Client
Cannot reliably protect a Client Secret.
Examples:
- desktop application
- command-line client
- mobile application
- browser-based application
- locally distributed editor extension
Primary protections include:
- PKCE
- strict redirects
- state validation
- short-lived tokens
- Refresh Token rotation
Confidential Client
Can authenticate securely to the token endpoint.
Examples:
- controlled backend service
- server-side web application
- internal gateway
- protected automation service
Possible authentication methods include:
- Client Secret
- private key JWT
- mutual TLS
- another approved method
Public Client:
Proof = PKCE + redirect flow protections
Confidential Client:
PKCE + authenticated client identity
A confidential client should still use PKCE where required. Client authentication does not eliminate authorization-code interception risk.
Client Secrets
Client Secrets should be:
- generated with high entropy
- stored in a secret manager
- transmitted only over TLS
- scoped to one client
- rotated
- excluded from logs
- unavailable to browser code
- unavailable to distributed public clients
Unsafe:
client_secret committed to Git repository
Also unsafe:
client_secret embedded in desktop application
A secret copied into every installation cannot provide meaningful confidential-client authentication.
Machine-to-Machine Authorization
Some MCP deployments operate without a human user.
Examples include:
- scheduled agents
- backend automation
- monitoring systems
- service integrations
- batch processing
In such cases, an Authorization Server may support a machine-oriented grant suitable for confidential clients.
Backend MCP Client
│
Authenticates to Authorization Server
│
▼
Resource-Bound Access Token
│
▼
MCP Resource Server
The credential should represent the workload, not impersonate a human by default.
Machine identities should receive:
- narrow scopes
- one intended resource
- short token lifetimes
- restricted network access
- auditable identity
- no interactive-user permissions unless explicitly delegated
The selected grant must be advertised and supported by the Authorization Server rather than assumed by the client.
Delegated Third-Party Authorization
An MCP service may depend on an upstream platform such as GitHub, Google, Microsoft, or another SaaS provider.
A secure architecture keeps the MCP OAuth boundary separate from the upstream OAuth boundary.
MCP Client
│
▼
MCP Authorization Server
│
▼
Upstream Authorization Server
│
▼
Upstream API
The MCP Authorization Server or backend may:
- authenticate the user
- obtain upstream authorization
- securely store the upstream token
- issue its own MCP-specific Access Token
- map the MCP token to the upstream authorization state
The older MCP specification described this pattern as a third-party authorization flow and required secure mapping and lifecycle management between upstream and MCP tokens.
Never Pass Through Upstream Tokens
The MCP server must not accept an upstream token from the MCP client and forward it blindly to another API.
It must also not issue the upstream token itself as though it were an MCP token.
Unsafe architecture:
MCP Client
│
Upstream SaaS Token
│
▼
MCP Server
│
Forwards Same Token
│
▼
Upstream API
Problems include:
- token audience mismatch
- confused deputy attacks
- exposing powerful upstream credentials
- bypassing MCP-specific authorization
- inability to enforce MCP scopes
- unclear audit attribution
Correct architecture:
MCP Client
│
MCP-Specific Token
aud = MCP Server
│
▼
MCP Server
│
Secure Server-Side Mapping
│
▼
Upstream Token
aud = Upstream API
The MCP security guidance explicitly prohibits token passthrough and requires tokens presented to MCP servers to be issued for those servers.
Token Audience Validation
An MCP Resource Server must verify that every Access Token was issued for that specific server.
A token may be correctly signed, unexpired, and issued by a trusted Authorization Server while still being invalid for the receiving MCP server.
Token:
iss = https://auth.example.com
aud = https://docs-mcp.example.com
Presented to:
https://finance-mcp.example.com
Result:
Reject
The audience identifies the intended recipient of the token.
For JWT Access Tokens, the audience is commonly represented by the aud claim:
{
"iss": "https://auth.example.com",
"sub": "user-123",
"aud": "https://mcp.example.com",
"scope": "documents:read",
"exp": 1784550000
}
The MCP server should compare the token audience with its configured resource identifier.
It should not derive the expected audience from an untrusted request header.
Why Signature Validation Is Not Enough
Consider two MCP servers protected by the same Authorization Server:
Authorization Server
│
├── Token for Calendar MCP
└── Token for Finance MCP
Both tokens may:
- use the same issuer
- use the same signing keys
- use the same signing algorithm
- contain valid user identities
- contain overlapping scope names
Without audience validation, the Finance MCP server might accept a token issued for the Calendar MCP server.
That creates cross-service token substitution.
Recommended Validation
The MCP Resource Server should verify:
- the token contains an audience
- its own resource identifier is present
- the audience format matches the deployment policy
- unexpected additional audiences are rejected where appropriate
- the audience is not inferred solely from the token's scope
- tokens intended for upstream APIs are rejected
Access Token
│
├── Trusted issuer?
├── Valid signature?
├── Correct audience?
├── Not expired?
└── Required permissions?
Resource Identifier Consistency
The same MCP resource identifier should be used consistently in:
- Protected Resource Metadata
- authorization requests
- token requests
- token audience claims
- introspection responses
- Resource Server configuration
For example:
https://mcp.example.com
An inconsistent deployment may use:
Protected Resource Metadata:
https://mcp.example.com
Authorization request:
https://mcp.example.com/
Token audience:
mcp.example.com
Although these values appear related, they may not be identical identifiers.
Authorization systems should define a canonical resource identifier and compare it according to the applicable OAuth rules rather than implementing unsafe normalization.
Potentially dangerous normalization includes:
- ignoring scheme differences
- removing ports
- accepting arbitrary subdomains
- converting paths
- using substring matching
- accepting suffix matches
Unsafe:
Expected:
https://mcp.example.com
Accepted:
https://mcp.example.com.attacker.example
Use exact, configured identifiers wherever possible.
Token Introspection
Token introspection allows an MCP Resource Server to ask the Authorization Server whether an Access Token is active and what authorization it represents.
This is especially common with opaque Access Tokens.
MCP Resource Server
│
▼
Introspection Endpoint
│
▼
Token Status and Claims
A simplified request:
POST /introspect HTTP/1.1
Host: auth.example.com
Authorization: Basic <resource-server-credentials>
Content-Type: application/x-www-form-urlencoded
token=2YotnFZFEjr1zCsicMWpAA
A simplified active response:
{
"active": true,
"iss": "https://auth.example.com",
"sub": "user-123",
"aud": "https://mcp.example.com",
"scope": "documents:read",
"exp": 1784550000,
"client_id": "mcp-client-123"
}
An inactive response:
{
"active": false
}
Introspection Validation
The MCP server should not stop after checking:
{
"active": true
}
It should also validate:
- expected issuer
- intended audience
- expiration
- required scopes
- client identity where relevant
- tenant
- subject
- authorization context
- token type
Protecting the Introspection Endpoint
The introspection endpoint reveals sensitive token information.
It should require authentication from approved Resource Servers.
Possible authentication methods include:
- private key JWT
- mutual TLS
- a confidential Client Secret
- workload identity through a trusted gateway
The endpoint should not allow arbitrary public callers to test whether stolen tokens are valid.
Introspection Availability
Online introspection creates a runtime dependency.
MCP Request
│
▼
MCP Server
│
▼
Authorization Server Introspection
If the Authorization Server is unavailable, the MCP server may be unable to validate opaque tokens.
Organizations must decide whether failure should be:
Fail Closed
Reject requests when authorization status cannot be verified.
This is normally appropriate for sensitive MCP operations.
Use a Short Cache
Cache successful introspection responses for a limited time.
This improves availability but increases the delay before revocation takes effect.
Offline JWT Validation
Use signed self-contained tokens so the MCP server can validate them without contacting the Authorization Server for every request.
This improves availability but makes immediate revocation more difficult unless additional revocation mechanisms exist.
The choice is a tradeoff between:
- availability
- revocation speed
- infrastructure complexity
- token lifetime
- operational risk
Token Revocation
Revocation invalidates previously issued authorization.
The Authorization Server may support revocation for:
- Refresh Tokens
- Access Tokens
- complete token families
- user grants
- client sessions
User Revokes Access
│
▼
Authorization Server
│
├── Revoke Refresh Token
├── Revoke Access Tokens
└── Mark Grant Inactive
A client may call a revocation endpoint:
POST /revoke HTTP/1.1
Host: auth.example.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic <client-authentication>
token=def50200...
&token_type_hint=refresh_token
What Revocation Should Cover
Depending on the reason, revocation may apply to:
- one token
- all tokens derived from one authorization grant
- all sessions for one MCP client
- all tokens for one user and resource
- all tokens issued to a compromised client
- all tokens signed by a compromised key
A stolen Refresh Token often requires revoking the complete token family rather than only one token value.
Revocation and JWT Access Tokens
Self-contained JWT Access Tokens may remain valid until expiration because Resource Servers validate them offline.
Possible approaches include:
- short Access Token lifetimes
- token revocation lists
- session-version claims
- authorization-state lookups
- event-based revocation notifications
- gateway-level enforcement
- emergency signing-key rotation
Each approach adds complexity.
For many MCP deployments, short-lived Access Tokens combined with revocable Refresh Tokens provide a practical balance.
Access Token:
Short lifetime
Refresh Token:
Longer lifetime
Revocable
Rotated
Consent Revocation
A user should be able to remove an MCP client's access.
A consent-management interface should clearly identify:
- MCP client
- MCP Resource Server
- granted scopes
- authorization date
- recent activity
- account used
- organization or tenant
- revocation control
Example AI Client
Access to:
Documentation MCP
Permissions:
- Read documents
- Search internal content
[Revoke Access]
Revoking consent should normally:
- invalidate the authorization grant
- revoke associated Refresh Tokens
- prevent new Access Tokens from being issued
- invalidate or rapidly expire active Access Tokens
- end related sessions where appropriate
- create an audit event
Removing the client from a user interface without revoking tokens is insufficient.
Logout
OAuth authorization, application sessions, and identity-provider sessions are different states.
A user may have:
- an MCP client session
- an Authorization Server session
- an identity-provider login session
- active Access Tokens
- active Refresh Tokens
- an upstream SaaS authorization
User Session Layers
│
├── MCP Client
├── Authorization Server
├── Identity Provider
└── Upstream Provider
Logging out of the MCP client may not automatically revoke tokens.
Logging out of the identity provider may not invalidate existing Access Tokens.
Clear Logout Semantics
An MCP product should explain whether logout:
- removes local tokens
- revokes Refresh Tokens
- ends the Authorization Server session
- signs the user out of the identity provider
- removes upstream authorizations
- affects other devices
For high-risk environments, a “sign out everywhere” operation may revoke all related grants and sessions.
OAuth Error Responses
Authorization Servers should return standardized OAuth errors without leaking unnecessary internal details.
Common authorization endpoint errors include:
invalid_requestunauthorized_clientaccess_deniedunsupported_response_typeinvalid_scopeserver_errortemporarily_unavailable
Common token endpoint errors include:
invalid_requestinvalid_clientinvalid_grantunauthorized_clientunsupported_grant_typeinvalid_scope
Example:
{
"error": "invalid_grant",
"error_description": "The authorization code is invalid or expired."
}
Error Security
Avoid exposing:
- database queries
- stack traces
- signing-key details
- internal hostnames
- complete token values
- whether a specific user account exists
- confidential client configuration
- exact anti-abuse thresholds
Detailed diagnostic information can be stored in protected server logs using a correlation identifier.
{
"error": "server_error",
"error_description": "The request could not be completed.",
"error_uri": "https://auth.example.com/errors/AUTH-102"
}
invalid_token and insufficient_scope
The MCP Resource Server should distinguish between an invalid token and a valid token lacking permission.
Invalid Token
Examples:
- expired token
- invalid signature
- wrong issuer
- wrong audience
- revoked token
- malformed token
Conceptual response:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer error="invalid_token"
Insufficient Scope
The token is valid but does not authorize the requested operation.
HTTP/1.1 403 Forbidden
WWW-Authenticate: Bearer
error="insufficient_scope",
scope="documents:write"
This distinction allows the client to decide whether it should:
- refresh authorization
- request an additional scope
- prompt the user
- stop the operation
The error response must not reveal protected resource details the caller is not authorized to know.
Authorization Server Hardening
An Authorization Server is a high-value target because it controls access to every MCP Resource Server that trusts it.
A compromise may allow an attacker to:
- issue forged tokens
- impersonate users
- grant excessive scopes
- redirect authorization codes
- steal Refresh Tokens
- modify OAuth metadata
- register malicious clients
- change signing keys
- access consent records
The Authorization Server should be treated as critical security infrastructure.
Administrative Isolation
Administrative interfaces should be separated from public OAuth endpoints.
Public:
- /authorize
- /token
- metadata
- JWKS
- registration where supported
Restricted:
- client administration
- key management
- policy configuration
- user impersonation
- audit export
- emergency revocation
Administrative access should require:
- strong multi-factor authentication
- privileged access management
- limited network reachability
- role separation
- detailed auditing
- short-lived administrator sessions
- change approval for sensitive operations
Signing-Key Security
Authorization Server signing keys determine whether Resource Servers trust a token.
Private signing keys should be protected using controls such as:
- hardware security modules
- managed key services
- non-exportable keys
- strict service identities
- limited signing permissions
- key-use auditing
- regular rotation
- emergency revocation procedures
Authorization Server
│
▼
Protected Signing Service
│
▼
Signed Access Token
Application code should not need direct access to raw private-key material when a managed signing service can perform the operation.
Key Separation
Different keys may be used for:
- Access Tokens
- ID Tokens
- metadata
- client assertions
- different environments
Production keys should never be shared with development or staging environments.
Algorithm Restrictions
The MCP Resource Server should allow only expected signing algorithms.
Unsafe validation may trust whatever algorithm the token header declares.
{
"alg": "unexpected-algorithm"
}
The Resource Server should configure an explicit allowlist such as:
Allowed:
ES256
Rejected:
Everything else
The appropriate algorithm depends on the deployment.
The important requirement is that the verifier selects policy first, rather than allowing the token to choose its own trust model.
The server should also:
- reject unsigned tokens
- reject algorithm confusion
- reject keys of unexpected types
- verify key use
- validate the selected
kid - limit remote key retrieval
JWKS Security
The jwks_uri is security-sensitive.
A Resource Server retrieving signing keys should:
- require HTTPS
- validate the expected issuer
- use the configured metadata relationship
- limit response size
- apply network timeouts
- cache keys securely
- handle rotation
- prevent SSRF
- reject unexpected redirects
- avoid trusting a
jkusupplied by the token
Unsafe pattern:
JWT header contains arbitrary key URL
│
▼
Resource Server downloads key
│
▼
Attacker controls verification key
Signing keys should come from the trusted Authorization Server configuration, not from an arbitrary token-controlled location.
Authorization Endpoint Protection
The authorization endpoint interacts directly with users and is a major phishing target.
Controls should include:
- strong user authentication
- session protection
- CSRF defenses
- clickjacking protection
- clear client identity
- clear resource identity
- scope display
- suspicious-login detection
- rate limiting
- secure cookies
- protection against open redirects
Users should be able to distinguish:
- the Authorization Server
- the MCP client
- the MCP Resource Server
A deceptive screen that only says “Allow AI access” does not provide meaningful context.
Phishing Attacks
A malicious MCP server may advertise a fake Authorization Server.
MCP Server
│
▼
Fake Authorization URL
│
▼
User Enters Credentials
│
▼
Attacker
A malicious client may also imitate a legitimate consent flow.
Mitigations
- discover authorization endpoints from verified metadata
- use HTTPS
- validate issuer relationships
- display the Authorization Server domain clearly
- allow enterprise issuer restrictions
- warn when an issuer changes
- use phishing-resistant authentication
- avoid embedded webviews where they weaken origin visibility
- educate users not to enter credentials into the MCP client itself
The MCP client should open the actual Authorization Server authorization endpoint rather than collecting the user's Authorization Server password.
OAuth Mix-Up Attacks
Mix-up attacks can occur when a client supports several Authorization Servers and confuses which server produced an authorization response.
Client Supports:
Authorization Server A
Authorization Server B
Attacker Causes:
Response from B
treated as response from A
Consequences may include:
- sending a code to the wrong token endpoint
- leaking authorization codes
- accepting tokens from the wrong issuer
- misbinding a user session
Mitigations
- bind each authorization request to the selected issuer
- validate issuer information in the response where supported
- use distinct redirect URIs where appropriate
- store Authorization Server state per authorization transaction
- send the code only to the matching token endpoint
- validate token issuer
- never select the token endpoint using attacker-controlled callback data
Authorization Code Injection
An attacker may attempt to inject their own authorization code into another user's client session.
Potential result:
Victim MCP Client
│
Redeems Attacker's Code
│
▼
Client Connected to Attacker's Account
The victim may then upload sensitive information into the attacker's account.
Mitigations include:
- PKCE
- state validation
- issuer binding
- strict redirect handling
- one-time authorization transaction records
- short-lived codes
- client and redirect URI binding
SSRF in Authorization Discovery
Authorization discovery may require the MCP client or its backend to fetch URLs advertised by an MCP Resource Server.
Potential URLs include:
- Protected Resource Metadata
- Authorization Server Metadata
- OpenID Connect configuration
- client metadata
- JWKS
- registration endpoints
A malicious server may advertise:
http://169.254.169.254/
or:
http://127.0.0.1:8080/admin
Required Defenses
- require HTTPS for remote endpoints
- block loopback addresses
- block private and link-local networks
- block cloud metadata addresses
- validate DNS resolutions
- revalidate redirects
- limit response size
- apply strict timeouts
- restrict ports
- use an egress proxy
- maintain an issuer allowlist where possible
Authorization metadata should be treated as untrusted input until validated.
Metadata Caching
Authorization and JWKS metadata may be cached to improve performance and availability.
Caching introduces security considerations.
A client or Resource Server should define:
- maximum cache lifetime
- forced refresh behavior
- response size limits
- handling of changed issuers
- handling of changed endpoints
- key-rotation refresh
- stale-cache policy during outages
- administrator override
Unexpected changes in:
- issuer
- token endpoint
- authorization endpoint
- registration endpoint
- JWKS URI
- signing keys
should be treated as security-relevant events.
A cached endpoint should not remain trusted indefinitely after the relationship changes.
Client Registration Security
The Authorization Server should validate client metadata before accepting a client.
Relevant checks include:
- redirect URI scheme
- redirect host
- exact callback paths
- client type
- token endpoint authentication method
- grant types
- response types
- client name
- logo and policy URLs
- metadata document origin
- software identity
A malicious client might attempt to register:
{
"client_name": "Official Corporate MCP Client",
"redirect_uris": [
"https://attacker.example/callback"
]
}
The displayed client name should not be treated as verified identity.
High-risk MCP Resource Servers may require administrative client approval even if automated registration is supported technically.
Rate Limiting and Abuse Prevention
Authorization Server endpoints may be abused for:
- password attacks
- registration floods
- token guessing
- Refresh Token replay
- authorization request spam
- consent fatigue
- resource exhaustion
- user enumeration
Rate limiting may be applied by:
- IP
- account
- client
- device
- tenant
- endpoint
- failed authentication count
- risk score
Limits should not rely only on source IP because many users may share addresses and attackers may distribute requests.
Security controls should avoid creating denial-of-service opportunities against legitimate users.
Refresh Token Replay Detection
With Refresh Token rotation, the Authorization Server can detect reuse of an invalidated token.
Token A issued
│
Token A exchanged
│
Token B issued
Token A invalidated
│
Token A used again
│
▼
Possible Theft
A secure response may:
- revoke the token family
- revoke active Access Tokens
- end the client session
- require user reauthentication
- generate an audit alert
- notify the user
Replay detection should distinguish between:
- benign retry caused by network failure
- parallel requests from one client
- actual token theft
Clients should serialize refresh operations where practical to avoid accidental replay.
Multi-Tenant Authorization
An Authorization Server protecting multi-tenant MCP services must prevent cross-tenant token use.
A token may include tenant context:
{
"sub": "user-123",
"aud": "https://mcp.example.com",
"tenant_id": "tenant-a",
"scope": "documents:read"
}
The MCP Resource Server must independently enforce tenant boundaries.
Unsafe:
Tool Argument:
tenant_id = tenant-b
Token:
tenant_id = tenant-a
Server trusts tool argument
Safe:
Token tenant:
tenant-a
Requested object tenant:
tenant-b
Result:
Reject
Multi-Tenant Requirements
- bind authorization grants to a tenant
- include trusted tenant context
- prevent users from selecting unauthorized tenants
- isolate client registrations where required
- prevent cross-tenant Refresh Token use
- validate organization membership continuously
- handle users belonging to multiple tenants explicitly
- log tenant switches
- prevent tenant IDs from being controlled only by model-generated arguments
User and Workload Identity Separation
An MCP operation may involve:
- a human user
- an MCP client
- a backend workload
- the MCP Resource Server
- an upstream API identity
These identities should not be collapsed into one generic service account.
Human:
user-123
OAuth Client:
ai-desktop
MCP Workload:
mcp-server-prod
Upstream Identity:
service-connector-42
Audit and authorization decisions should preserve which actor performed each role.
This improves:
- least privilege
- incident investigation
- revocation
- tenant isolation
- non-repudiation
- consent transparency
Impersonation and Delegation
Some enterprise Authorization Servers support administrator or service impersonation.
This capability is dangerous because it may bypass normal user authentication.
If impersonation is permitted, tokens should clearly distinguish:
- effective user
- acting administrator or service
- delegation reason
- authorization chain
Actor:
support-admin-42
Effective User:
user-123
MCP audit logs should not record only the effective user.
Impersonation should require:
- explicit privileged permission
- strong authentication
- a documented reason
- short token lifetime
- enhanced logging
- user notification where appropriate
- restrictions on high-impact tools
Step-Up Authentication
A user may authenticate normally for low-risk MCP operations but require stronger verification for sensitive actions.
Example:
Read documentation:
Normal session
Delete production resource:
Recent MFA required
The Authorization Server may enforce step-up authentication based on:
- requested scope
- MCP resource
- tool sensitivity
- transaction value
- user risk
- device posture
- session age
- geographic anomaly
The Access Token may carry authentication-context information that the MCP Resource Server can evaluate.
The MCP server should not assume that any valid login is sufficient for every operation.
Authorization Policy Changes
User permissions can change after a token is issued.
Examples include:
- removal from an organization
- role downgrade
- project access removal
- account suspension
- employment termination
- policy updates
- tenant deletion
Long-lived self-contained tokens may continue carrying stale authorization.
Mitigations include:
- short Access Token lifetimes
- introspection
- authorization-state checks
- revocation events
- token-version claims
- immediate session termination for critical changes
The appropriate method depends on how quickly access changes must take effect.
Audit Logging
An Authorization Server should record security-relevant events.
Useful events include:
- authorization request received
- user authentication success or failure
- consent granted or denied
- authorization code issued
- code redemption
- Access Token issuance
- Refresh Token issuance and rotation
- Refresh Token replay
- token revocation
- client registration
- client metadata change
- signing-key rotation
- administrative policy change
- suspicious issuer or redirect attempt
Useful Audit Fields
- timestamp
- user
- client
- resource
- scopes
- tenant
- grant type
- authentication method
- result
- network context
- correlation identifier
- administrator actor where applicable
Do not log complete:
- Access Tokens
- Refresh Tokens
- authorization codes
- Client Secrets
- user passwords
- session cookies
Token fingerprints may be used for correlation without storing reusable credentials.
Correlating Authorization and MCP Tool Calls
A complete audit trail should connect authorization events with MCP activity.
Authorization Event
│
▼
Token or Session Identifier
│
▼
MCP Request
│
▼
Tool Execution
│
▼
Downstream Action
This enables investigators to determine:
- which client received authorization
- which user approved it
- which resource was targeted
- which scopes were granted
- which tool was called
- which downstream system changed
- whether the operation was permitted
Correlation identifiers should not expose raw token values.
Privacy in Authorization Logs
Authorization logs may contain sensitive information such as:
- user identities
- organizational relationships
- requested resources
- scopes
- IP addresses
- device information
- security decisions
Logs should have:
- access controls
- retention limits
- encryption
- integrity protection
- regional handling rules
- monitoring for unauthorized access
- redaction
- deletion procedures
Security logging should be detailed enough for investigation without becoming a new source of credential or personal-data exposure.
High Availability
If many MCP Resource Servers depend on one Authorization Server, it becomes a critical shared dependency.
Potential failure points include:
- authorization endpoint
- token endpoint
- metadata endpoint
- JWKS endpoint
- introspection endpoint
- registration endpoint
- key-management service
- user directory
- upstream identity provider
Authorization Server Failure
│
├── New logins fail
├── Token refresh fails
├── Introspection fails
└── MCP access degrades
Availability Controls
- multiple instances
- regional redundancy
- replicated authorization state
- resilient key services
- protected metadata caching
- JWKS caching
- health monitoring
- capacity planning
- rate-limit isolation
- dependency timeouts
- tested disaster recovery
Security During Authorization Server Outages
An outage should not cause systems to bypass authorization.
Unsafe fallback:
Authorization Server unavailable
│
▼
MCP Server allows request
Safer behavior depends on token type and risk.
Valid Cached JWT
The MCP server may continue accepting a correctly signed, unexpired token using cached public keys.
Opaque Token Requiring Introspection
The server may fail closed or use a very short validated cache according to documented policy.
New Authorization
The client should report that authorization is temporarily unavailable rather than silently using unrelated credentials.
Security-critical MCP actions should not become anonymous because the Authorization Server is down.
Backup and Recovery
Authorization Server backups may contain:
- client registrations
- consent records
- Refresh Tokens
- signing-key metadata
- user-session state
- policy configuration
- audit logs
Backups should be:
- encrypted
- access-controlled
- integrity-protected
- tested
- retained according to policy
- separated from production credentials
Private signing keys should be backed up only through an approved secure key-management process.
Restoring an outdated authorization database can accidentally reactivate:
- revoked clients
- revoked grants
- removed administrators
- expired policies
- old signing configuration
Recovery procedures should reconcile security state before returning to service.
Authorization Server Deployment Architecture
A production architecture may separate public OAuth traffic from sensitive internal services.
MCP Client
│
▼
Public Authorization Gateway
│
├── TLS
├── Rate Limits
├── Request Filtering
└── DDoS Protection
│
▼
Authorization Service
│
├── User Authentication
├── Consent
├── Client Validation
├── Policy Evaluation
└── Token Service
│
├────────► Key Management Service
├────────► User Directory
├────────► Consent Store
└────────► Audit Pipeline
The token-signing operation may be isolated further:
Authorization Service
│
Authenticated Signing Request
│
▼
Restricted Signing Service
│
▼
Hardware-Protected Key
Separating Authorization and Business Data
The Authorization Server should not need unrestricted access to every MCP Resource Server's business data.
Its role is to issue authorization context.
The MCP server remains responsible for resource-specific decisions.
Authorization Server:
User may request document access
MCP Resource Server:
User may read document 42
This separation limits the blast radius of Authorization Server compromise and avoids centralizing all application data in the identity layer.
Centralized Authorization Server Tradeoffs
Using one Authorization Server for many MCP servers provides:
- consistent authentication
- centralized consent
- common policy
- easier revocation
- simpler user management
- consolidated auditing
It also creates:
- a high-value target
- a shared availability dependency
- broad impact from signing-key compromise
- risk of overly generic scopes
- possible cross-resource token confusion
Strong audience binding and Resource Server validation are essential in centralized deployments.
Dedicated Authorization Servers
High-risk MCP systems may use dedicated Authorization Servers or isolated authorization realms.
Examples include:
- financial operations
- production infrastructure
- healthcare data
- regulated customer records
- administrative control planes
Benefits may include:
- smaller trust domain
- separate signing keys
- dedicated policies
- isolated administrators
- independent audit retention
- reduced cross-service impact
The operational cost is higher because identity, keys, clients, and policy must be managed separately.
Authorization Server Implementation Options
Organizations may:
- use an existing identity platform
- extend an existing OAuth Authorization Server
- deploy an OAuth-focused open-source product
- build a custom authorization service
Using an established implementation usually reduces the amount of OAuth protocol logic that must be written and maintained.
A custom server requires expertise in:
- OAuth security
- PKCE
- redirect validation
- client registration
- token issuance
- key management
- Refresh Token rotation
- discovery
- revocation
- mix-up defenses
- tenant isolation
- incident response
OAuth flows should not be implemented through ad hoc login endpoints and manually constructed tokens.
MCP Authorization Server Implementation Checklist
Architecture
- Is the MCP server treated as a Resource Server?
- Is the Authorization Server role clearly separated?
- Is the canonical MCP resource identifier defined?
- Can one issuer protect several resources safely?
- Are high-risk resources isolated where appropriate?
- Is business authorization enforced by the MCP server?
Discovery
- Does the MCP server publish Protected Resource Metadata?
- Does it return a correct
WWW-Authenticatechallenge? - Is Authorization Server Metadata available?
- Is the issuer validated exactly?
- Are OpenID Connect discovery rules applied correctly where supported?
- Are metadata URLs protected against SSRF?
- Are unexpected endpoint changes monitored?
Authorization Requests
- Is the Authorization Code flow used for user delegation?
- Is PKCE required?
- Is only
S256accepted? - Is
stategenerated with sufficient entropy? - Is the authorization request bound to one issuer?
- Is the
resourceparameter required? - Are requested scopes validated?
- Are authorization requests protected from tampering?
Redirect URIs
- Are redirect URIs preregistered or securely derived from verified client metadata?
- Is exact matching used?
- Are arbitrary wildcards rejected?
- Are remote redirects HTTPS-only?
- Are loopback callbacks bound only to loopback?
- Are open redirects blocked?
- Are custom schemes restricted?
- Is each authorization response accepted only once?
Authorization Codes
- Are codes short-lived?
- Are codes single-use?
- Are they bound to the client?
- Are they bound to the redirect URI?
- Are they bound to the intended resource?
- Are they bound to the PKCE challenge?
- Is code replay detected?
- Are codes excluded from logs?
Client Registration
- Which client identification methods are supported?
- Are public and confidential clients distinguished?
- Are client metadata documents fetched safely?
- Is Dynamic Client Registration rate-limited?
- Are redirect URIs validated at registration?
- Are deceptive client names handled safely?
- Can sensitive MCP resources require preregistration?
- Can clients be revoked centrally?
Token Issuance
- Are tokens issued for the requested MCP resource?
- Is the audience recorded correctly?
- Are scopes minimized?
- Are Access Tokens short-lived?
- Are Refresh Tokens protected?
- Is Refresh Token rotation enabled for public clients?
- Is replay detected?
- Are token responses protected from caching?
Token Validation
- Is the signature verified?
- Are allowed algorithms configured explicitly?
- Is the issuer validated?
- Is the audience validated?
- Is expiration checked?
- Are not-before conditions checked?
- Are scopes enforced?
- Are tenant and object-level permissions enforced separately?
- Are upstream tokens rejected?
- Are tokens accepted only through the Authorization header?
Signing Keys
- Are private keys protected by a managed key service or HSM where appropriate?
- Are keys non-exportable where possible?
- Are key operations audited?
- Is rotation documented?
- Are old keys retained only as long as required?
- Can compromised keys be revoked?
- Is the JWKS endpoint protected from unauthorized modification?
- Do development and production use separate keys?
Refresh and Revocation
- Are Refresh Tokens bound to the client?
- Are they rotated?
- Is reuse detected?
- Can a token family be revoked?
- Can users revoke consent?
- Can administrators revoke a client?
- Can all grants for a compromised resource be disabled?
- Are logout semantics documented?
Scopes and Consent
- Are scopes understandable?
- Are destructive permissions separated?
- Is incremental authorization supported?
- Are high-risk scopes clearly displayed?
- Is consent bound to the client and resource?
- Are scope expansions shown again?
- Can enterprise administrators preapprove or deny access?
- Does the MCP server perform finer-grained authorization?
Multi-Tenant Security
- Is tenant identity derived from trusted authorization context?
- Are tenant memberships validated?
- Are client registrations isolated appropriately?
- Can a token for one tenant be used in another?
- Are tenant switches explicit?
- Are administrator impersonation events logged?
- Are cross-tenant tests included in security testing?
Endpoint Protection
- Are authorization and token endpoints rate-limited?
- Are secure cookies used?
- Is CSRF protection implemented?
- Is clickjacking blocked?
- Are public and administrative endpoints separated?
- Are error messages sanitized?
- Are direct backend connections restricted?
- Are proxy headers trusted only from approved infrastructure?
Monitoring
- Are authorization failures logged?
- Are client registrations monitored?
- Are redirect changes alerted?
- Are Refresh Token replays alerted?
- Are signing-key changes alerted?
- Are metadata changes monitored?
- Can authorization events be correlated with MCP tool calls?
- Are suspicious scope requests investigated?
Availability
- Is the Authorization Server redundant?
- Are JWKS documents cached safely?
- Is introspection failure behavior documented?
- Does the system fail closed for sensitive operations?
- Are dependencies protected with timeouts?
- Is disaster recovery tested?
- Does recovery preserve revocation state?
- Are emergency key rotation procedures available?
Incident Response
- Can client access be disabled immediately?
- Can user grants be revoked?
- Can Refresh Token families be invalidated?
- Can signing keys be rotated urgently?
- Can affected Resource Servers reject compromised tokens?
- Are token and authorization inventories available?
- Are logs sufficient to determine affected users and resources?
- Are users notified when appropriate?
Recommended MCP Authorization Architecture
A secure user authorization flow may look like:
MCP Client
│
│ 1. Request protected MCP endpoint
▼
MCP Resource Server
│
│ 2. 401 + Protected Resource Metadata
▼
MCP Client
│
│ 3. Discover and validate issuer
▼
Authorization Server
│
│ 4. Authenticate user
│ 5. Validate client
│ 6. Obtain consent
│ 7. Validate PKCE
▼
Resource-Bound Access Token
│
│ aud = MCP Resource Server
│ scope = minimum required
▼
MCP Resource Server
│
├── Validate signature or introspection
├── Validate issuer
├── Validate audience
├── Validate scope
├── Validate tenant
├── Validate object permission
└── Execute approved tool
For upstream SaaS integration:
MCP Client
│
MCP Access Token
│
▼
MCP Resource Server
│
Server-Side Token Mapping
│
▼
Upstream Access Token
│
▼
Upstream API
The upstream token remains hidden from the MCP client.
Common MCP Authorization Server Mistakes
Treating the MCP Server as an OAuth Proxy
Passing upstream tokens through the MCP boundary breaks audience separation and enables confused deputy attacks.
Skipping the Resource Parameter
The Authorization Server may issue a token without a clearly defined MCP audience.
Accepting Any Token from a Trusted Issuer
A trusted issuer can issue tokens for many unrelated resources.
Audience validation is still mandatory.
Using Scopes as Audiences
A scope describes permission, not the intended Resource Server.
Embedding a Client Secret in Desktop Software
Distributed software cannot reliably keep one shared secret confidential.
Allowing Weak Redirect Matching
Prefix, suffix, or wildcard matching may redirect codes to attacker-controlled endpoints.
Supporting PKCE but Not Requiring It
An attacker may intentionally omit PKCE and weaken the flow.
Trusting Client Display Names
A registered name such as “Official MCP Client” is not verified identity.
Decoding JWTs Without Verifying Them
Readable claims are not trustworthy until the signature and security properties are validated.
Ignoring Tenant Authorization
A valid user and scope do not automatically grant access to every tenant or object.
Logging Tokens
Access Tokens, Refresh Tokens, and authorization codes are credentials.
Failing Open During an Outage
Authorization infrastructure failure must not make protected MCP tools anonymous.
Conclusion
An MCP Authorization Server is the security authority that enables MCP clients to obtain controlled access to protected MCP servers.
Its responsibilities extend beyond displaying a login page.
A secure implementation must:
- publish trustworthy OAuth metadata
- identify MCP clients safely
- require Authorization Code flow protections
- enforce PKCE
- validate redirect URIs
- bind authorization to a specific MCP resource
- issue short-lived Access Tokens
- rotate Refresh Tokens
- support revocation
- protect signing keys
- prevent issuer and client confusion
- isolate tenants
- produce reliable audit trails
- remain available without weakening security
The MCP Resource Server must independently validate every token and enforce authorization for the actual tool, object, user, and tenant.
The central principle is:
The Authorization Server grants a client limited access to a specific MCP resource. It does not grant general-purpose authority across every service that trusts the same identity system.
Continue learning:
- MCP OAuth — Understand the complete MCP OAuth authorization flow.
- MCP Authorization Code Flow — Implement secure user authorization with PKCE.
- MCP Protected Resource Metadata — Advertise the MCP resource and its trusted Authorization Servers.
- MCP OAuth Discovery — Discover and validate authorization infrastructure safely.
- OAuth Resource Indicators for MCP — Bind Access Tokens to the intended MCP Resource Server.
- MCP Access Token Validation — Validate issuer, audience, scopes, signatures, and expiration.
- MCP Dynamic Client Registration — Register previously unknown MCP clients securely.
- MCP Token Passthrough — Understand why upstream Access Tokens must not cross the MCP trust boundary.
- MCP Security Best Practices — Apply layered protection across the entire MCP architecture.