Align Enterprise-Managed Authorization with id-jag-04
Reduce duplication by referencing draft-ietf-oauth-identity-assertion-authz-grant-04 for roles, token exchange parameters, ID-JAG claims, and processing rules, keeping only MCP-specific constraints inline. - Adopt 'Resource Authorization Server' terminology from id-jag §2 - Replace parameter/claim tables with section references plus MCP deltas - Keep `resource` REQUIRED in this profile (id-jag-04 made it optional) - Drop the restriction on `actor_token` (removed upstream in -03) - Replace multi-tenant implementation notes with reference to id-jag §6 - Reference id-jag §5 for cross-domain client_id handling - Add Discovery section referencing `authorization_grant_profiles_supported`
This commit is contained in:
parent
030b7382ea
commit
67ffc6c02d
1 changed files with 38 additions and 92 deletions
|
|
@ -8,11 +8,11 @@ title: Enterprise-Managed Authorization
|
|||
|
||||
### 1.1 Purpose and Scope
|
||||
|
||||
This document defines an application of the "[Identity Assertion Authorization Grant](https://datatracker.ietf.org/doc/draft-ietf-oauth-identity-assertion-authz-grant/)" for use within enterprise deployments of the Model Context Protocol (MCP).
|
||||
This document defines an application of the "[Identity Assertion JWT Authorization Grant](https://datatracker.ietf.org/doc/draft-ietf-oauth-identity-assertion-authz-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 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, and how that authorization server validates the request 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:
|
||||
|
||||
|
|
@ -22,20 +22,18 @@ This profile is designed to facilitate secure and interoperable authorization wi
|
|||
|
||||
### 1.2 Roles and Terminology
|
||||
|
||||
- **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](https://openid.net/specs/openid-connect-core-1_0.html#IDToken).
|
||||
- **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](https://datatracker.ietf.org/doc/html/rfc7523#section-2.1).
|
||||
This document uses the roles and terms defined in [Section 2 of draft-ietf-oauth-identity-assertion-authz-grant](https://www.ietf.org/archive/id/draft-ietf-oauth-identity-assertion-authz-grant-04.html#section-2). In the context of this profile:
|
||||
|
||||
- The **Client** is the MCP Client.
|
||||
- The **Resource Server** is the MCP Server.
|
||||
- The **Resource Authorization Server** is the authorization server that issues access tokens for the MCP Server, as advertised in the MCP Server's Protected Resource Metadata ([RFC9728](https://datatracker.ietf.org/doc/html/rfc9728)).
|
||||
- The **IdP Authorization Server (IdP)** is the enterprise Identity Provider used for single sign-on.
|
||||
|
||||
## 2. Identity Assertion Authorization Grant Overview
|
||||
|
||||
This profile is an application of the "Identity Assertion Authorization Grant" [draft-ietf-oauth-identity-assertion-authz-grant](https://datatracker.ietf.org/doc/draft-ietf-oauth-identity-assertion-authz-grant/), which itself is a profile of "Identity and Authorization Chaining Across Domains" [draft-ietf-oauth-identity-chaining](https://datatracker.ietf.org/doc/draft-ietf-oauth-identity-chaining/).
|
||||
This profile is an application of the "Identity Assertion JWT Authorization Grant" [draft-ietf-oauth-identity-assertion-authz-grant](https://datatracker.ietf.org/doc/draft-ietf-oauth-identity-assertion-authz-grant/), which itself is a profile of "Identity Chaining Across Trust Domains" [draft-ietf-oauth-identity-chaining](https://datatracker.ietf.org/doc/draft-ietf-oauth-identity-chaining/).
|
||||
|
||||
The Identity Assertion Authorization Grant follows three steps:
|
||||
The Identity Assertion JWT Authorization Grant follows three steps:
|
||||
|
||||
1. Single Sign-On to the MCP Client via OpenID Connect or SAML
|
||||
2. Token Exchange ([RFC8693](https://datatracker.ietf.org/doc/html/rfc8693))
|
||||
|
|
@ -45,8 +43,8 @@ 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](https://datatracker.ietf.org/doc/html/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](https://datatracker.ietf.org/doc/html/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 Identity Assertion JWT Authorization Grant as a JWT Authorization Grant [[RFC7523](https://datatracker.ietf.org/doc/html/rfc7523)] to request an access token from the Resource Authorization Server.
|
||||
- The Resource Authorization Server validates the Identity Assertion JWT Authorization Grant and, if valid, issues an access token.
|
||||
- The MCP Client uses the access token to make requests to the MCP Server.
|
||||
|
||||
### 2.1 Sequence Diagram
|
||||
|
|
@ -98,7 +96,7 @@ Location: https://acme.idp.example/authorize?response_type=code&scope=openid&cli
|
|||
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 Client makes a request to the Authorization Server and, if valid, receives the tokens in the response:
|
||||
For example, in an OpenID Connect flow, after receiving a redirect from the IdP with an authorization code, the MCP Client makes a request to the IdP's token endpoint and, if valid, receives the tokens in the response:
|
||||
|
||||
```
|
||||
POST /token HTTP/1.1
|
||||
|
|
@ -121,18 +119,12 @@ Content-Type: application/json
|
|||
|
||||
## 4. Token Exchange
|
||||
|
||||
To request a JWT Assertion Grant, the MCP Client **MUST** make a Token Exchange ([RFC8693](https://datatracker.ietf.org/doc/html/rfc8693)) request to the IdP's Token Endpoint with the following parameters:
|
||||
To request an ID-JAG, the MCP Client makes a Token Exchange request to the IdP's token endpoint as defined in [Section 4.3 of draft-ietf-oauth-identity-assertion-authz-grant](https://www.ietf.org/archive/id/draft-ietf-oauth-identity-assertion-authz-grant-04.html#section-4.3).
|
||||
|
||||
| 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 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](https://datatracker.ietf.org/doc/html/rfc8693#section-3). | `urn:ietf:params:oauth:token-type:id_token` (OIDC)<br/>`urn:ietf:params:oauth:token-type:saml2` (SAML) |
|
||||
In this profile:
|
||||
|
||||
Additional parameters defined in [Section 2.1 of RFC8693](https://datatracker.ietf.org/doc/html/rfc8693#name-request) (`actor_token` and `actor_token_type`) are not used in this specification.
|
||||
- `audience` **MUST** be the issuer identifier of the Resource Authorization Server.
|
||||
- `resource` is **REQUIRED** and **MUST** be the Resource Identifier of the MCP Server as defined in [RFC9728](https://datatracker.ietf.org/doc/html/rfc9728).
|
||||
|
||||
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.
|
||||
|
||||
|
|
@ -156,15 +148,11 @@ grant_type=urn:ietf:params:oauth:grant-type:token-exchange
|
|||
|
||||
### 4.1 Processing Rules
|
||||
|
||||
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.
|
||||
The IdP processes the request according to [Section 4.3.3 of draft-ietf-oauth-identity-assertion-authz-grant](https://www.ietf.org/archive/id/draft-ietf-oauth-identity-assertion-authz-grant-04.html#section-4.3.3). 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.
|
||||
|
||||
### 4.2 Token Exchange Response
|
||||
|
||||
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](https://datatracker.ietf.org/doc/html/rfc8693#section-2.2):
|
||||
If access is granted, the IdP returns the ID-JAG in a token exchange response as defined in [Section 4.3.4 of draft-ietf-oauth-identity-assertion-authz-grant](https://www.ietf.org/archive/id/draft-ietf-oauth-identity-assertion-authz-grant-04.html#section-4.3.4):
|
||||
|
||||
```
|
||||
HTTP/1.1 200 OK
|
||||
|
|
@ -181,46 +169,13 @@ Pragma: no-cache
|
|||
}
|
||||
```
|
||||
|
||||
| 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 access 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` |
|
||||
|
||||
#### 4.2.1 Error Response
|
||||
|
||||
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](https://datatracker.ietf.org/doc/html/rfc6749#section-5.2). 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"
|
||||
}
|
||||
```
|
||||
Error responses are returned as OAuth 2.0 Token Error responses per [Section 5.2 of RFC6749](https://datatracker.ietf.org/doc/html/rfc6749#section-5.2).
|
||||
|
||||
### 4.3 Identity Assertion JWT Authorization Grant
|
||||
|
||||
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:
|
||||
The ID-JAG is a JWT issued and signed by the IdP with the claims defined in [Section 3.1 of draft-ietf-oauth-identity-assertion-authz-grant](https://www.ietf.org/archive/id/draft-ietf-oauth-identity-assertion-authz-grant-04.html#section-3.1).
|
||||
|
||||
| Parameter | Required/Optional | Description | Reference / Example |
|
||||
| ----------- | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
|
||||
| `iss` | REQUIRED | The IdP issuer URL. | [Section 4.1.1 of RFC7519](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.1) |
|
||||
| `sub` | REQUIRED | The subject identifier (e.g., user ID) of the user at the MCP Server. | [Section 4.1.2 of RFC7519](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.2) |
|
||||
| `aud` | REQUIRED | The Issuer URL of the Authorization Server. | [Section 4.1.3 of RFC7519](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.3) |
|
||||
| `resource` | REQUIRED | The Resource Identifier of the MCP Server. | [Section 1.2 of RFC9728](https://datatracker.ietf.org/doc/html/rfc9728#section-1.2) |
|
||||
| `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](https://datatracker.ietf.org/doc/html/rfc8693#section-4.3) |
|
||||
| `jti` | REQUIRED | Unique ID of this JWT. | [Section 4.1.7 of RFC7519](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.7) |
|
||||
| `exp` | REQUIRED | Expiration time of this JWT (Unix timestamp in seconds). | [Section 4.1.4 of RFC7519](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.4) |
|
||||
| `iat` | REQUIRED | Issued-at time of this JWT (Unix timestamp in seconds). | [Section 4.1.6 of RFC7519](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.6) |
|
||||
| `scope` | OPTIONAL | A JSON string containing a space-separated list of scopes associated with the token, per Section 3.3 of RFC6749. | `["scope1 scope2"]`<br/>[Section 3.3 of RFC6749](https://datatracker.ietf.org/doc/html/rfc6749#section-3.3) |
|
||||
|
||||
The `typ` claim of the JWT indicated in the JWT header **MUST** be `oauth-id-jag+jwt`.
|
||||
In this profile, the `resource` claim is **REQUIRED** and **MUST** contain the Resource Identifier of the MCP Server.
|
||||
|
||||
An example JWT shown with expanded header and payload claims may look like this:
|
||||
|
||||
|
|
@ -244,26 +199,15 @@ An example JWT shown with expanded header and payload claims may look like this:
|
|||
signature
|
||||
```
|
||||
|
||||
The IdP **MAY** add additional claims as necessary.
|
||||
|
||||
#### Implementation notes
|
||||
|
||||
If the IdP is multi-tenant and uses the same issuer for all tenants, the Authorization 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 Authorization 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 Authorization Server to properly link existing user accounts to the `sub` identifier used within the enterprise context for SSO.
|
||||
See [Section 6 of draft-ietf-oauth-identity-assertion-authz-grant](https://www.ietf.org/archive/id/draft-ietf-oauth-identity-assertion-authz-grant-04.html#section-6) for handling of multi-tenant issuers and subject identifier uniqueness.
|
||||
|
||||
## 5. Access Token Request
|
||||
|
||||
The MCP Client makes an access token request to the Authorization Server using the previously obtained Identity Assertion Authorization Grant as a JWT Assertion as defined by [RFC7523](https://datatracker.ietf.org/doc/html/rfc7523).
|
||||
The MCP Client presents the ID-JAG to the Resource Authorization Server's token endpoint as defined in [Section 4.4 of draft-ietf-oauth-identity-assertion-authz-grant](https://www.ietf.org/archive/id/draft-ietf-oauth-identity-assertion-authz-grant-04.html#section-4.4), using `grant_type` `urn:ietf:params:oauth:grant-type:jwt-bearer` and the ID-JAG as the `assertion`.
|
||||
|
||||
| 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-bearer`<br/>[Section 4.1 of RFC7523](https://datatracker.ietf.org/doc/html/rfc7523#section-4.1) |
|
||||
| `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 Resource Authorization Server.
|
||||
|
||||
The MCP Client authenticates with its credentials as registered with the Authorization Server.
|
||||
|
||||
If the MCP Client has not yet registered with the Authorization Server, then it can do a [Dynamic Client Registration](/specification/draft/basic/authorization#dynamic-client-registration) request at this stage.
|
||||
If the MCP Client has not yet registered with the Resource Authorization Server, then it can do a [Dynamic Client Registration](/specification/draft/basic/authorization#dynamic-client-registration) request at this stage.
|
||||
|
||||
An example request may look like this:
|
||||
|
||||
|
|
@ -278,15 +222,13 @@ assertion=eyJhbGciOiJIUzI1NiIsI...
|
|||
|
||||
### 5.1 Processing Rules
|
||||
|
||||
All of [Section 5.2 of RFC7521](https://datatracker.ietf.org/doc/html/rfc7521#section-5.2) applies, in addition to the following processing rules:
|
||||
The Resource Authorization Server processes the request according to [Section 4.4.1 of draft-ietf-oauth-identity-assertion-authz-grant](https://www.ietf.org/archive/id/draft-ietf-oauth-identity-assertion-authz-grant-04.html#section-4.4.1).
|
||||
|
||||
- Validate the JWT `typ` is `oauth-id-jag+jwt` (per [RFC8725](https://datatracker.ietf.org/doc/html/rfc8725))
|
||||
- The `aud` claim of the assertion JWT **MUST** identify the Issuer URL of the Authorization Server as the intended audience of the JWT.
|
||||
- The `client_id` claim of the assertion JWT **MUST** identify the same client as the client authentication in the request (e.g., the `client_id` specified in a basic auth header).
|
||||
In this profile, the issued access token **MUST** be audience-restricted to the MCP Server identified by the `resource` claim in the ID-JAG.
|
||||
|
||||
### 5.2 Access Token Response
|
||||
|
||||
The Authorization Server responds with an OAuth 2.0 Token Response, like this:
|
||||
The Resource Authorization Server responds with an OAuth 2.0 Token Response, like this:
|
||||
|
||||
```
|
||||
HTTP/1.1 200 OK
|
||||
|
|
@ -301,17 +243,21 @@ Cache-Control: no-store
|
|||
}
|
||||
```
|
||||
|
||||
## 6. Security Considerations
|
||||
## 6. Discovery
|
||||
|
||||
### 6.1 Client Registration
|
||||
An MCP Client can determine that a Resource Authorization Server supports this profile by checking for `urn:ietf:params:oauth:grant-profile:id-jag` in the `authorization_grant_profiles_supported` field of the server's authorization server metadata, as defined in [Section 7.2 of draft-ietf-oauth-identity-assertion-authz-grant](https://www.ietf.org/archive/id/draft-ietf-oauth-identity-assertion-authz-grant-04.html#section-7.2).
|
||||
|
||||
## 7. Security Considerations
|
||||
|
||||
### 7.1 Client Registration
|
||||
|
||||
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 Authorization Server.
|
||||
It is also assumed that the MCP client will be pre-registered with the Resource 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.
|
||||
See [Section 5 of draft-ietf-oauth-identity-assertion-authz-grant](https://www.ietf.org/archive/id/draft-ietf-oauth-identity-assertion-authz-grant-04.html#section-5) for how the IdP determines the `client_id` value to include in the ID-JAG.
|
||||
|
||||
### 6.2 Scope of Enterprise Visibility and Policy Enforcement
|
||||
### 7.2 Scope of Enterprise Visibility and Policy Enforcement
|
||||
|
||||
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.
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue