LLM Application Security advanced 8 min read 8 flashcards

Audience Binding and Token Exchange

Why a bearer token that does not name its destination becomes a skeleton key the moment an agent passes it along, and the OAuth mechanisms — resource indicators, token exchange, protected resource metadata — that MCP now requires to stop it.

A bearer token is defined by a single unhappy property: anyone holding it can use it. RFC 8707 puts the consequence bluntly, noting that bearer tokens let any party in possession get access to the associated resources, so an access token must be valid only at a specific protected resource and for a specific scope. An audience-restricted token legitimately presented to one service cannot then be taken by that service and presented elsewhere (Campbell et al., 2020, Resource Indicators for OAuth 2.0, RFC 8707).

Agent architectures multiply the number of hands a token passes through. A client calls an MCP server, which calls a SaaS API, which calls another. If the same token travels the whole chain, every component on it holds the user's full authority, and compromising the least defended one is equivalent to compromising them all. That is the Drift failure pattern generalised: authority stored where it is not needed.

The two anti-patterns

Token passthrough is forwarding an incoming token to a downstream service. It is convenient, and it destroys the audit chain: the downstream service sees a call that appears to come from the user, with nothing recording that an agent made it. It also means a token issued for the MCP server now works at the SaaS API.

Audience-blind validation is accepting any token that verifies cryptographically without checking that it was issued for you. A service that does this will happily accept a token stolen from somewhere else in the mesh.

MCP's authorization specification forbids both in normative language. An MCP server is an OAuth 2.1 resource server and MUST validate that access tokens were issued specifically for it as the intended audience, rejecting tokens that do not include it in the audience claim. And "the MCP server MUST NOT pass through the token it received from the MCP client" when calling upstream APIs; it must obtain a separate token for that upstream audience (Model Context Protocol, 2025-06-18, Authorization).

Asking for the right token

Audience binding starts at the request. RFC 8707 adds a resource parameter so a client can say which protected resource the token is for, letting the authorization server apply the audience restriction. MCP makes this mandatory: clients MUST include resource in both authorization and token requests, and it MUST identify the MCP server the token will be used with.

The server side needs a way to tell clients where to get such a token. RFC 9728, published in April 2025, defines protected resource metadata: a JSON document at a well-known location describing the resource and, critically, the authorization_servers it trusts (OAuth 2.0 Protected Resource Metadata, RFC 9728). MCP servers MUST implement it, and MUST return 401 Unauthorized with a WWW-Authenticate header pointing at the metadata URL, which is what lets a client discover authorization without any of it being configured ahead of time.

The full discovery sequence is therefore: call without a token, get a 401 naming the metadata document, fetch the metadata to learn the authorization server, fetch that server's metadata under RFC 8414, register dynamically under RFC 7591 if needed, then request a token with resource set to this server.

Exchanging, not forwarding

When the deputy legitimately needs to call something else, the mechanism is RFC 8693, OAuth 2.0 Token Exchange, published January 2020. The service presents the token it holds as a subject_token and asks for a new token for a different audience or resource, with equal or narrower scope (Jones et al., 2020, OAuth 2.0 Token Exchange, RFC 8693).

Its most useful feature for agents is the distinction between two things people conflate. Impersonation produces a token indistinguishable from one the user obtained directly; the downstream service cannot tell an agent was involved. Delegation produces a token that names both parties, carrying an act claim recording the actor operating on the subject's behalf. Delegation is what you want, because the fact that a machine made the call is exactly the fact an auditor needs and exactly the fact impersonation erases. A related may_act claim lets the authorization server state in advance which actors are permitted to act for a subject, so the policy lives in the issuer rather than in each service's code.

Each exchange is also an enforcement point. The authorization server sees the actor, the subject, the requested audience and the requested scope, and can refuse. Forwarding a token asks nobody's permission.

When it breaks

The aud claim is only as good as the check. Plenty of resource servers verify the signature and expiry and skip the audience entirely. The failure is silent and invisible in normal operation, and it converts every token in the system into a universal one.

Opaque tokens need introspection, and introspection needs a trip. Audience checking on a reference token means calling the authorization server on the hot path, so teams cache aggressively and the cache becomes the revocation delay.

Revocation is still slow. Audience binding limits where a stolen token works, not for how long. Short lifetimes, and a refresh path an incident responder can break, do that job.

Dynamic client registration is an unauthenticated write endpoint. MCP encourages RFC 7591 so clients can register without human setup. That convenience is also a registration flood and a confused-deputy consent bypass unless rate limits and per-client consent are in place.

References and further reading

Every source this page cites, in the order it cites them. All of them open in a new tab.

  1. Campbell et al., 2020, Resource Indicators for OAuth 2.0, RFC 8707 rfc-editor.org
  2. Model Context Protocol, 2025-06-18, Authorization github.com
  3. OAuth 2.0 Protected Resource Metadata, RFC 9728 rfc-editor.org
  4. Jones et al., 2020, OAuth 2.0 Token Exchange, RFC 8693 rfc-editor.org
Check yourself

8 flashcards for this concept

Click a card to reveal the answer.

Drill the whole track