SEP-2352: Clarify authorization server binding and migration — rust-sdk implementation
Spec PR: modelcontextprotocol/modelcontextprotocol#2352
Track: Specification · Stage: accepted · Priority: P0 · Theme: Enterprise Readiness
Needs code changes: Yes (Medium)
Summary
Multi-AS guidance:
- Clients SHOULD maintain separate registration state per authorization server and MUST NOT assume cross-AS credential validity.
- New "Authorization Server Binding" rules: DCR / pre-registered credentials must be keyed by issuer; CIMD
client_ids are portable; clients should error on AS mismatch.
Why this needs code changes in rust-sdk
The OAuth client in crates/rmcp/src/transport/auth.rs persists credentials and registration state
via the CredentialStore trait (StoredCredentials, InMemoryCredentialStore) and the
StateStore trait (StoredAuthorizationState, InMemoryStateStore). Today these are effectively
single-AS: StoredCredentials and the in-memory stores are not keyed by issuer, and
AuthorizationManager holds one metadata: Option<AuthorizationMetadata> (whose issuer field
exists but isn't used to partition stored credentials). So credentials from one AS could be reused
against another, which SEP-2352 forbids.
Proposed work
Affected areas
crates/rmcp/src/transport/auth.rs (CredentialStore/StoredCredentials, StateStore/StoredAuthorizationState, InMemory*Store, AuthorizationManager, AuthError).
Notes / risks
- Part of the Enterprise Readiness auth cluster (837, 2350, 2351, 2468). Bundle into one auth PR/effort to share test scaffolding.
SEP-2352: Clarify authorization server binding and migration — rust-sdk implementation
Spec PR: modelcontextprotocol/modelcontextprotocol#2352
Track: Specification · Stage: accepted · Priority: P0 · Theme: Enterprise Readiness
Needs code changes: Yes (Medium)
Summary
Multi-AS guidance:
client_ids are portable; clients should error on AS mismatch.Why this needs code changes in rust-sdk
The OAuth client in
crates/rmcp/src/transport/auth.rspersists credentials and registration statevia the
CredentialStoretrait (StoredCredentials,InMemoryCredentialStore) and theStateStoretrait (StoredAuthorizationState,InMemoryStateStore). Today these are effectivelysingle-AS:
StoredCredentialsand the in-memory stores are not keyed by issuer, andAuthorizationManagerholds onemetadata: Option<AuthorizationMetadata>(whoseissuerfieldexists but isn't used to partition stored credentials). So credentials from one AS could be reused
against another, which SEP-2352 forbids.
Proposed work
CredentialStore/StateStoreentries by issuer — either add anissuerdiscriminator toStoredCredentials/load/savekeys, or make the in-memory storesHashMap<issuer, …>so per-AS state is isolated.AuthorizationMetadata.issueragainst the issuer the stored credentials were minted for; on mismatch return a clearAuthError(add a variant, e.g.AuthError::AuthorizationServerMismatch).client_ids as portable (don't tie those to a single issuer), but keep DCR/pre-registered credentials issuer-bound.register_client/configure_client_id/get_credentialspaths to read/write the issuer-keyed store.Affected areas
crates/rmcp/src/transport/auth.rs(CredentialStore/StoredCredentials,StateStore/StoredAuthorizationState,InMemory*Store,AuthorizationManager,AuthError).Notes / risks