Skip to content

Track support for the MCP Enterprise-Managed Authorization extension (ID-JAG) #18

@dbernheisel

Description

@dbernheisel

Tracking issue for the Enterprise-Managed Authorization auth extension for MCP, which adds a three-party token-exchange flow built on RFC 8693 / RFC 7523. This issue is for tracking the gap only — not proposing an implementation.

What this extension adds

A three-party authorization profile for MCP that lets enterprise IdPs (Okta, Entra ID, Ping, etc.) broker access between an MCP Client and an MCP Server's Authorization Server. End users get SSO-style access to MCP servers through their existing corporate identity, IT centrally controls which clients can talk to which servers, and per-server interactive consent is removed.

Key spec points:

  • New token type: urn:ietf:params:oauth:token-type:id-jag ("Identity Assertion JWT Authorization Grant"), JWT with typ header oauth-id-jag+jwt.
  • Grant type at the Authorization Server: urn:ietf:params:oauth:grant-type:jwt-bearer (RFC 7523).
  • Required ID-JAG claims: iss (IdP), sub (user), aud (Authorization Server issuer URL), resource (MCP server identifier per RFC 9728), client_id (MCP client registered at the Authorization Server), jti, exp, iat; optional scope.
  • Five-step flow:
    1. User authenticates to the MCP Client via enterprise SSO (OIDC or SAML), producing an ID Token.
    2. Client sends an RFC 8693 token-exchange request to the IdP: grant_type=urn:ietf:params:oauth:grant-type:token-exchange, requested_token_type=urn:ietf:params:oauth:token-type:id-jag, audience=<AS issuer>, resource=<MCP server>, subject_token=<ID Token>, subject_token_type.
    3. IdP validates, applies admin policy, returns a signed ID-JAG (recommended ~300s lifetime).
    4. Client posts a JWT bearer assertion to the Authorization Server with the ID-JAG as the assertion.
    5. Authorization Server validates typ, aud, and client_id, then issues a standard OAuth 2.0 access token to the client.
  • Authorization Server obligations: validate JWT typ/aud/client_id, pre-register MCP clients, issue normal OAuth 2.0 access tokens.
  • MCP Client obligations: acquire the ID-JAG via SSO + token exchange before talking to the MCP server; authenticate at the AS token endpoint.

Current state in Phantom

Phantom delegates all authentication to the application's c:Phantom.Router.connect/2 callback (lib/phantom/router.ex) and the README points users at Oidcc, Boruta, or ExOauth2Provider. Concretely:

  • No first-class recognition of the ID-JAG profile (oauth-id-jag+jwt, id-jag token type) at any layer — connect/2 receives raw headers and hands them off to user code.
  • No helpers or documented patterns for validating an access token that was issued in exchange for an ID-JAG (vs. one from interactive user OAuth).
  • No conventions for surfacing the resource identifier (RFC 9728) that the AS expects to see in the resource claim — relevant for Phantom.Plug's validate_origin / discovery story but not currently exposed.
  • No guidance for how connect/2 should map the resulting principal (enterprise user identity, plus org/policy attributes carried in the access token) onto allowed_tools / allowed_resource_templates for tenant-aware servers.
  • The c:Phantom.Router.connect/2 unauthorized return shape (Phantom.Plug.www_authenticate/1) doesn't have an idiomatic way to advertise that the protected resource expects ID-JAG-derived tokens vs. ordinary user-delegated ones.

Why this matters

Enterprise rollouts are the primary near-term commercial deployment path for MCP servers. Without first-class affordances for this extension, every Phantom user landing in an enterprise has to wire ID-JAG validation, the resource claim, and per-tenant policy mapping by hand on top of a generic OAuth library — and rediscover the same edge cases independently.

Out of scope for this issue

Design and implementation. This issue exists to make the gap visible and link to the spec.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions