Spec explainer
What is RFC 9207 iss validation in MCP OAuth?
Last verified: 10 August 2026 · spec 2026-07-28 · ruleset 1.4.2
iss parameter to the OAuth authorization response so the client can confirm which authorization server answered before redeeming the code. It closes the mix-up attack. Under MCP 2026-07-28, authorization servers SHOULD send it and MUST advertise it — but the validation itself is the client's job, not your MCP server's.The short answer
HTTP/1.1 302 Found
Location: https://client.example.com/callback
?code=SplxlOBeZQQYbYS6WxSbIA
&state=af0ifjsldkj
&iss=https%3A%2F%2Fauth.example.com ← RFC 9207
// The client MUST compare that iss against the issuer it
// expected for this authorization request, and refuse to
// redeem the code if they differ.- The authorization server sends
issand advertises that it does. - The client compares it and rejects a mismatch.
- Your MCP server never sees the authorization response at all.
The attack it closes
Mix-up only threatens a client that talks to more than one authorization server — which, for an MCP client connecting to arbitrary servers, is the normal case rather than an edge case.
1. Client starts a login. It intends to authenticate at
honest-as.example, but an attacker influences the choice
and it actually starts the flow at attacker-as.example.
2. attacker-as.example redirects back to the client's real
callback with a code.
3. The callback carries: code, state. Nothing else.
The client knows a code arrived. It does NOT know which
authorization server minted it.
4. The client redeems that code at honest-as.example —
or hands the attacker a code meant for the honest server.
The redirect looked correct. state matched. The only
missing fact was "who answered".iss supplies exactly that missing fact, and nothing else. It is a small parameter for a narrow, real problem — which is why it is worth understanding once rather than treating as generic OAuth boilerplate.
Whose job is it? (the part most write-ups skip)
iss in front of it to check. Any guide telling you to “add RFC 9207 to your MCP server” has confused the resource server with the client.Concretely, the three roles split like this:
| Role | Obligation | Level |
|---|---|---|
| Authorization server | Send iss; advertise authorization_response_iss_parameter_supported | SHOULD / MUST |
| MCP client | Compare it to the expected issuer before redeeming | Client-side |
| MCP server (resource server) | Choose an authorization server that supports it | Indirect |
That third row is the only lever you have, and it is a real one: your Protected Resource Metadata names the authorization servers clients should use. Naming one that does not support iss is a choice you are making on behalf of every client that connects to you.
What MCP 2026-07-28 actually requires
“MCP authorization servers SHOULD include the iss parameter in authorization responses... Authorization servers that include the iss parameter MUST advertise this by setting authorization_response_iss_parameter_supported to true.”
Read the two halves carefully, because they have different strengths. Sending the parameter is SHOULD. Advertising it, if you send it, is MUST — an authorization server that emits iss without declaring support is worse than one that does neither, because a client cannot rely on a parameter it was not told to expect.
iss that time, not that it always will.Checking whether your authorization server supports it
# RFC 8414 (OAuth 2.0 Authorization Server Metadata)
curl -s https://auth.example.com/.well-known/oauth-authorization-server \
| jq '.authorization_response_iss_parameter_supported'
# OpenID Connect Discovery 1.0
curl -s https://auth.example.com/.well-known/openid-configuration \
| jq '.authorization_response_iss_parameter_supported'
# true → supported and advertised
# false → explicitly not supported
# null → the field is absent, which means the same as falseAn absent field and false are equivalent for your purposes. The spec requires servers that send iss to advertise it, so silence is a claim: this server does not send it.
“MCP authorization servers MUST provide at least one of: OAuth 2.0 Authorization Server Metadata (RFC8414) or OpenID Connect Discovery 1.0.”
Where this sits in the rest of the auth chain
iss validation is one link. The checks around it are the ones your MCP server can satisfy directly, and they are what makes discovering your authorization server possible in the first place:
“MCP servers MUST implement OAuth 2.0 Protected Resource Metadata (RFC9728).”
“HTTP/1.1 401 Unauthorized. WWW-Authenticate: Bearer resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource".”
The chain runs: an unauthenticated request gets a 401 whose WWW-Authenticate header points at your Protected Resource Metadata; that document names your authorization servers; each of those exposes metadata; and that metadata is where authorization_response_iss_parameter_supported lives. Break any earlier link and the client never gets far enough to care about iss.
“Authorization servers providing OpenID Connect Discovery 1.0 MUST include code_challenge_methods_supported in their metadata to ensure MCP compatibility.”
PKCE with S256 sits alongside iss as the other defence against code interception — different attack, same stage of the flow, and also advertised through authorization server metadata rather than implemented by you.
The 11 authorization rules we check
All eleven carry verbatim spec sentences. Note that several describe the authorization server's behaviour: we reach them by following your Protected Resource Metadata outward, and report the result on your server's report because your metadata is what pointed us there.
| Rule | What we check | Level | If it fails |
|---|---|---|---|
| MCP-AUT-005 | AS advertises authorization_response_iss_parameter_supported: true | SHOULD | warn |
| MCP-AUT-002 | RFC 9728 Protected Resource Metadata is served and valid | MUST | fail |
| MCP-AUT-004 | Each listed authorization server exposes RFC 8414 or OIDC discovery metadata | MUST | fail |
| MCP-AUT-003 | PRM resource equals the canonical server URI | MUST | fail |
| MCP-AUT-001 | Unauthenticated request returns 401 with WWW-Authenticate resource_metadata | MUST | fail |
| MCP-AUT-010 | AS advertises S256 in code_challenge_methods_supported | MUST | fail |
| MCP-AUT-011 | AS supports Client ID Metadata Documents, not DCR alone | SHOULD | warn |
| MCP-AUT-006 | WWW-Authenticate includes a scope parameter | SHOULD | warn |
| MCP-AUT-007 | Insufficient scope returns 403 with error="insufficient_scope" | SHOULD | warn |
| MCP-AUT-008 | Tokens with a foreign audience are rejected | MUST | fail |
| MCP-AUT-009 | offline_access absent from scopes_supported / challenge scope | SHOULD_NOT | info |
MCP-AUT-005 is the RFC 9207 check. Security-relevant failures cap a report grade at D.
Check your authorization chain end to end
The validator follows the whole path — 401 challenge, Protected Resource Metadata, each authorization server's metadata — and reports all eleven rules, including whether your authorization server advertises RFC 9207 support.
Validate a server →Frequently asked
What is RFC 9207 iss validation?
RFC 9207 (OAuth 2.0 Authorization Server Issuer Identification) adds an iss parameter to the authorization response. The client compares that value against the issuer it expected before redeeming the authorization code, so a code minted by one authorization server can never be redeemed as though it came from another. It closes the authorization server mix-up attack.
Does MCP require iss validation?
The 2026-07-28 specification says MCP authorization servers SHOULD include the iss parameter in authorization responses, and that servers which do include it MUST advertise this by setting authorization_response_iss_parameter_supported to true in their metadata. The validation itself is performed by the client.
Can an MCP server implement iss validation?
No. The MCP server is the OAuth resource server — it never sees the authorization response, so there is nothing for it to validate. The obligation sits with the client, which receives the redirect, and with the authorization server, which must send and advertise the parameter. An MCP server's only lever is which authorization server it points clients at.
What is the authorization server mix-up attack?
An attack in which a client that talks to more than one authorization server is tricked into sending an authorization code issued by an attacker-controlled server to a legitimate one, or into redeeming a legitimate code at the attacker's token endpoint. Without an issuer identifier in the response, the redirect alone does not tell the client which server actually answered.
How do I check whether my authorization server supports it?
Fetch its metadata document — /.well-known/oauth-authorization-server for RFC 8414, or /.well-known/openid-configuration for OpenID Connect Discovery — and look for authorization_response_iss_parameter_supported set to true. If the field is absent or false, the server is telling you it does not send the iss parameter.
Why does createmcps.com report this as a warning rather than a failure?
Because the specification states it at SHOULD level rather than MUST, and because it is a property of the authorization server rather than of the MCP server being validated. We check it by reading the metadata of each authorization server the MCP server names in its Protected Resource Metadata, and report it as a warning on the MCP server's report.