Rightshold™ Sign up

Answers · MCP security

What is MCP's Enterprise-Managed Authorization extension (ID-JAG, also called Cross App Access or XAA)? How does it work, what does my MCP server or its authorization server have to do to support it, and should I?

Last updated

TL;DR: It's an optional MCP extension, io.modelcontextprotocol/enterprise-managed-authorization, that lets a company's identity provider (IdP) decide which employees may use which MCP clients with which MCP servers, instead of each employee clicking through an OAuth consent screen for every server. The employee signs in to the MCP client with company SSO. The client then trades that sign-in (an OpenID Connect ID token, or a refresh token obtained from a SAML assertion) at the IdP for a short-lived signed grant called an Identity Assertion JWT Authorization Grant (ID-JAG), using OAuth Token Exchange (RFC 8693). The IdP checks its admin policy before issuing it. The client presents the ID-JAG to your MCP server's authorization server as a JWT bearer grant (RFC 7523), and your authorization server validates it and issues an ordinary access token that must be audience-restricted to your MCP server. Okta markets this as Cross App Access (XAA); the MCP spec doesn't use that term. To support it, your authorization server has to accept the jwt-bearer grant, validate ID-JAGs from each customer's IdP (signature, issuer, audience, expiry, client and resource), map the subject to an account, and advertise urn:ietf:params:oauth:grant-profile:id-jag in its metadata. It's worth doing if you sell to companies that run workforce SSO, and premature if your users are mostly individuals. The underlying IETF draft isn't an RFC yet, client support varies, and extensions are opt-in and never on by default.

What should I check, step by step?

1. Decide whether your customers need it. The extension is written for MCP clients and servers that both sit behind an enterprise IdP. If most of your users sign in as individuals, the standard MCP OAuth flow stays your main path; the extension doesn't replace it.

  1. Check whether your authorization server already accepts ID-JAGs before building anything. The MCP extension page lists products with documented support, including Okta, Ping Identity (PingFederate 13.1 and later), Descope, Stytch, Athenz, ThunderID and AuthPlane, with Auth0, WorkOS AuthKit and Scalekit in early access and Keycloak experimental. It also names Cloudflare's workers-oauth-provider (experimental, 0.7.0 and later) and FastMCP 4.0 and later (beta).
  2. Accept the grant type urn:ietf:params:oauth:grant-type:jwt-bearer at your token endpoint, with the ID-JAG as the assertion, and authenticate the client with the credentials it registered with you. The extension says a client that isn't pre-registered can use its Client ID Metadata Document URL as its client_id.
  3. Validate every ID-JAG: the JWT's typ is oauth-id-jag+jwt, the signature verifies against the keys of an IdP you trust for that customer, iss is that IdP, aud is your authorization server's issuer identifier, exp hasn't passed, and client_id matches the client presenting it. If a resource claim is present it must be your MCP server's resource identifier.
  4. Issue access tokens audience-restricted to the MCP server named in the ID-JAG's resource claim; the extension makes that a MUST. Your MCP server still validates the audience of every token it receives.
  5. Trust IdPs per customer, not globally. An ID-JAG is only as trustworthy as the issuer you accept it from, and the IETF draft has a section on multi-tenant issuers and subject identifier uniqueness. Configure which issuer belongs to which customer organisation.
  6. Use the sub claim as the stable identifier for the user. The MCP extension page says email may also be present and suggests using it only to link pre-existing accounts created before enterprise-managed authorization was turned on.
  7. Map the ID-JAG's scope to your own permissions and refuse scopes the customer's policy didn't grant. Define scopes fine enough that an IdP admin can, for example, give one group read-only access and another read-write.
  8. Advertise support: add urn:ietf:params:oauth:grant-profile:id-jag to authorization_grant_profiles_supported in your authorization server metadata, which is how the extension says clients discover it.
  9. Keep a record of grants outside the token flow. The extension says the IdP sees only token issuance, not the MCP traffic itself, so log which client used which scopes on which server for whom, and keep offboarding at the IdP as the off switch.

How does MCP enterprise-managed authorization (ID-JAG) work step by step?

The extension, at protocol revision 2026-07-28, is an application of the IETF OAuth working group draft Identity Assertion JWT Authorization Grant, which is itself a profile of the Identity Chaining Across Trust Domains draft. It has three steps: single sign-on to the MCP client with OpenID Connect or SAML; a Token Exchange request (RFC 8693) to the IdP that names the MCP server's authorization server as the audience and returns an ID-JAG; and a JWT authorization grant (RFC 7523) at that authorization server, which returns an access token.

Does MCP enterprise-managed authorization let a company's IdP see or approve individual MCP tool calls?

The MCP extension page lists the benefits: employees use corporate SSO with no per-server consent prompts, the IdP keeps one place to decide which MCP servers are approved and for whom (group membership, roles, conditional access), and revoking an employee's access happens at the IdP for every MCP client at once instead of server by server. That stops new ID-JAGs; access tokens your authorization server has already issued are a separate matter, so keep them short-lived or revocable (the extension's example access token has an expires_in of 86,400 seconds, one day).

Is the ID-JAG / Cross App Access standard for MCP final, and which clients and identity providers support it?

The extension page says support varies by client and that extensions are opt-in and never active by default; it points to the MCP client matrix for current status. A server that requires the enterprise flow will turn away clients that haven't implemented it, so keep the standard MCP authorization flow available unless every customer's client supports it.

How do I ask Rightshold about this (free, no key)?

Add the MCP server https://www.rightshold.com/mcp to Claude, Cursor, ChatGPT, Grok or VS Code, then ask: “Our IdP now lets the engineering group use our coding agent with the source-control MCP server, read-only, until the end of the quarter. Record that grant so we can show who authorized it and whether it was in force on any given day.”

One-click setup

{
  "tool": "record_access_grant",
  "arguments": {
    "workspace_id": "<your operations workspace id>",
    "agent_label": "Coding agent (engineering group, via IdP policy)",
    "resource": "Source-control MCP server",
    "grantor": "Identity and access admin",
    "scope": "Read-only scopes as granted by the IdP policy; no write or admin tools.",
    "expires_at": "2026-12-31T23:59:59Z"
  }
}

Rightshold records access grants and reports what it has on record. It isn't an identity provider or an OAuth authorization server, doesn't issue or validate ID-JAGs, and isn't affiliated with the MCP project, the IETF or any vendor named here. Requirements are quoted from the MCP Enterprise-Managed Authorization extension (revision 2026-07-28) and the IETF draft as checked on November 10, 2026.

What are the sources?

Related

Not legal advice. JSON · Markdown · All answers

Get a free API key in one call

No card and no email needed. 100 free credits; the license and policy checks stay free without a key.

curl -s -X POST https://www.rightshold.com/v1/accounts/signup -H "Content-Type: application/json" -d '{"accept_terms":true}'
export RIGHTSHOLD_API_KEY=rs_...   # the api_key from the reply (shown once)
curl -s https://www.rightshold.com/v1/licenses/check -H "Authorization: Bearer $RIGHTSHOLD_API_KEY" \
  -H "Content-Type: application/json" -d '{"license":"MIT","intended_use":{"commercial_use":true}}'