Skip to content

fix(auth): add an SDK path for pre-registered OAuth clients#994

Merged
jamadeo merged 1 commit into
mainfrom
auth-pre-reg-check-fails
Jul 18, 2026
Merged

fix(auth): add an SDK path for pre-registered OAuth clients#994
jamadeo merged 1 commit into
mainfrom
auth-pre-reg-check-fails

Conversation

@jamadeo

@jamadeo jamadeo commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

... and exercise it in conformance tests

fixes #984

Motivation and Context

The sdk didn't have a high-level path for preregistered oauth clients, so the conformance client implemented it in a more custom way, which didn't pick up the iss-parameter preservation.

How Has This Been Tested?

Ran the conformance client.

Breaking Changes

None

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

@jamadeo
jamadeo requested a review from a team as a code owner July 15, 2026 16:15
@github-actions github-actions Bot added T-core Core library changes T-transport Transport layer changes labels Jul 15, 2026
Comment thread crates/rmcp/src/transport/auth.rs Outdated
Comment thread crates/rmcp/src/transport/auth.rs Outdated
/// dynamic client registration and URL-based client IDs.
///
/// The manager must already have discovered authorization server metadata.
pub async fn with_preregistered_client(

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.

The same impl currently exposes new and for_scope_upgrade. While with_* is valid Rust naming, the three constructors do not seem to communicate an obvious shared convention. I was just thinking we could clean up the API, since v3 allows us to make breaking changes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, good point, we should take the opportunity. Probably best in a follow-up PR - what do you think? What's your preferred convention?

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.

My preference would be a single AuthorizationSession::new(...) plus chained builder methods for the optional parts. Same shape as OAuthClientConfig.

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.

/// out of band and already holds a `client_id` (and optionally a
/// `client_secret`). If `config.scopes` is empty, scopes are selected
/// from the discovered authorization server metadata.
pub async fn start_authorization_with_preregistered_client(

@DaleSeo DaleSeo Jul 16, 2026

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.

Could we add targeted tests using the existing recording HTTP client to verify that this path skips the registration endpoint, handles default and explicit scopes, and etc? Those tests would isolate the new orchestration from the broader conformance harness. e.g.

#[tokio::test]
async fn custom_http_client_handles_registration_exchange_and_refresh() {

/// out of band and already holds a `client_id` (and optionally a
/// `client_secret`). If `config.scopes` is empty, scopes are selected
/// from the discovered authorization server metadata.
pub async fn start_authorization_with_preregistered_client(

@DaleSeo DaleSeo Jul 16, 2026

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.

The draft authorization spec recommends the priority pre-registered client information → CIMD → DCR, but the current API exposes these choices through separate entry points. In particular, start_authorization() passes no metadata URL and therefore cannot take the preferred CIMD path, while start_authorization_with_metadata_url() is the method that actually implements CIMD with DCR fallback. This PR understandably extends that pattern with another mechanism-specific method, but we might want to consolidates these paths behind one start_authorization API. This is out of scope and non-blocking for this PR. Let me know what you think, and we can follow up on this separately.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

That makes sense to me. Probably a good thing to do jointly along with cleaning up the API as you suggested in the above comment.

Opened: #1006

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.

@jamadeo Sounds good! Let's fast-follow on this so we can include it in v3 alongside the other breaking changes.

... and exercise it in conformance tests
@jamadeo
jamadeo force-pushed the auth-pre-reg-check-fails branch from 0a82f65 to 9e87e9b Compare July 17, 2026 16:20
let placeholder = self.placeholder().await?;
if let OAuthState::Unauthorized(mut manager) = std::mem::replace(self, placeholder) {
debug!("start discovery");
let metadata = manager.discover_metadata().await?;

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.

Should the same recovery pattern be applied to the existing paths too?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yep, that makes sense. Added to #1006

@jamadeo
jamadeo merged commit 7d811c4 into main Jul 18, 2026
21 checks passed
@jamadeo
jamadeo deleted the auth-pre-reg-check-fails branch July 18, 2026 01:20
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.

auth/pre-registration: new pre-registration-auth conformance check fails

2 participants