| title | Enterprise-Managed Authorization |
|---|
Protocol Revision: draft
This document defines an application of the "Identity Assertion Authorization Grant" for use within enterprise deployments of the Model Context Protocol (MCP).
When an MCP Client and MCP Server are both enabled for single sign-on through an enterprise Identity Provider, this three-way relationship can be leveraged to streamline the authorization process.
This document specifies how an MCP Client can obtain an access token from an MCP Server's Authorization Server by presenting an identity assertion it previously obtained from an enterprise Identity Provider during single sign-on. It also describes how an MCP Server's Authorization Server can validate the request from the client before issuing an access token.
This profile is designed to facilitate secure and interoperable authorization within enterprise environments, leveraging the organization's existing identity infrastructure. Enterprise-managed authorization for MCP Clients and Servers has some key benefits:
- For end users, this removes the need to manually connect and authorize the MCP Client to each MCP Server for use within the organization.
- For enterprise admins, this enables visibility and control over which MCP Servers are able to be used within the organization.
- For MCP clients, this enables the client to automatically obtain access tokens for any connected MCP servers without user interaction, and removes the need for user interaction when obtaining new access tokens.
- Resource Application: In the context of this profile, the Resource Application is the MCP Server.
- Identity Provider (IdP): An entity that creates, maintains, and manages identity information, provides authentication services, and is trusted by a set of applications in an organization's app ecosystem.
- Identity Assertion: A security token (e.g., ID Token, SAML Assertion) that contains information about an authenticated user and is issued by an Identity Provider trusted by the Authorization Server.
- Authorization Server: This profile uses the term "Authorization Server" to refer to the authorization server that issues tokens to be used at the MCP server.
- Client: In the context of this profile, the Client is the MCP Client.
- ID Token: A security token that contains claims about the authentication of a user when using a client, as defined in OpenID Connect.
- Subject Token: A security token that represents the identity of the user, such as an ID Token.
- JAG: JWT Authorization Grant, as described in RFC7523.
This profile is an application of the "Identity Assertion Authorization Grant" draft-ietf-oauth-identity-assertion-authz-grant, which itself is a profile of "Identity and Authorization Chaining Across Domains" draft-ietf-oauth-identity-chaining.
The Identity Assertion Authorization Grant follows three steps:
- Single Sign-On to the MCP Client via OpenID Connect or SAML
- Token Exchange (RFC8693)
- JWT Authorization Grant (RFC7523)
The core flow is as follows:
- A user logs in to an MCP Client through their enterprise Identity Provider, resulting in an Identity Assertion (ID Token or SAML assertion) being issued to the MCP Client.
- The MCP Client sends a Token Exchange [RFC8693] request to the Identity Provider including the identity assertion and identifier of the MCP Server it is attempting to access, and obtains a Identity Assertion JWT Authorization Grant (ID-JAG).
- The MCP Client uses the Identity Assertion JWT Authorization Grant as a JWT Authorization Grant [RFC7523] to request an access token from the Authorization Server.
- The Authorization Server validates the Identity Assertion Authorization Grant and, if valid, issues an access token.
- The MCP Client uses the access token to make requests to the MCP Server.
The following diagram outlines an example flow:
sequenceDiagram
participant UA as Browser
participant C as MCP Client
participant IdP as Identity Provider
participant MAS as MCP Authorization Server
participant MRS as MCP Resource Server
C-->>UA: Redirect to IdP
UA->>IdP: Redirect to IdP
Note over IdP: User Logs In
IdP-->>UA: IdP Authorization Code
UA->>C: IdP Authorization Code
C->>IdP: Token Request with IdP Authorization Code
IdP-->>C: ID Token
note over C: User is logged<br/>in to MCP Client.<br/>Client stores ID Token.
C->>IdP: Exchange ID Token for ID-JAG
note over IdP: Evaluate Policy
IdP-->>C: Responds with ID-JAG
C->>MAS: Token Request with ID-JAG
note over MAS: Validate ID-JAG
MAS-->>C: MCP Access Token
loop
C->>MRS: Call MCP API with Access Token
MRS-->>C: MCP Response with Data
end
To authenticate a user, the MCP Client initiates the process through a request with the IdP using OpenID Connect or SAML.
For example, a web-based MCP client might initiate the user authentication process by redirecting the browser using OpenID Connect:
302 Redirect
Location: https://acme.idp.example/authorize?response_type=code&scope=openid&client_id=...
The user authenticates with the IdP, and is redirected back to the Client with an authorization code, which it can then exchange for an ID Token.
The enterprise IdP may enforce additional security controls such as multi-factor authentication before granting the user access to the MCP Client. For example, in an OpenID Connect flow, after receiving a redirect from the IdP with an authorization code, the MCP server makes a request to the Authorization Server and, if valid, receives the tokens in the response:
POST /token HTTP/1.1
Host: acme.idp.example
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=.....
HTTP/1.1 200 OK
Content-Type: application/json
{
"id_token": "eyJraWQiOiJzMTZ0cVNtODhwREo4VGZCXzdrSEtQ...",
"token_type": "Bearer",
"access_token": "7SliwCQP1brGdjBtsaMnXo",
"scope": "openid"
}
To request a JWT Assertion Grant, the MCP Client MUST make a Token Exchange (RFC8693) request to the IdP's Token Endpoint with the following parameters:
| Parameter | Required/Optional | Description | Example/Allowed Values |
|---|---|---|---|
requested_token_type |
REQUIRED | Indicates that an ID Assertion JWT is being requested. | urn:ietf:params:oauth:token-type:id-jag |
audience |
REQUIRED | The Issuer URL of the MCP server's authorization server. | https://auth.chat.example/ |
resource |
REQUIRED | The RFC9728 Resource Identifier of the MCP server. | https://mcp.chat.example/ |
scope |
OPTIONAL | The space-separated list of scopes at the MCP Server that are being requested. | scope1 scope2 |
subject_token |
REQUIRED | The identity assertion (e.g. the OpenID Connect ID Token or SAML assertion) for the target end-user. | (JWT or SAML assertion string) |
subject_token_type |
REQUIRED | Indicates the type of the security token in the subject_token parameter, as specified in RFC8693 Section 3. |
urn:ietf:params:oauth:token-type:id_token (OIDC)urn:ietf:params:oauth:token-type:saml2 (SAML) |
Additional parameters defined in Section 2.1 of RFC8693 (actor_token and actor_token_type) are not used in this specification.
If the IdP requires client authentication when the MCP Client performs OpenID Connect for single sign-on, then client authentication of the Token Exchange request is also required.
The example below illustrates the Token Exchange request, using an OpenID Connect ID Token as the Identity Assertion and a client secret as the client authentication method. The ID token is passed as a Subject Token.
POST /oauth2/token HTTP/1.1
Host: acme.idp.example
Content-Type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:token-exchange
&requested_token_type=urn:ietf:params:oauth:token-type:id-jag
&audience=https://auth.chat.example/
&resource=https://mcp.chat.example/
&scope=chat.read+chat.history
&subject_token=eyJraWQiOiJzMTZ0cVNtODhwREo4VGZCXzdrSEtQ...
&subject_token_type=urn:ietf:params:oauth:token-type:id_token
&client_id=2ec954a1d60620116d36d9ceb7
&client_secret=a26d84873504215a34a86d52ef5cd64f4b76
The IdP MUST validate the Subject Token, and MUST validate that the audience of the Subject Token (e.g. the aud claim of the ID Token) matches the Client Identifier of the MCP client making this request (e.g. by checking the client_id in the client authentication).
The IdP evaluates administrator-defined policies for the token exchange request and determines if the MCP Client should be granted access to act on behalf of the user for the target MCP Server and scopes.
The IdP may also introspect the authentication context described in the Identity Assertion to determine if step-up authentication is required.
If access is granted, the IdP creates a signed Identity Assertion JWT Authorization Grant and returns it in the token exchange response defined in Section 2.2 of RFC8693:
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache
{
"issued_token_type": "urn:ietf:params:oauth:token-type:id-jag",
"access_token": "eyJhbGciOiJIUzI1NiIsI...",
"token_type": "N_A",
"scope": "chat.read chat.history",
"expires_in": 300
}
| Parameter | Required/Optional | Description | Example/Allowed Values |
|---|---|---|---|
issued_token_type |
REQUIRED | Indicates the type of token issued. | urn:ietf:params:oauth:token-type:id-jag |
access_token |
REQUIRED | The Identity Assertion JWT Authorization Grant. (Note: Token Exchange requires the access_token response parameter for historical reasons, not an OAuth token.) |
(JWT string) |
token_type |
REQUIRED | The token type. | N_A (because this is not an OAuth access token.) |
scope |
OPTIONAL/REQUIRED | OPTIONAL if the scope of the issued token is identical to the requested; otherwise REQUIRED. May be fewer scopes than requested. | scope1 scope2 |
expires_in |
RECOMMENDED | The lifetime in seconds of the authorization grant. | 3600 |
In case of an error occurring while performing the token exchange, the IdP will return an OAuth 2.0 Token Error response as defined in Section 5.2 of RFC6749. An example response may look like this:
HTTP/1.1 400 Bad Request
Content-Type: application/json
Cache-Control: no-store
{
"error": "invalid_grant",
"error_description": "Audience validation failed"
}
The Identity Assertion JWT Authorization Grant (ID-JAG) is issued and signed by the IdP, and describes the intended audience of the authorization grant as well as the client to which it was issued and the subject identifier of the resource owner, using the following claims:
| Parameter | Required/Optional | Description | Reference / Example |
|---|---|---|---|
iss |
REQUIRED | The IdP issuer URL. | Section 4.1.1 of RFC7519 |
sub |
REQUIRED | The subject identifier (e.g., user ID) of the user at the MCP Server. | Section 4.1.2 of RFC7519 |
aud |
REQUIRED | The Issuer URL of the MCP Server's authorization server. | Section 4.1.3 of RFC7519 |
resource |
REQUIRED | The Resource Identifier of the MCP Server. | Section 1.2 of RFC9728 |
client_id |
REQUIRED | An identifier of the MCP Client registered at the Authorization Server that this JWT was issued to; SHOULD be a client_id as defined in Section 4.3 of RFC8693. |
Section 4.3 of RFC8693 |
jti |
REQUIRED | Unique ID of this JWT. | Section 4.1.7 of RFC7519 |
exp |
REQUIRED | Expiration time of this JWT (Unix timestamp in seconds). | Section 4.1.4 of RFC7519 |
iat |
REQUIRED | Issued-at time of this JWT (Unix timestamp in seconds). | Section 4.1.6 of RFC7519 |
scope |
OPTIONAL | A JSON string containing a space-separated list of scopes associated with the token, per Section 3.3 of RFC6749. | ["scope1 scope2"]Section 3.3 of RFC6749 |
The typ claim of the JWT indicated in the JWT header MUST be oauth-id-jag+jwt.
An example JWT shown with expanded header and payload claims may look like this:
{
"typ": "oauth-id-jag+jwt"
}
.
{
"jti": "9e43f81b64a33f20116179",
"iss": "https://acme.idp.example",
"sub": "U019488227",
"aud": "https://auth.chat.example/",
"resource": "https://mcp.chat.example/",
"client_id": "f53f191f9311af35",
"exp": 1311281970,
"iat": 1311280970,
"scope": "chat.read chat.history"
}
.
signature
The authorization server MAY add additional claims as necessary.
If the IdP is multi-tenant and uses the same issuer for all tenants, the MCP Server will already have IdP-specific logic to determine the tenant from the OpenID Connect ID Token (e.g., the hd claim for Google) or SAML assertion, and will need to use that if the IdP also has only one client registration for the MCP Server.
sub should be an opaque ID, as iss+sub is unique. The IdP might want to also include additional user information, such as an email address, which it should do as a new email claim. This may allow the MCP Client application to properly link existing user accounts to the sub identifier used within the enterprise context for SSO.
The MCP Client makes an access token request to the MCP Server's authorization server using the previously obtained Identity Assertion Authorization Grant as a JWT Assertion as defined by RFC7523.
| Parameter | Required/Optional | Description | Example/Allowed Values |
|---|---|---|---|
grant_type |
REQUIRED | MUST be urn:ietf:params:oauth:grant-type:jwt-bearer |
urn:ietf:params:oauth:grant-type:jwt-bearerSection 4.1 of RFC7523 |
assertion |
REQUIRED | The Identity Assertion JWT Authorization Grant obtained in the previous token exchange step | (JWT string) |
The MCP Client authenticates with its credentials as registered with the MCP Server's authorization server.
If the MCP Client has not yet registered with the MCP Server's authorization server, then it can do a Dynamic Client Registration request at this stage.
An example request may look like this:
POST /oauth2/token HTTP/1.1
Host: auth.chat.example
Authorization: Basic yZS1yYW5kb20tc2VjcmV0v3JOkF0XG5Qx2
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
assertion=eyJhbGciOiJIUzI1NiIsI...
All of Section 5.2 of RFC7521 applies, in addition to the following processing rules:
- Validate the JWT
typisoauth-id-jag+jwt(per RFC8725) - The
audclaim of the assertion JWT MUST identify the Issuer URL of the MCP Server's authorization server as the intended audience of the JWT. - The
client_idclaim of the assertion JWT MUST identify the same client as the client authentication in the request (e.g., theclient_idspecified in a basic auth header).
The MCP Server's authorization server responds with an OAuth 2.0 Token Response, like this:
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
{
"token_type": "Bearer",
"access_token": "2YotnFZFEjr1zCsicMWpAA",
"expires_in": 86400,
"scope": "chat.read chat.history"
}
In most enterprise deployments, the IdP policy will only allow users to sign in to pre-registered clients. The MCP client will likely need to be pre-registered with the enterprise IdP for single sign-on.
It is also assumed that the MCP client will be pre-registered with the MCP server's authorization server.
In order for the IdP to include the correct client_id in the ID-JAG (described in Section 4.3), the IdP will need to be aware of the MCP Client's client_id that it normally uses with the MCP Server. This mapping happens outside of the protocol, such as during the configuration of the feature in the IdP.
This specification enables the enterprise IdP to be part of the issuance of the access token at the MCP Server. The visibility the IdP has between the MCP Client and MCP Server is limited to the process of issuing the access token, but does not extend to the actual API calls between the MCP Client and Server.
This enables the enterprise IdP to enforce policies such as which users in the organization can use certain MCP clients with certain MCP servers. Depending on the granularity of the OAuth scopes defined at the MCP server, this can also extend to govern which scopes a given user can request.
For example, the enterprise policy of granting an access token through this extension may allow users in the "engineering" group to get read-only access from an AI code editor to the source control MCP server, whereas users in the "marketing" group may be able to get read and write access to the internal documentation application.
In the MCP context, scopes often translate to agentic capabilities with significant impact. The IdP and MCP Authorization Server SHOULD treat requested scopes as a risk-weighted inventory of possible agent actions:
- The IdP SHOULD apply stricter validation or step-up authentication for high-impact scopes (e.g., scopes enabling destructive operations, administrative functions, or access to sensitive data).
- The IdP SHOULD validate that requested scopes are consistent with the user's role, the client's authorized capabilities, and enterprise policy, issuing tokens with only the intersection of these permissions (least privilege principle).
- The MCP Authorization Server MUST validate that the scopes in the ID-JAG are a subset of or equal to the scopes requested in the access token request, and issue access tokens with scopes that are the intersection of the requested scopes and the scopes present in the ID-JAG.
- Deployments SHOULD consider implementing scope versioning or tool snapshot tracking to detect when a scope's definition changes to include new, high-risk tools, and SHOULD require re-authorization in such cases.
All protocol exchanges that carry credentials, authorization codes, ID tokens, ID-JAGs, or access tokens MUST be protected in transit using TLS.
- Implementations MUST use
httpsURLs for authorization endpoints, token endpoints, and any metadata or key-discovery endpoints. - Parties MUST validate the peer's TLS certificate according to normal Web PKI rules.
- Clients, the IdP, and the MCP Authorization Server MUST NOT transmit secrets, assertions, or tokens over insecure channels.
- Implementations MUST NOT place ID-JAGs or access tokens in URLs (for example, query parameters) where they may be leaked via referrers, browser history, intermediaries, or logs.
The ID-JAG is an assertion and is subject to the threats described in RFC 7521, Section 8.
To mitigate forged assertions, the MCP Authorization Server MUST validate the ID-JAG as a signed JWT:
- The MCP Authorization Server MUST verify the JWS signature using a trusted key for the issuing IdP (or other designated issuer of the ID-JAG).
- The MCP Authorization Server MUST restrict accepted signature algorithms to an explicit allow-list and MUST NOT accept
alg: none. - The MCP Authorization Server MUST validate JWT claims including issuer (
iss), audience (aud), subject (sub), and time bounds (iat,exp) according to this specification. - The MCP Authorization Server MUST reject ID-JAGs with an
audthat does not identify the intended MCP Authorization Server (or the applicable audience as defined by this profile).
If the MCP Authorization Server retrieves public keys (for example, via a JWKS), it MUST do so over authenticated TLS and MUST handle key rotation safely (for example, using kid while preventing downgrade or rollback to untrusted keys).
An ID-JAG is a bearer artifact unless additional sender-constraining is applied. If an attacker obtains an ID-JAG, they may replay it until expiration.
- ID-JAGs MUST be short-lived (via
exp) and MUST be rejected outside their validity window (accounting for minimal clock skew). - The MCP Authorization Server MUST validate
jtiwhen present and MUST implement replay detection by rejecting re-use of the samejtifor the lifetime of the assertion (at minimum untilexp), scoped appropriately (for example, byissandsub). As noted in RFC 7523, replay protection is optional in the general JWT bearer grant framework, but it is REQUIRED in this profile due to the high-impact nature of MCP tool invocations. - Clients and servers MUST NOT log full ID-JAGs and MUST treat them as sensitive credentials.
Assertions can leak personal data if they include unnecessary claims or are mishandled.
- The ID-JAG SHOULD minimize included claims to only what is required for authorization decisions.
- Personally identifying information, such as email addresses, SHOULD NOT be included unless strictly necessary for a defined purpose and covered by enterprise policy and user expectations.
- If personally identifying information is included, it MUST be treated as sensitive: protect it in transit, avoid logging, and apply access controls to any stored copies.
- As noted in RFC 7521, Section 3, an assertion MAY additionally be encrypted to prevent unauthorized parties (such as the client) from inspecting privacy-sensitive content. If encryption is used, the ID-JAG MUST be encrypted to the MCP Authorization Server.
Where client authentication is used (for example, between the MCP Client and the MCP Server Server, and between the IdP and the MCP Authorization Server), implementations MUST protect client credentials:
- Client secrets MUST be stored securely and MUST NOT be embedded in distributed native applications or shipped to untrusted environments.
- Token endpoints SHOULD apply rate limiting and monitoring to mitigate credential-guessing and brute-force attacks.
- Implementations SHOULD support credential rotation and revocation.
- For enterprise scenarios involving high-impact MCP tool invocations, deployments SHOULD use strong client authentication methods such as
private_key_jwtor Mutual TLS rather thanclient_secret_basicorclient_secret_postto cryptographically bind the request to the client's identity and reduce the risk of credential theft.
Where a browser-based authorization request is used during single sign-on, clients SHOULD use CSRF protections:
- Authorization requests SHOULD include a
statevalue and the client MUST validate that the returnedstatematches the one it issued before processing the response. - Where applicable, implementations SHOULD use and validate a
nonceto bind the authentication response to the initiating session.
If the flow uses authorization codes to obtain ID tokens or other artifacts:
- Authorization codes MUST be treated as sensitive and exchanged only over TLS.
- Authorization servers MUST require exact redirect URI matching against pre-registered redirect URIs to mitigate redirection-based attacks (including open redirectors).
- Clients SHOULD use PKCE where applicable, especially for public clients, to reduce authorization code interception risk.
- Implementations SHOULD be aware of the security risks described with localhost redirect URIs and SHOULD apply additional validation for localhost-only redirect URIs, such as requiring additional attestation mechanisms or displaying clear warnings to users.
Access tokens issued by the MCP Authorization Server are bearer tokens unless otherwise specified.
- Clients MUST protect access tokens and ID-JAGs and MUST NOT leak them via logs, URLs, referrers, or to third-party origins.
- Clients SHOULD store tokens and ID-JAGs securely using platform-specific secure storage mechanisms (e.g., Keychain on macOS/iOS, Credential Manager on Windows, encrypted storage on Linux).
- MCP Servers MUST validate access tokens according to their token format and policy (including signature verification for JWTs, and audience restrictions where applicable).
- MCP Servers MAY use token introspection (RFC 7662) to validate access tokens, especially for opaque tokens or when real-time revocation checks are required.
- If refresh tokens are issued by an implementation, they MUST be treated as high-value credentials and protected accordingly (secure storage, rotation, revocation, and replay resistance as appropriate).
- Deployments SHOULD implement token revocation mechanisms (RFC 7009) and SHOULD provide incident response procedures for revoking tokens upon suspected compromise.
The ID-JAG contains both an aud claim (identifying the MCP Server's Authorization Server) and a resource claim (identifying the MCP Server itself). These two values MUST be treated as a bound pair to prevent cross-server token confusion attacks.
Threat Example: An attacker who obtains an ID-JAG intended for MCP Server B could attempt to present it to MCP Server A's Authorization Server. If Server A does not validate that the resource claim matches its own Resource Identifier, and if scope namespaces overlap between the two servers, the attacker may gain unauthorized access to Server A.
The IdP MUST maintain a mapping of valid (audience, resource) pairs and MUST validate that the audience and resource parameters in the token exchange request represent a valid and authorized pairing according to enterprise policy.
- The IdP MUST reject token exchange requests where the
audiencedoes not correspond to the authorization server for the specifiedresource. The mentioned validation prevents the IdP from issuing an ID-JAG with confused or mismatchedaudandresourceclaims.
The MCP Authorization Server MUST validate both the aud and resource claims in the ID-JAG:
- The MCP Authorization Server MUST validate that the
audclaim matches its own Issuer URL. - The MCP Authorization Server MUST validate that the
resourceclaim matches its own registered Resource Identifiers (MCP Servers). - If specified, the MCP Authorization Server SHOULD validate that the
scopeclaim matches its own registered scopes for the specifiedresource
If either the aud, resource or scope claim does not match the expected values, the MCP Authorization Server MUST reject the request with an invalid_grant error.
- Deployments SHOULD use globally unique and unambiguous Resource Identifiers to minimize the risk of identifier collision.
- Scope namespaces SHOULD be designed to be server-specific where possible, or prefixed or namespaced to reduce cross-server collision risk.
The use of OAuth 2.0 Token Exchange (RFC 8693) to obtain an ID-JAG introduces specific risks related to delegation and impersonation in the MCP context.
- Abuse of Delegated Rights: Any time a principal is delegated the rights of another, the potential for abuse increases. Implementations SHOULD mitigate this by using the
scopeparameter to restrict the contexts in which delegated rights can be exercised. - Scope-to-Tool Mapping: In the MCP context, scopes often grant autonomous agentic capabilities. The IdP and MCP Authorization Server SHOULD treat requested scopes as a risk-weighted inventory of possible actions and apply stricter validation or step-up authentication for high-impact scopes.
- Compromised Token Leverage: Omitting client authentication during the token exchange request allows a compromised subject token to be leveraged by any party to obtain an ID-JAG. Therefore, client authentication MUST be enforced.
In accordance with RFC 8693, Section 6, tokens employed in this profile may contain privacy-sensitive information.
- Data Minimization: Deployments SHOULD determine the minimally necessary amount of data and only include such information in issued ID-JAGs or access tokens.
- Encryption to Recipient: In cases where it is desirable to prevent the MCP Client from viewing privacy-sensitive claims intended for the MCP Server, the ID-JAG MUST be encrypted to the MCP Authorization Server.
- Encrypted Channels: All tokens and assertions MUST only be transmitted over encrypted channels (TLS) to prevent disclosure to unintended parties.