Skip to content

Delegated MCP authentication

Delegated MCP authentication lets a tool call execute with the caller’s upstream permissions without forwarding the caller credential to the MCP server. It is opt-in and applies only to OAuth-enabled Streamable HTTP MCP clients.

  • The MCP client uses Streamable HTTP and has an authorized OAuth configuration.
  • Its authorization server supports OAuth 2.0 Token Exchange.
  • The OAuth token endpoint and MCP resource use HTTPS. Loopback HTTP is allowed only for local development.
  • The caller supplies a short-lived subject access token no larger than 16 KiB. A non-empty value above that limit fails before token exchange and never falls back to the connection’s shared credential.

Local stdio, SSE-only, and non-OAuth clients reject delegation. Requests that do not carry a subject token continue to use the existing shared-client path.

  1. The caller sends its token to DeepIntShield in X-MCP-Subject-Token.
  2. DeepIntShield sends that token only to the configured OAuth token endpoint with the RFC 8693 token-exchange grant.
  3. The exchange includes the exact MCP server URL as the RFC 8707 resource.
  4. DeepIntShield initializes a Streamable HTTP MCP session with the exchanged bearer token.
  5. The session is isolated by MCP client, resource, and a one-way digest of the caller credential.
Terminal window
curl "$DEEPINTSHIELD_URL/v1/chat/completions" \
-H "Authorization: Bearer $DEEPINTSHIELD_VIRTUAL_KEY" \
-H "X-MCP-Subject-Token: $CALLER_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-5.6",
"messages": [{"role": "user", "content": "Use my project tools."}]
}'

The subject token is removed from generic request headers and provider extra-header maps, recorded as [REDACTED] in header audit data, never persisted, and never placed in an error message. It is not forwarded to the MCP server and does not replace existing agentic authorization headers.

When canonical GAF is enabled, authorization happens before the delegated session is acquired. The same exact-workspace decision used by /mcp, /v1/mcp/tool/execute, and autonomous execution must return Allow; a Deny, pending approval, workload-proof failure, or unavailable policy dependency never falls back to the connection’s shared OAuth credential.

X-MCP-Subject-Token does not populate the GAF user or delegation fields. The MCP authorization adapter treats the governed agent as the direct caller; the subject token is used only afterward to obtain the upstream resource-bound transport credential.

Token endpoint redirects are disabled. The exchanged token must be a supported bearer token and is retained only until it approaches expiry.

Each process holds a bounded pool of at most 1,024 delegated sessions. A cold caller identity performs token exchange plus MCP initialization. A warm caller avoids those network operations, but every acquisition first revalidates the durable OAuth status, exact resource, expected authentication type, immutable MCP client ID, configuration generation, and current MCP-to-OAuth binding before consulting the process-local pool. A protocol mismatch, revoke, reauthorization swap, or binding change therefore denies or evicts stale warm state. Different credentials or resources cannot share a session. Streamable HTTP session IDs returned by the MCP server remain bound to that isolated client session.

The implementation follows OAuth 2.0 Token Exchange (RFC 8693), OAuth 2.0 Resource Indicators (RFC 8707), and the MCP requirements for resource-bound authorization and Streamable HTTP sessions.

This release expects an explicitly configured exchange endpoint and session flow. It does not implement that revision’s automatic protected-resource metadata discovery or step-up/claims-challenge flow. Token exchange is also not available for stdio and legacy SSE transports.

SymptomCheck
Delegation rejected before exchangeConfirm OAuth is authorized and transport is Streamable HTTP.
Oversized subject token rejectedKeep X-MCP-Subject-Token at or below 16 KiB; larger non-empty values fail closed rather than using the shared credential.
Token exchange rejectedCheck subject-token type, client credentials, requested resource, scopes, and authorization-server policy.
Session repeatedly initializesCheck token lifetime, replica stickiness, and the 1,024-session process limit.
Tool sees the original caller tokenStop the request and inspect custom middleware; the built-in path never forwards it.

For standard non-delegated setup, see MCP OAuth 2.1 and OAuth 2.0 and Connecting to MCP servers.