Skip to content
datarekha
MLOps Hard Asked at MicrosoftAsked at AnthropicAsked at Google

Why is OAuth token passthrough dangerous in an MCP server?

The short answer

In a normal MCP deployment, blindly forwarding the client’s bearer token to a downstream API violates the token’s audience boundary and can create confused-deputy, replay, and audit risks. The server should validate a token intended for itself, authorize the tool call, and obtain a separate, narrowly scoped credential for the downstream resource.

How to think about it

Short answer

In a normal MCP deployment, token passthrough is dangerous and should not be used: it forwards a bearer access token issued for the MCP server to a different downstream resource. The downstream API either rejects the wrong audience or accepts authority it was never meant to receive, creating confused-deputy, replay, and audit problems.

Why the boundary matters

A bearer token is a credential whose authority belongs to whoever possesses it. An OAuth audience is the resource the token was issued to, usually represented by an aud claim in a JWT or by an equivalent value from token introspection. A scope is a permission label such as invoice:read.

Those three details work together. The issuer says which authorization server made the decision. The audience says which service may rely on it. The scope says what that service may do.

A token for an MCP server is therefore not a general-purpose pass to every API that trusts the same identity provider. The scope read is not globally meaningful. read for a document service and read for a payroll service are different permissions, even if the spelling is identical.

OAuth token passthrough breaks this separation. The MCP server receives a token intended for itself, then copies the Authorization header to an upstream API. That upstream API now has to decide whether to trust a credential that was not issued for it.

There are two outcomes:

  • A correctly configured downstream API rejects the request because the audience is wrong. The usual symptom is 401 Unauthorized with an error such as invalid_token or an audience mismatch.
  • A permissively configured downstream API accepts the token because it validates only the issuer, signature, or a broad scope. The token now works outside its intended boundary.

The second outcome is the dangerous one. It turns a resource-specific credential into a reusable relay credential. It also makes incident response harder: the downstream service may see the end user as the caller, but not the MCP tool, server policy, or exact authorization decision that caused the request.

A confused deputy is a privileged service tricked into using its authority on behalf of a less-privileged caller. Passthrough can create or amplify that problem when the MCP server routes requests, selects tools, or falls back to its own downstream credentials. The client may be allowed to call lookup_invoice, while the server can reach much more powerful ERP operations. If the server forwards or substitutes credentials without making a separate authorization decision, the boundary is mostly decorative.

A concrete example

Suppose Alice uses a desktop MCP client to call a finance server. The identity provider issues this token:

ClaimValue
Issuerhttps://id.acme.example
SubjectAlice
Audiencehttps://finance-mcp.acme.example
Scopeinvoice:read
Lifetime10 minutes

The finance MCP server exposes a lookup_invoice tool, but it gets invoice data from an ERP API. The ERP expects a token with this relationship:

ClaimRequired value
Audiencehttps://erp.acme.example
Scopeinvoice:read

The bad request path is:

Alice's client -- T_mcp --> Finance MCP -- T_mcp --> ERP

T_mcp is intended for the finance MCP server, not the ERP.

If the ERP validates its audience, it returns a 401 response. A team under delivery pressure may “fix” that by allowing both audiences or disabling the audience check. The request then succeeds, but the security model has changed: a token minted for the MCP server is now accepted by the ERP.

The correct path uses a distinct credential:

Alice's client -- T_mcp --> Finance MCP
Finance MCP -- authorization decision --> Identity provider
Identity provider -- T_erp --> Finance MCP
Finance MCP -- T_erp --> ERP

T_erp is issued for the ERP audience and only the permissions needed for this operation. It might last five minutes rather than ten. It may represent Alice, the finance server, or both, depending on the delegation mechanism supported by the identity provider.

The important point is not that the token is a JWT, or that its scope has a particular spelling. The important point is that the ERP receives a credential created for the ERP relationship.

What the server should do instead

