Skip to content
AdminKit

The MCP confused-deputy problem and token passthrough, explained

A confused-deputy vulnerability happens when an MCP server with legitimate access to a third-party API can be tricked into misusing that access on an attacker's behalf, and the single most common way it happens in MCP deployments today is a server forwarding a client's access token straight through to a downstream API instead of validating and re-issuing its own.

By AdminKit team, Netbase JSC · Updated October 22, 2026

Why MCP servers are “deputies” in the first place

Most useful MCP servers aren’t the final destination for a request — they’re a middle layer that holds its own credentials for a real backend: a ticketing API, a cloud account, an internal database. In classic computer-security terms, that makes the MCP server a deputy: a program acting with delegated authority on someone else’s behalf. The MCP Authorization specification’s security considerations describe exactly this scenario, warning that “attackers can exploit MCP servers acting as intermediaries to third-party APIs, leading to confused deputy vulnerabilities.” A deputy becomes “confused” when it can no longer tell a legitimate instruction from an attacker’s, and ends up spending its own privileged access on the attacker’s behalf — the term predates MCP by decades, but the pattern is a near-perfect fit for how agent tool-calling servers are built today.

The specific failure: token passthrough

The spec names the concrete version of this problem that keeps showing up in real MCP deployments: token passthrough. It happens in two steps that each look reasonable in isolation:

  1. An MCP server accepts an access token from a client without strictly checking that the token’s audience claim actually names this server as the intended recipient.
  2. The server then forwards that same, unmodified token to a downstream or upstream API, rather than using its own credentials to call that API.

The spec is direct about why this is dangerous: “the downstream API may incorrectly trust the token as if it came from the MCP server or assume the token was validated by the upstream API.” The upstream has no way to distinguish a token that was properly checked from one that was just relayed, so a token obtained for one purpose — or stolen outright — can end up exercising access it was never meant to grant, with the MCP server as an unwitting accomplice.

Why this is easy to build by accident

Token passthrough isn’t usually a deliberate shortcut; it’s often the first working implementation. A developer wires up an MCP server, sees that the client already has a valid-looking OAuth token, and forwards it to the backend API because the backend API also happens to speak OAuth — it “just works” in testing, often with a single client and a single backend, which hides the problem entirely. The failure only becomes visible once a second client, a different authorization server, or an attacker-controlled token enters the picture, by which point the pattern is already baked into the server’s integration code.

The fix: validate audience, then re-issue your own credentials

The spec’s prescribed fix has two parts, and both are necessary:

  • Reject tokens that weren’t issued for you. Per the MCP Authorization specification, “MCP servers MUST only accept tokens specifically intended for themselves and MUST reject tokens that do not include them in the audience claim.” RFC 8707 (Resource Indicators for OAuth 2.0) defines the resource parameter MCP clients use to request an audience-bound token in the first place, so this check has something concrete to validate against.
  • Never forward the client’s token to an upstream API. If your MCP server needs to call a third-party service on the client’s behalf, it should hold its own, separately issued OAuth credentials for that call. The spec states this plainly: “The MCP server MUST NOT pass through the token it received from the MCP client.” The client’s token authenticates the client to your server; it was never meant to authenticate your server to someone else’s API.

Together these two rules mean every hop in the chain — client to MCP server, MCP server to upstream API — uses a token that was actually issued, and validated, for that specific hop.

The spec also flags a related failure mode for MCP servers that act as OAuth proxies in front of a third-party authorization server using a single, static client ID shared across all of their own users. In that setup, “attackers can exploit MCP servers acting as intermediaries to third-party APIs,” including by using stolen authorization codes to obtain access tokens without the real user’s consent. The mitigation is specific: MCP proxy servers using static client IDs must obtain user consent for each dynamically registered downstream client before forwarding to the third-party authorization server, not just once at initial setup.

Where this fits in the rest of your hardening work

Fixing audience validation and token passthrough is one specific control among several an MCP deployment needs — our guide to securing an MCP server covers the fuller checklist, including OAuth setup end-to-end, tool allowlists, and treating tool responses as untrusted input. If you’re routing MCP traffic through a reverse proxy or gateway as part of that hardening, confirm its TLS setup with SSL/TLS check and that the hostnames clients resolve actually point where you expect with DNS lookup — a confused-deputy fix doesn’t help if traffic is being intercepted or misrouted before it reaches your validation logic at all.

AdminKit’s planned MCP & Agent Gateway is designed to enforce audience-bound token validation and block passthrough centrally, so individual MCP server implementations don’t each have to get this right independently — it’s in early access and not live yet, so the validation logic above remains the practical fix today.

Other ways an MCP deployment gets tricked

Token passthrough confuses the server itself about whose authority it’s using. Three related but distinct failure modes confuse the agent, or the server acting on its behalf, instead: prompt injection, where text the agent reads (including a tool’s own response) carries hidden instructions; tool poisoning, where a tool’s description or metadata — not its actual function — is crafted to manipulate the agent before it ever calls the tool; and SSRF, where a tool that fetches a URL on the agent’s behalf gets steered toward an internal destination instead of the intended one. All four are worth checking for in the same hardening pass.

This guide is general information, not a security audit of your specific network — see our disclaimer for what AdminKit's guidance does and does not commit to.

Frequently asked questions

What is the confused deputy problem, in plain terms?

A 'deputy' is a program that has more privilege than the party asking it to act — here, an MCP server that holds credentials for a third-party API. The deputy is 'confused' when it can't tell a legitimate request from an attacker's, and ends up using its own privileged access to do something the attacker wasn't authorized to do.

Isn't passing a client's token straight through the simplest way to build an MCP server?

It's simple, which is exactly why it's common — but the MCP specification explicitly forbids it. If a server accepts a token it wasn't the intended audience for and then forwards that same token unmodified to an upstream API, the upstream has no reliable way to know the token didn't come from a trusted, already-validated source.

What does 'audience binding' actually fix?

An audience-bound token is only valid for the specific server it names as the recipient. If your MCP server checks that it is the named audience on every inbound token, a token stolen from, or issued for, a different service simply won't validate — closing off the exact path a token-passthrough bug leaves open.

Does this only matter for public-facing MCP servers?

No. An internal MCP server that proxies to internal-only APIs is still a deputy with real privilege, and an internal attacker — or a compromised client application — can exploit the same passthrough flaw. Treat token validation as mandatory regardless of whether the server is public or internal-only.

What's the one-line fix if I'm already doing this wrong?

Stop forwarding the client's token to the upstream API. Validate the inbound token's audience against your own server identity, then use your server's own, separately issued credentials — not the client's token — to call the upstream API on the client's behalf.

Want AdminKit to watch this for you?

Free checks tell you the state today. Protective DNS and monitoring tell you when it changes.