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
Bind client credentials to their authorization server (SEP-2352)
Persisted client credentials are now bound to the issuer that registered them:
OAuthClientInformationFull records an issuer, set by the SDK after DCR/CIMD.
When protected resource metadata points at a different authorization server,
the client discards the bound credentials and old tokens and re-registers,
instead of presenting one server's client_id to another.
URL-based client IDs (CIMD) are portable and always match; credentials with no
recorded issuer (pre-registered, or stored before this change) carry no binding
to enforce and are left as-is. No TokenStorage protocol change - the issuer
round-trips through the existing get_client_info/set_client_info.
Follows the Go SDK's approach. The auth/authorization-server-migration
conformance scenario's re-register check is satisfied in spirit (no-reuse and
no-cross-AS checks pass) but the scenario stays baselined: it runs at
2026-07-28, where client.py's 2025 lifecycle is rejected before the migration
401 fires. It unblocks with the 2026 stateless client lifecycle.
Copy file name to clipboardExpand all lines: docs/migration.md
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1322,6 +1322,10 @@ If you relied on extra fields round-tripping through MCP types, move that data i
1322
1322
1323
1323
## New Features
1324
1324
1325
+
### OAuth client credentials are bound to their authorization server (SEP-2352)
1326
+
1327
+
Persisted OAuth client credentials are now bound to the authorization server that issued them: `OAuthClientInformationFull` records an `issuer`, set by the SDK after registration. When a server's protected resource metadata later points at a different authorization server, the client discards the bound credentials (and the old tokens) and re-registers with the new server instead of presenting one server's `client_id` to another. URL-based client IDs (CIMD) are portable and unaffected; credentials with no recorded issuer (pre-registered, or stored before this change) are left as-is. No API change for existing `TokenStorage` implementations - the `issuer` round-trips through the unchanged `get_client_info`/`set_client_info`.
When a `403 insufficient_scope` challenge triggers step-up re-authorization, the OAuth client now requests the union of the previously requested scopes and the newly challenged scopes, instead of replacing the scope with only the challenged ones. This keeps permissions granted for earlier operations from being dropped when a later operation escalates. No API change; the wider scope is sent automatically on the re-authorization request.
0 commit comments