Skip to content
WarHound AI

Engineering

MCP authorization: validate token audience and avoid passthrough

The Model Context Protocol (MCP) relies on OAuth 2.1 and RFC 8707 Resource Indicators to secure HTTP transports. This article details how application engineers must implement strict audience validation and avoid token passthrough to prevent confused deputy attacks, including a concrete test matrix and implementation tradeoffs.

Input meets a permission boundary.CONTROL THE CAPABILITYWARHOUND / FIELD NOTESCONCEPTINPUTPOLICYREAD SCOPEWRITE SCOPESTOP RULELIMIT CAPABILITY. KEEP CONTEXT.Input meets a permission boundary.CONTROL THE CAPABILITYINPUTPOLICYREAD SCOPEWRITE SCOPESTOP RULEWARHOUND / CONCEPTUAL ILLUSTRATION
Untrusted input should meet a permission boundary before it can cause a privileged action. Conceptual illustration.

MCP Authorization Architecture and the Confused Deputy

The Model Context Protocol (MCP) specification for HTTP-based transports delegates authorization to an OAuth 2.1 framework. In this architecture, the MCP server acts as an OAuth 2.1 resource server, while the MCP client acts as the OAuth 2.1 client. A critical vulnerability arises when MCP servers act as intermediaries to third-party APIs. If an MCP server accepts tokens issued for other resources, or forwards its own inbound tokens to downstream services, it creates a confused deputy problem.

A confused deputy vulnerability occurs when a downstream API incorrectly trusts a forwarded token as if the request originated directly from the user, or assumes the upstream MCP server validated the request context. Attackers exploiting this can reuse legitimate tokens across unintended services. To mitigate this, the MCP specification explicitly forbids token passthrough and mandates strict audience validation using RFC 8707 Resource Indicators for OAuth 2.0.

When an MCP server receives an HTTP request, it must extract the Bearer token from the Authorization header and validate that the token was explicitly issued for its canonical URI. If the server subsequently makes requests to upstream APIs to fulfill the client's prompt, it must negotiate and use an entirely separate access token issued by the upstream authorization server, never forwarding the client's original token.

  • MCP clients must implement RFC 8707 Resource Indicators.
  • MCP servers must validate that inbound access tokens specify them as the intended audience.
  • MCP servers must never transit or pass through inbound tokens to downstream systems.

Mechanism of Audience Binding

To explicitly specify the target resource, MCP clients must include the resource parameter in both authorization and token requests. This parameter identifies the canonical URI of the MCP server. According to the specification, the canonical URI uses a lowercase scheme and host, and implementations should consistently omit trailing slashes unless semantically significant.

By enforcing the resource parameter, the authorization server binds the issued access token to the specific MCP server. When the token is presented, the MCP server inspects the audience claim. If the audience claim does not match the server's canonical URI, the token must be rejected with an HTTP 401 Unauthorized response.

This boundary ensures that a token compromised at one MCP server cannot be replayed against another MCP server or a completely different resource server within the same ecosystem. Implementing this requires the authorization server to support RFC 8707, but MCP clients are required to send the parameter regardless of server support to ensure future-proof interoperability.

Concrete Worked Example: Token Negotiation

Consider a hypothetical MCP client interacting with a protected MCP server located at https://mcp.example.com. The client initiates the authorization code flow with Proof Key for Code Exchange (PKCE) as mandated by OAuth 2.1. The client constructs the authorization request, appending the resource parameter.

The query string includes resource=https%3A%2F%2Fmcp.example.com. The authorization server authenticates the user and returns an authorization code. The client then exchanges this code for an access token at the token endpoint, again including the resource parameter in the POST body.

The authorization server mints a JWT access token where the 'aud' (audience) claim is explicitly set to ["https://mcp.example.com"]. The client sends this token in the Authorization: Bearer header of its requests. The MCP server parses the JWT, verifies the signature using the authorization server's public keys, and asserts that the 'aud' claim matches its exact URI. It then proceeds to process the context request.

Implementation Tradeoffs and Failure Modes

Implementing strict audience validation introduces architectural friction. Authorization servers that predate RFC 8707 may ignore the resource parameter, forcing engineers to rely on custom scope conventions or custom claims to restrict token usage. This degrades interoperability and requires custom validation logic on the MCP server.

Another tradeoff involves the complexity of managing separate tokens for upstream requests. When an MCP server needs to query a third-party API, it must maintain its own OAuth client credentials, handle consent flows, and manage token lifecycles independent of the MCP client's session. This increases the statefulness of the MCP server.

Failure modes commonly include fragment inclusion in the canonical URI, which the specification marks as invalid, leading to validation mismatches. Additionally, caching tokens on the MCP server without robust encryption risks token theft. If an attacker extracts a cached token, short-lived access tokens and rotated refresh tokens are the primary defense mechanisms to limit the exposure window.

Safe Test Matrix: Allowed and Denied Outcomes

Engineers must implement a comprehensive test matrix to verify audience validation and ensure passthrough protections are active. These tests involve presenting synthetic tokens with varying configurations to the MCP server's HTTP endpoints.

The testing environment should isolate the MCP server and mock the authorization server's JWKS endpoint to control token issuance without relying on live authentication flows. The server must uniformly return HTTP 401 Unauthorized for audience mismatches, rather than HTTP 403 Forbidden, which is reserved for scope failures.

  • Token 'aud' matches canonical URI exactly (https://mcp.example.com): Allowed, HTTP 200.
  • Token 'aud' missing entirely: Denied, HTTP 401.
  • Token 'aud' matches canonical URI but includes trailing slash (https://mcp.example.com/): Denied, HTTP 401.
  • Token 'aud' issued for downstream API (https://api.thirdparty.com): Denied, HTTP 401.
  • Inbound token sent in downstream request header (passthrough): Denied, mock downstream receives no Authorization header or a separate valid server token.
  • Token provided in URI query string instead of header: Denied, HTTP 401.

Sources and Acknowledgments

The facts and protocol-specific claims in this article are grounded in the official Model Context Protocol Documentation. Artificial intelligence assistance was utilized in formatting and structuring this technical analysis.

Drafted with Gemini and checked for source links, advisory identifiers, structure and unsupported product claims. Examples are synthetic and are not scan results.

Drafted with Gemini and checked for source links, advisory identifiers, structure and unsupported product claims. Examples are synthetic and are not scan results.

Prepared with AI assistance and published by WarHound AI. Check the references and evidence limits in each article.

The WarHoundAI journal

Questions or a factual correction? Get in touch with the article URL and supporting evidence.

Continue reading.

All articles
Security Engineering

Retesting security fixes with positive and negative controls

Implementing an automated authorization matrix ensures that security fixes are thoroughly retested. By employing both positive and negative controls, application engineers can programmatically verify that authenticated and unauthenticated roles behave exactly as expected during regression testing.

Read article 5 min read
Engineering

Build release security gates around testable invariants

Security gates in deployment pipelines often fail because they rely on heuristic analysis rather than deterministic checks. By defining strict, testable security invariants based on standard frameworks like OWASP ASVS 5.0.0, application engineers can build reliable release gates. This article details how to translate security requirements into measurable pipeline constraints, including a matrix for input validation, implementation tradeoffs, and how WarHound AI supports isolated invariant testing.

Read article 5 min read
Engineering

Measure reasoning-token costs without weakening hard budgets

Reasoning tokens introduce variable costs that complicate API budgeting. This article details methods for calculating these costs, enforcing hard execution limits, and handling mid-generation truncations, with specific implementation patterns for WarHound AI.

Read article 5 min read