Skip to content

Support RFC 9207 issuer identification (iss parameter) - #4

Merged
wille merged 1 commit into
masterfrom
rfc9207-iss-parameter
Jul 6, 2026
Merged

Support RFC 9207 issuer identification (iss parameter)#4
wille merged 1 commit into
masterfrom
rfc9207-iss-parameter

Conversation

@wille

@wille wille commented Jul 6, 2026

Copy link
Copy Markdown
Owner

Summary

Ports the server-side authorization changes from SEP-2468 (MCP 2026-07-28 spec revision) in the MCP SDK: modelcontextprotocol/typescript-sdk#2357, landed upstream via #2286.

RFC 9207 defends against authorization server mix-up attacks: the AS appends iss=<issuer identifier> to every authorization response redirect, and clients validate it against the discovered issuer before redeeming the code. Updated MCP SDK clients now perform this validation, so servers should emit iss and advertise support.

Changes

  • OAuthServer gains an issuerUrl option — the single source of truth for the authorization server's issuer identifier (used as the RFC 8414 metadata issuer and the RFC 9207 iss value).
  • OAuthServer.authenticate() appends iss to the success redirect back to the client's redirect_uri.
  • authorizationHandler and authenticateHandler append iss to error redirects (RFC 9207 §2 requires it on error responses too).
  • Authorization server metadata advertises authorization_response_iss_parameter_supported: true; the field is added to OAuthMetadataSchema.

BREAKING CHANGE

mcpAuthRouter no longer accepts issuerUrl — it reads the issuer from the provider and throws at construction if unset:

 const oauthServer = new OAuthServer({
+    issuerUrl: new URL('https://auth.example.com'),
     authorizationUrl: new URL('https://auth.example.com/consent'),
     ...
 });

 app.use(mcpAuthRouter({
     provider: oauthServer,
-    issuerUrl: new URL('https://auth.example.com'),
 }));

Caveat

Since the metadata now claims iss support, a custom consent flow that issues the callback redirect itself (bypassing authenticateHandler / OAuthServer.authenticate()) must append iss (available as provider.issuerUrl) — SEP-2468 clients reject callbacks that omit it when support is advertised.

Tests

  • iss asserted on success redirects (authenticate()) and error redirects (authorize handler), plus absent-when-unconfigured.
  • Metadata assertions for authorization_response_iss_parameter_supported and the new missing-issuerUrl throw.
  • Verified end-to-end against the example server: metadata, consent-flow success redirect, and error redirect all carry iss.

Port of the server-side parts of SEP-2468 (MCP 2026-07-28) from
modelcontextprotocol/typescript-sdk#2357. Authorization responses now
carry iss on both success and error redirects, and the metadata
advertises authorization_response_iss_parameter_supported.

BREAKING CHANGE: issuerUrl moved from mcpAuthRouter options to
OAuthServer options, which is now the single source of truth for the
issuer identifier.
@wille wille self-assigned this Jul 6, 2026
@wille
wille merged commit 65450bc into master Jul 6, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant