Skip to content

feat: accumulate client-side scopes during step-up authorization (SEP-2350)#888

Open
stefanoamorelli wants to merge 1 commit into
modelcontextprotocol:mainfrom
stefanoamorelli:worktree-sep-2350-scope-accumulation
Open

feat: accumulate client-side scopes during step-up authorization (SEP-2350)#888
stefanoamorelli wants to merge 1 commit into
modelcontextprotocol:mainfrom
stefanoamorelli:worktree-sep-2350-scope-accumulation

Conversation

@stefanoamorelli
Copy link
Copy Markdown
Contributor

@stefanoamorelli stefanoamorelli commented Jun 4, 2026

Closes #877

Motivation and Context

SEP-2350 makes scope accumulation a client responsibility. A 403 / insufficient_scope challenge carries only the scopes for the current operation (RFC 6750 §3.1), so on re-authorization the client must request the union of what it asked for before and what was just challenged.

select_base_scopes() returned a single source, so a challenge replaced the earlier scopes instead of widening them, and step-up dropped previously granted permissions (the auth/scope-step-up conformance test failed for this). This PR unions current_scopes, the WWW-Authenticate challenge, and the resource metadata scopes (RFC 9728); defaults only seed the first request. On exchange, an explicit scope list stays authoritative so a server can still narrow the grant, but when the server omits scope (RFC 6749 §5.1) the accumulated set is retained rather than cleared.

How Has This Been Tested?

Added unit tests for multi-round accumulation, union-not-replace, dedup of an already-requested challenge, and resource metadata accumulation. The rmcp suite passes with the auth feature, and cargo +nightly fmt --all and clippy are clean.

Breaking Changes

No API changes. The behavior change is required by the SEP: re-authorization requests the union of prior and challenged scopes. exchange_code_for_token still honors an explicit downgrade from the server and only retains the accumulated set when the server omits scope, so a previously granted scope is not reported back unless the server kept granting it.

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

This is the client half of SEP-2350; server-side per-operation scope reporting is out of scope for the SDK. No new error handling was needed since the change only widens the requested set.

@stefanoamorelli stefanoamorelli requested a review from a team as a code owner June 4, 2026 17:59
@github-actions github-actions Bot added T-core Core library changes T-transport Transport layer changes labels Jun 4, 2026
SEP-2350 [1] clarifies that scope accumulation is a client-side
responsibility: during re-authorization the client requests the union of
its previously requested scopes and the newly challenged scopes, because
servers report only the scopes needed for the current operation in
403 / insufficient_scope challenges (RFC 6750 §3.1), not the union of
everything granted so far.

select_base_scopes returned a single source, so a 403 challenge replaced
the previously requested scopes instead of widening them, dropping prior
permissions across step-up rounds. I make it union the previously
requested scopes, the WWW-Authenticate challenge, and the protected
resource metadata scopes (RFC 9728), treating each server-reported set as
an operational requirement for the current operation rather than an
exclusive directive; AS metadata and caller defaults only seed the
request when nothing has been requested or challenged yet.

exchange_code_for_token treats an explicit scope list as authoritative,
so a server may still narrow the grant, but retains the accumulated set
when the server omits scope (RFC 6749 §5.1) rather than clearing it.
Deduplication preserves first-seen order for stable, testable output.
Tests cover multi-round accumulation, dedup, and resource-metadata
unioning. Implements [2].

[1]: https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/docs/specification/draft/basic/authorization.mdx#L682
[2]: modelcontextprotocol#877

Signed-off-by: Stefano Amorelli <stefano@amorelli.tech>
@stefanoamorelli stefanoamorelli force-pushed the worktree-sep-2350-scope-accumulation branch from 94c4a47 to 563280f Compare June 4, 2026 18:05
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-2350: Clarify client-side scope accumulation (step-up auth)

1 participant