First, the MCP server should treat itself as a resource server. It validates the incoming token’s issuer, signature or introspection result, expiry, audience, and required scopes. It should also authorize the specific tool and arguments. A user allowed to read one tenant’s invoices should not gain access to another tenant merely because the tool accepts an arbitrary invoice identifier.

Next, the server establishes its own authorization relationship with the downstream service.

For app-only access, the server can authenticate as itself using a client-credentials-style flow. This gives the ERP the server’s identity, not Alice’s. The MCP server must then enforce Alice’s permissions before making the call; a service credential is not a substitute for user authorization.

For delegated access, the server can use token exchange or an on-behalf-of flow where the identity provider supports it. Token exchange means presenting the incoming authorization context to obtain a new token for a specified downstream audience and narrower scope. A capable provider can preserve the user and delegation chain so the ERP can distinguish “Alice through Finance MCP” from “Finance MCP acting alone.”

The server should never blindly copy the incoming Authorization header. It should also avoid putting either token in logs, traces, error messages, or tool results. Outbound destinations should be allowlisted. A fetch-like tool that accepts a user-controlled URL must not attach a bearer token to arbitrary hosts; otherwise one malicious URL can become a token-exfiltration endpoint.

The senior-level nuance

A separate token is not magic. The MCP server can still be a confused deputy if its tool authorization is too broad, its downstream scopes are excessive, or it lets the caller control sensitive parameters. Token exchange narrows the credential boundary; it does not decide whether Alice should be allowed to approve a payment.

There is also a legitimate architecture that looks superficially similar: a carefully designed gateway may receive a token explicitly issued for one downstream resource and relay it to that same resource. That is not ordinary MCP token passthrough. The gateway must be intentionally designed as that resource’s proxy, validate the token for the correct audience, restrict destinations, and define how user consent and audit attribution work. An MCP server that accepts a token for itself and forwards it elsewhere has a different trust model.

The trade-off is operational complexity. A separate downstream token may require an extra identity-provider call, credential rotation, and short-lived-token caching. Cache keys must include the user or service identity, tenant, audience, and scope. A token cached only by “MCP server” can accidentally grant one user’s authority to another.

A failure mode you can recognise

The first production symptom is often a sudden rise in downstream 401 responses labeled invalid_token or “audience mismatch.” Someone adds the MCP audience to the ERP’s accepted-audience list, and the errors disappear.

The next symptom may be worse: ERP audit logs show successful actions under sub=alice, but the security team cannot tell which MCP tool caused them. In a fetch or connector tool, a red-team request may even reveal the bearer token in a proxy log after the server sends it to an unexpected host.

That sequence is a useful diagnostic. Do not repair an audience failure by weakening audience validation. Issue the downstream credential correctly and inspect every place bearer tokens can be logged or forwarded.

What they’ll ask next

How should the MCP server preserve the user’s identity without forwarding the same token?

Use token exchange or an on-behalf-of mechanism that issues a new token for the downstream audience. Where supported, the resulting token can carry the user subject and delegation information. The downstream API then makes its own authorization decision and records both the user and the acting service.

Is a matching audience enough to make passthrough safe?

No. It removes one major problem, but the server still needs to authorize the tool call, constrain arguments, protect the token from replay, and ensure the token cannot be sent to another host. If the token was explicitly issued for the downstream resource and the MCP server is deliberately a gateway for that resource, passthrough may be part of that architecture. Blind forwarding is still not acceptable.

Why not use one powerful service token for every downstream call?

A service token simplifies plumbing but removes user-level least privilege. If stolen, it may expose every tenant and operation available to the service. Use the smallest downstream scope, enforce the caller’s permissions before the call, and use delegated tokens when the downstream system needs to know which user authorized the action.

Say this in the interview

OAuth token passthrough is dangerous because a token is audience-specific: an MCP server should validate the token issued for itself, make its own tool authorization decision, and obtain a separate least-privilege token for each downstream resource rather than forwarding the client’s bearer credential.

Learn it properly MCP tool poisoning & supply-chain security

Keep practising

All MLOps questions

Explore further