You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(client): gate RFC 9207 fail-closed iss rejection behind explicit caller signal
The advertised-but-missing rejection (AS metadata sets
authorization_response_iss_parameter_supported: true but no iss was
supplied) previously fired whenever iss was omitted from auth()/
finishAuth(). The SDK never sees the authorization response itself, so
it cannot distinguish 'the response had no iss' from 'the caller did
not plumb response parameters through' — and every existing
finishAuth(code) caller falls in the second bucket. This broke the
client-conformance auth/pre-registration scenario (the fixture AS
advertises RFC 9207 support; the harness never passes iss).
iss is now tri-state on validateAuthorizationResponseIssuer(), auth(),
and both transports' finishAuth():
- string: exact-match validation against the recorded issuer (unchanged)
- null: caller asserts it inspected the response and it had no iss ->
RFC 9207 fail-closed rejection applies when support is advertised
- undefined: caller had no access to response parameters -> validation
is skipped entirely
Conformance: client suite back to baseline-green (auth/pre-registration
15/15). Client tests: 386 passed.
Copy file name to clipboardExpand all lines: .changeset/sep-2468-iss-validation.md
+5-1Lines changed: 5 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,4 +3,8 @@
3
3
'@modelcontextprotocol/client': minor
4
4
---
5
5
6
-
Add RFC 9207 `iss` parameter validation for authorization responses (SEP-2468). `OAuthMetadataSchema` and `OpenIdProviderMetadataSchema` now recognize `authorization_response_iss_parameter_supported`. The client exports a new `validateAuthorizationResponseIssuer()` helper, `auth()` accepts an optional `iss`, and `StreamableHTTPClientTransport.finishAuth()` / `SSEClientTransport.finishAuth()` accept an optional `{ iss }` second argument. When provided, the `iss` from the authorization response is validated against the issuer recorded in the authorization server metadata before the authorization code is sent to any token endpoint; on mismatch the response is rejected without processing any other response parameters. All additions are backwards-compatible.
6
+
Add RFC 9207 `iss` parameter validation for authorization responses (SEP-2468). `OAuthMetadataSchema` and `OpenIdProviderMetadataSchema` now recognize `authorization_response_iss_parameter_supported`. The client exports a new `validateAuthorizationResponseIssuer()` helper,
7
+
`auth()` accepts an optional `iss`, and `StreamableHTTPClientTransport.finishAuth()` / `SSEClientTransport.finishAuth()` accept an optional `{ iss }` second argument. The `iss` option is tri-state: a string is validated by exact comparison against the issuer recorded in the
8
+
authorization server metadata before the authorization code is sent to any token endpoint (mismatch rejects the response without processing any other response parameters); `null` asserts the caller inspected the authorization response and it carried no `iss`, enabling the RFC
9
+
9207 fail-closed rejection when the AS advertises `authorization_response_iss_parameter_supported: true`; `undefined` (omitted) skips validation, so existing `finishAuth(code)` callers that never see the authorization response are unaffected. All additions are
'Authorization server metadata advertises authorization_response_iss_parameter_supported, but the authorization response did not include an iss parameter (RFC 9207)'
@@ -593,8 +611,16 @@ export async function auth(
593
611
* The `iss` parameter received alongside the authorization code in the
594
612
* authorization response, validated per RFC 9207 against the issuer recorded
595
613
* in the authorization server metadata before the code is exchanged.
614
+
*
615
+
* Pass the string value when the authorization response contained an `iss`
616
+
* parameter. Pass `null` to assert that you inspected the authorization
617
+
* response and it contained no `iss` — this enables the RFC 9207 fail-closed
Copy file name to clipboardExpand all lines: packages/client/src/client/sse.ts
+7-3Lines changed: 7 additions & 3 deletions
Original file line number
Diff line number
Diff line change
@@ -230,11 +230,15 @@ export class SSEClientTransport implements Transport {
230
230
* Call this method after the user has finished authorizing via their user agent and is redirected back to the MCP client application. This will exchange the authorization code for an access token, enabling the next connection attempt to successfully auth.
231
231
*
232
232
* @param authorizationCode - The authorization code from the authorization response
233
-
* @param options.iss - The `iss` parameter from the authorization response, if present.
234
-
* Validated against the issuer recorded in the authorization server metadata per RFC 9207
233
+
* @param options.iss - The `iss` parameter from the authorization response. Pass the string
234
+
* value when present; pass `null` to assert the authorization response was inspected and
235
+
* contained no `iss` (this enables the RFC 9207 fail-closed rejection when the AS advertises
236
+
* `authorization_response_iss_parameter_supported: true`). Leave `undefined` when the response
237
+
* parameters were not available — validation is then skipped. When provided, the value is
238
+
* validated against the issuer recorded in the authorization server metadata per RFC 9207
Copy file name to clipboardExpand all lines: packages/client/src/client/streamableHttp.ts
+7-3Lines changed: 7 additions & 3 deletions
Original file line number
Diff line number
Diff line change
@@ -491,11 +491,15 @@ export class StreamableHTTPClientTransport implements Transport {
491
491
* Call this method after the user has finished authorizing via their user agent and is redirected back to the MCP client application. This will exchange the authorization code for an access token, enabling the next connection attempt to successfully auth.
492
492
*
493
493
* @param authorizationCode - The authorization code from the authorization response
494
-
* @param options.iss - The `iss` parameter from the authorization response, if present.
495
-
* Validated against the issuer recorded in the authorization server metadata per RFC 9207
494
+
* @param options.iss - The `iss` parameter from the authorization response. Pass the string
495
+
* value when present; pass `null` to assert the authorization response was inspected and
496
+
* contained no `iss` (this enables the RFC 9207 fail-closed rejection when the AS advertises
497
+
* `authorization_response_iss_parameter_supported: true`). Leave `undefined` when the response
498
+
* parameters were not available — validation is then skipped. When provided, the value is
499
+
* validated against the issuer recorded in the authorization server metadata per RFC 9207
0 commit comments