Skip to content

Downstream Authentication & Credential Delegation Guide ​

1. Overview ​

This guide describes how Model Context Gateway (MCG) authenticates to downstream Model Context Protocol (MCP) servers on behalf of callers.

The gateway decouples inbound ingress authentication (such as Active Directory, OIDC, or AppKeys) from outbound downstream delegation. After the gateway authorizes an incoming request, it selects a configured delegation pattern to invoke the target server.


2. Downstream Delegation Patterns ​

The gateway supports seven downstream delegation patterns:

Pattern 1: Trusted Gateway Pattern (Identity Header Propagation) ​

Use this pattern when backend microservices trust the gateway IP address and enforce internal authorization or Row-Level Security (RLS).

  • Outbound Transport: HTTP or SSE.
  • Injected Headers:
    • X-Forwarded-User: Username of the authenticated caller (such as steve or CORP\steve).
    • X-Forwarded-Groups: Comma-separated list of caller group memberships (such as Domain Users,DevOps,Engineering).
    • X-Mcp-Session-Id: Unique identifier for the client session.
  • Downstream Enforcement: The downstream service verifies the shared gateway token, trusts the forwarded headers, and applies internal data filters.

Pattern 2: RFC 8693 Downstream Token Exchange ​

Use this pattern in zero-trust architectures where backend microservices require user-delegated tokens scoped specifically to their audience.

  • Component: TokenExchangeClient.
  • How It Works:
    1. The gateway extracts the incoming user token from the request.
    2. The gateway calls the Identity Provider token endpoint using grant type:
      text
      urn:ietf:params:oauth:grant-type:token-exchange
    3. The IdP mints a short-lived downstream JWT scoped to the target server audience (SecretKey).
    4. The gateway caches the exchanged token in memory for its lifetime minus 60 seconds.
    5. The gateway attaches Authorization: Bearer <downstream_jwt> to the outbound call.

Pattern 3: Bring Your Own Key (BYOK / User-Provided Secrets) ​

Use this pattern when backend MCP servers require individual user tokens (such as personal GitHub Personal Access Tokens or Slack user tokens).

  • Configuration: Set SecretProvider to UserProvided in the server configuration.
  • Storage Providers:
    • Database (Encrypted Storage): Stored in SQLite/SQL encrypted with AES-256-GCM.
    • HashiCorp Vault (KV v2): Stored in Vault KV v2 using path templates (such as {Company}/mcgateway/{User}/{Server}).
  • User Self-Service: Users add, update, and remove personal credentials in the My MCP Servers dashboard tab.
  • Resolution: During tool execution, the gateway retrieves the caller's credentials and injects them into the outbound request.

Pattern 7: 3LO Egress OAuth & Per-User Delegation (Google Home & Connected Accounts) ​

Use this pattern when downstream tools require individual user authentication through standard OAuth 2.0 (such as Google Home, Google Workspace, GitHub, Slack, Jira, or Notion).

  • The Problem It Solves: Multi-user environments (such as household smart homes or enterprise teams) cannot safely share a single static bot token. Shared tokens cause context bleed, lack individual user permissions, and create security hazards.
  • Operator Configuration: Set EnableOAuth3Lo: true on the server. Enter the OAuth Client ID, Client Secret, Authorization URL, Token URL, and requested Scopes.
  • Out-of-Band User Consent: The user clicks Connect Account in the My MCP Servers dashboard. MCG generates a 256-bit random state token bound to the caller, redirects the browser to the provider consent page, and processes the authorization callback at /api/oauth/egress/callback.
  • Encrypted Per-User Vaulting: MCG exchanges the authorization code for { access_token, refresh_token, expires_at }. It encrypts the token bundle with AES-256-GCM in the user secret store (IUserSecretStore). Each user's tokens remain isolated from all other users.
  • Automated JIT Background Token Refresh: When an AI client invokes tools on the server:
    1. MCG extracts the user's encrypted token bundle from storage.
    2. If the token is near expiration (expires_at - 10s), MCG automatically uses the stored refresh_token to retrieve fresh tokens in the background.
    3. MCG updates the user secret store and injects Authorization: Bearer <access_token> into the outbound HTTP or SSE request.
    4. Outbound HTTP requests preserve target SNI authority (req.Headers.Host = req.RequestUri.Authority) to satisfy cloud TLS requirements.
  • Complete Specification: See the dedicated Per-User OAuth Delegation & Connected Accounts Flow Guide.

