Skip to content

feat(auth): bind DCR client credentials to issuing authorization server (SEP-2352)#998

Open
alexhancock wants to merge 1 commit into
mainfrom
alexhancock/sep-2352-as-binding
Open

feat(auth): bind DCR client credentials to issuing authorization server (SEP-2352)#998
alexhancock wants to merge 1 commit into
mainfrom
alexhancock/sep-2352-as-binding

Conversation

@alexhancock

Copy link
Copy Markdown
Contributor

Motivation and Context

Per modelcontextprotocol/modelcontextprotocol#2352 clients SHOULD maintain separate registration state per auth server and MUST NOT assume cross-AS credential validity

How Has This Been Tested?

Conformance tests

cargo build -p mcp-conformance
npx -y @modelcontextprotocol/conformance@0.2.0-alpha.9 client --command ./target/debug/conformance-client --scenario auth/authorization-server-migration -o results

Breaking Changes

None. StoredCredentials is #[non_exhaustive] and has a new constructor

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

Closes #879

@alexhancock alexhancock requested a review from a team as a code owner July 16, 2026 15:58
@github-actions github-actions Bot added T-core Core library changes T-transport Transport layer changes labels Jul 16, 2026
token_response: Some(token_result.clone()),
granted_scopes,
token_received_at: Some(Self::now_epoch_secs()),
issuer: self.metadata_issuer(),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We now stamp issuer: self.metadata_issuer() here, but nothing reads it back. After a migration, what stops a static pre-registered credential from being silently sent to the new AS, the case where SEP-2352 says clients "SHOULD surface an error"?

token_response: Some(credentials),
granted_scopes,
token_received_at: Some(AuthorizationManager::now_epoch_secs()),
issuer: None,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since discover_metadata() runs right after the save, the issuer is actually available in this function. Was keeping the save before discovery intentional, or could the stamp be filled in after discovery succeeds?

Comment on lines +1075 to +1076
if let (Some(stored_issuer), Some(current_issuer)) =
(stored.issuer.as_deref(), self.metadata_issuer().as_deref())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SEP-2352 explicitly says CIMD client IDs "are portable across authorization servers … No re-registration is required." The mismatch check here doesn't distinguish credential types.

token_response,
granted_scopes,
token_received_at,
issuer: None,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How can external CredentialStore implementors set issuer?

Comment on lines +1078 to +1081
if stored_issuer != current_issuer {
self.credential_store.clear().await?;
return Ok(false);
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clearing stored credentials is destructive. Should we add a warning log here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T-core Core library changes T-transport Transport layer changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement SEP-2352: Clarify authorization server binding and migration

2 participants