Why is token audience binding required, and what happens if a server accepts tokens meant for a different service?

5 minadvancedmcpsecurityoauthtoken-audiencetoken-passthrough

Quick Answer

Token audience binding means an access token is issued for, and only valid against, a specific intended recipient (the aud claim in a JWT, or equivalent), and a resource server must verify that claim matches itself before accepting the token — rather than accepting any token that merely looks validly signed by a trusted issuer. Without this check, a token a user obtained to authenticate against Service A could be replayed against Service B (an MCP server) if B doesn't verify the token was actually meant for it, letting an attacker (or an overly permissive server) misuse a token far outside its intended scope — this is sometimes called a token passthrough vulnerability. MCP's authorization guidance requires servers to validate that any token presented was specifically issued for that server (per RFC 8707, Resource Indicators for OAuth 2.0), rejecting tokens whose audience doesn't match, precisely to prevent this class of cross-service token replay.

Detailed Answer

A validly-signed token isn't automatically a token you should accept. You also have to confirm it was actually issued for you.

What a bound token looks like

// Decoded JWT payload (illustrative)
{
  "sub": "user-42",
  "aud": "https://mcp.acme.com",
  "scope": "orders:read",
  "exp": 1730000000
}

The aud (audience) claim says this token is only valid for https://mcp.acme.com. A server at that address should check this claim matches itself. A different server (https://other-service.com) receiving this same token must reject it, even if it trusts the same issuer's signature, because the token was never meant for it.

The vulnerability without audience checking

1. User authenticates with Identity Provider, gets a token meant for Service A
2. Attacker (or a careless client) presents that SAME token to MCP Server B
3. If Server B only checks "is this signature valid and from a trusted issuer,"
   without checking WHO the token was actually issued for, it accepts it
4. Server B now treats the request as authorized, even though the user
   never actually granted access to Server B specifically

This is a token passthrough vulnerability: a token legitimately obtained for one purpose gets reused, unchecked, somewhere it was never intended to reach.

Why this matters more for MCP specifically

MCP is explicitly designed so many independent servers can all be part of one session. A token minted loosely is far more likely to end up presented somewhere it was never meant to go, simply because there are more distinct services in the mix than in a typical single-app OAuth setup. The required mitigation:

  • Servers must validate the aud claim (or equivalent audience-restriction mechanism) matches their own identifier before accepting any bearer token.
  • Clients should request tokens scoped to the specific resource server they intend to call, per RFC 8707 (Resource Indicators for OAuth 2.0), rather than obtaining one broad token and hoping it happens to work everywhere.
  • A server should never blindly forward a token it received from a client on to some other downstream API without similarly checking that forwarding is appropriate and that the downstream service is meant to receive it.

Related Resources