Pattern 4: Windows Kerberos Impersonation ​

Use this pattern on Windows Server and IIS deployments where downstream servers require the caller's Active Directory domain identity.

  • Operating System Requirement: Windows Server and IIS only. This mode does not run on Linux containers.
  • Configuration: Set AuthShape to impersonation. The UI automatically locks SecretProvider to None.
  • How It Works:
    1. The user authenticates to IIS with Negotiate or Kerberos.
    2. The gateway extracts the caller's WindowsIdentity.
    3. Outbound HTTP requests execute inside WindowsIdentity.RunImpersonated().
    4. Downstream servers receive the caller's Kerberos credentials through S4U2Proxy delegation.

Pattern 5: Pass-Through Dynamic JWTs ​

Use this pattern when clients obtain backend tokens directly and forward them through the gateway.

  • Configuration: Set AllowPassThroughAuth to true on the server configuration.
  • Routing Requirement: Requires target-specific proxy routes (/{serverId}). Not supported in universal meta-mode (/sse) because the client must target a specific backend.
  • How It Works:
    1. The client sends the backend token in the X-Target-Auth HTTP header.
    2. The gateway translates X-Target-Auth into the configured backend AuthShape (such as Authorization: Bearer <token>).

Pattern 6: Shared Service Account Credentials ​

Use this pattern when the gateway connects to shared infrastructure backends (such as Docker, Home Assistant, or Postgres).

  • Secret Providers:
    • HashiCorp Vault (KV v2): Reads credentials dynamically with JIT token renewal.
    • Windows Registry (DPAPI): Reads machine-encrypted values from HKLM hives.
    • Environment Variables: Reads values from host or container environment variables (ENV:VAR_NAME).
    • Encrypted Database: Reads static keys encrypted with AES-256-GCM.

3. Downstream Authentication Mixing Matrix & Guardrails ​

To prevent conflicting or invalid configurations, the gateway and UI enforce strict mixing rules:

Outbound Auth ModeSecret ProviderStatic API Key Allowed?Secret Key / Path Required?Valid TransportsEnforced Guardrail & Behavior
Kerberos Impersonation (impersonation)None (Locked)❌ No❌ Nosse, httpWindows-Only. Runs inside WindowsIdentity.RunImpersonated. External secret providers and static keys are disabled in the UI.
User-Provided (BYOK)UserProvided❌ No❌ Nosse, http, stdioStatic server API key is disabled. Credentials resolve dynamically per user from Database or HashiCorp Vault.
Token Exchange (TokenExchange)TokenExchange❌ No✅ Yes (Audience)sse, httpMints dynamic RFC 8693 downstream JWT asserting caller identity. Incompatible with Kerberos impersonation.
Static Shared SecretEnvironment, Vault, WindowsRegistry❌ No✅ Yessse, http, stdioShared service credentials fetched dynamically. The gateway manages TTL and caching.
Hardcoded API KeyNone✅ Yes❌ Nosse, http, stdioStored AES-256-GCM encrypted in the database. Simplest for single-tenant local servers.
Pass-Through JWT (AllowPassThroughAuth)(Any)OptionalOptionalsse, httpClient sends dynamic token in X-Target-Auth. Requires direct proxy route (/{serverId}).

4. Transport Injection Mechanics ​

The gateway formats resolved credentials based on the target transport type:

HTTP and SSE Transports (HttpTransport, SseTransport) ​

Credentials inject into HTTP request headers or URL query parameters according to AuthShape:

  • bearer: Injects Authorization: Bearer <token>.
  • custom-header: Injects <CustomHeaderName>: <token> (such as X-API-Key or X-Plex-Token).
  • basic: Formats username:password into Authorization: Basic <base64>.
  • query: Appends credentials to the URL query string (?token=<token>).
  • raw: Injects Authorization: <token>.

STDIO Local Subprocess Transport (StdioTransport) ​

For local script subprocesses (such as Node.js, Python, or shell tools):

  • The gateway never passes secrets in command-line arguments.
  • The gateway injects resolved credentials securely into process environment variables (such as API_KEY or TOKEN).
  • Subprocess arguments remain clean to prevent credential exposure in process monitoring tools (ps, top).

Released under the Apache 2.0 License.