SEP-2468: Recommend Issuer (iss) Parameter in MCP Auth Responses — rust-sdk implementation
Spec PR: modelcontextprotocol/modelcontextprotocol#2468
Track: Specification · Stage: accepted · Priority: P0 · Theme: Enterprise Readiness
Needs code changes: Yes (Medium) — additive (security)
Summary
Recommends including and validating an explicit issuer (iss) claim in MCP authorization
responses to mitigate authorization mix-up attacks in multi-IdP environments, following RFC 9207.
Clients will need to validate the iss parameter and bind responses to the correct authorization
server.
Why this needs code changes in rust-sdk
The OAuth client lives in crates/rmcp/src/transport/auth.rs. AuthorizationMetadata already has
an issuer: Option<String> field, and AuthorizationManager generates the authorization URL
(get_authorization_url) and exchanges the code in the callback path. Today the callback path does
not capture or validate the iss query parameter that RFC 9207 adds to the redirect, so the
mix-up defense isn't in place.
The expected issuer must also be available at callback time. The flow state is persisted as
StoredAuthorizationState (currently holds PKCE verifier + CSRF token) — that's the natural place
to also stash the issuer the flow was started against.
Proposed work
Affected areas
crates/rmcp/src/transport/auth.rs (AuthorizationManager callback/code-exchange, StoredAuthorizationState, AuthError).
Notes / risks
- Conformance currently shows
auth/metadata-var3 and auth/scope-step-up failing; this work touches the same auth client and may be bundled with SEP-2350/2351/2352.
SEP-2468: Recommend Issuer (iss) Parameter in MCP Auth Responses — rust-sdk implementation
Spec PR: modelcontextprotocol/modelcontextprotocol#2468
Track: Specification · Stage: accepted · Priority: P0 · Theme: Enterprise Readiness
Needs code changes: Yes (Medium) — additive (security)
Summary
Recommends including and validating an explicit issuer (
iss) claim in MCP authorizationresponses to mitigate authorization mix-up attacks in multi-IdP environments, following RFC 9207.
Clients will need to validate the
issparameter and bind responses to the correct authorizationserver.
Why this needs code changes in rust-sdk
The OAuth client lives in
crates/rmcp/src/transport/auth.rs.AuthorizationMetadataalready hasan
issuer: Option<String>field, andAuthorizationManagergenerates the authorization URL(
get_authorization_url) and exchanges the code in the callback path. Today the callback path doesnot capture or validate the
issquery parameter that RFC 9207 adds to the redirect, so themix-up defense isn't in place.
The expected issuer must also be available at callback time. The flow state is persisted as
StoredAuthorizationState(currently holds PKCE verifier + CSRF token) — that's the natural placeto also stash the issuer the flow was started against.
Proposed work
StoredAuthorizationStateto record the expected issuer (theAuthorizationMetadata.issuerused whenget_authorization_urlwas called).issquery parameter from the redirect.issequals the stored expected issuer (RFC 9207); on mismatch return anAuthError(e.g. reuse/extend theAuthorizationServerMismatchvariant proposed in SEP-2352).iss: tolerate for back-compat with non-RFC-9207 ASes, but require it when the AS advertised support.iss.Affected areas
crates/rmcp/src/transport/auth.rs(AuthorizationManagercallback/code-exchange,StoredAuthorizationState,AuthError).Notes / risks
auth/metadata-var3andauth/scope-step-upfailing; this work touches the same auth client and may be bundled with SEP-2350/2351/2352.