a2ally™ Sign up

Answers · MCP security

What is a wrong-audience OAuth token in MCP, and how do I defend against it?

Last updated

TL;DR: A wrong-audience token is an access token that was issued for one resource (another API, another MCP server) but is presented to yours. If your MCP server accepts any token your authorization server signed, a token a user granted to some other server, or one a malicious server captured, can be replayed against you: the confused-deputy and token-passthrough problems. The MCP authorization specification closes this with audience binding: clients must send the RFC 8707 resource parameter naming your server's canonical URI when they request a token, and your server must validate that each token was issued specifically for it (its audience) and reject everything else. It must also never forward the token it received to an upstream API; get a separate token for that API.

What should I check, step by step?

1. Publish OAuth Protected Resource Metadata (RFC 9728) at /.well-known/oauth-protected-resource naming your server's canonical URI and its authorization server(s).

  1. Use one canonical resource URI for the server (scheme, host and path, such as https://mcp.your-domain.com/mcp) and make sure clients send exactly that as the RFC 8707 resource parameter in both the authorization and the token request.
  2. On every request, validate the token fully: signature or introspection, issuer, expiry and not-before, and that the audience (aud, or the introspection response's audience) contains your canonical URI. Reject a token whose audience is missing or names something else, with HTTP 401.
  3. Check scopes per tool call, not only at connect time, and answer 403 insufficient_scope when a token lacks the scope a tool needs.
  4. Never pass the client's token through to an upstream API. Call upstream services with their own token, obtained for that audience (for instance by your own OAuth client or by token exchange, RFC 8693), and keep upstream tokens on the server.
  5. If your server is a proxy to a third-party API, require per-client user consent before forwarding to the third-party authorization server, so a static client ID cannot be abused across users (the confused-deputy case in the MCP security best practices).
  6. Keep access tokens short-lived, never log them, and log the token's issuer, audience and client ID on rejection so mis-issued tokens are easy to trace.

Why accepting "any valid token" is not enough

A signature only proves who issued a token, not who it was for. Many authorization servers issue tokens for several resources with the same key, so a token for a calendar API and a token for your MCP server can both verify.

What does the specification require?

The MCP authorization specification (2025-06-18 and later) requires MCP clients to implement RFC 8707 Resource Indicators and MCP servers to validate that tokens were issued specifically for them as the intended audience.

How do I ask a2ally about this (free, no key)?

Add the MCP server https://www.a2ally.com/mcp to Claude, Cursor, ChatGPT, Grok or VS Code, then ask: “Before I connect this MCP server, is it a listed, vetted app and has its tool list changed recently?”

One-click setup

{
  "tool": "check_listing",
  "arguments": {
    "url": "<the server's URL or repository>"
  }
}

a2ally does not test or certify another server's OAuth implementation. It reports what its store checks and listings actually found.

What are the sources?

Related

Not legal advice. JSON · Markdown · All answers

Get a free API key in one call

No card and no email needed. 100 free credits; the license and policy checks stay free without a key.

curl -s -X POST https://www.a2ally.com/v1/accounts/signup -H "Content-Type: application/json" -d '{"accept_terms":true}'
export A2ALLY_API_KEY=rs_...   # the api_key from the reply (shown once)
curl -s https://www.a2ally.com/v1/licenses/check -H "Authorization: Bearer $A2ALLY_API_KEY" \
  -H "Content-Type: application/json" -d '{"license":"MIT","intended_use":{"commercial_use":true}}'