feat: implement SEP-985 OAuth 2.0 Protected Resource Metadata fallback - #1045
Closed
cbcoutinho wants to merge 5 commits into
Closed
cbcoutinho wants to merge 5 commits into
cbcoutinho wants to merge 5 commits into
Conversation
Aligns OAuth 2.0 Protected Resource Metadata handling with RFC 9728 and SEP-985 by making the WWW-Authenticate header optional and implementing graceful fallback behavior. Changes: - Updated discoverOAuthProtectedResourceMetadata() to return undefined instead of throwing on 404, making protected resource metadata optional - Enhanced JSDoc comments to document SEP-985 fallback behavior - Updated authInternal() to handle optional metadata with proper null checks - Added comprehensive test suite for SEP-985 scenarios: - WWW-Authenticate header with resource_metadata present - WWW-Authenticate header without resource_metadata (fallback to well-known) - Missing WWW-Authenticate header (fallback to well-known) - 404 on well-known endpoint (graceful degradation) - CORS errors on metadata discovery (graceful fallback) - Updated existing tests to expect undefined instead of errors on 404 Per SEP-985, clients now: 1. Check WWW-Authenticate header for resource_metadata parameter 2. Fallback to /.well-known/oauth-protected-resource if not present 3. Continue gracefully using the MCP server as auth server if metadata unavailable All 856 tests pass. Related: modelcontextprotocol#920 Implements: SEP-985 (modelcontextprotocol/modelcontextprotocol#971)
…e Metadata Implements proper scope selection priority per MCP OAuth spec: 1. Explicit scope parameter (user override) 2. WWW-Authenticate challenge scope (authoritative per spec) 3. Protected Resource Metadata scopes_supported 4. Client default scope Changes: - Add extractChallengeScope() to parse scope from WWW-Authenticate header - Add selectScopes() helper with priority logic - Update auth(), authInternal() to accept and use challengeScope - Update SSE, StreamableHTTP, and middleware transports to extract and pass challenge scope - Add comprehensive tests for extractChallengeScope() and scope selection priority All 869 tests passing.
Member
|
@cbcoutinho hey this PR is redundant now, apologies for the delay and mix up, there were several tackling similar areas of the code. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation and Context
This PR addresses two OAuth-related improvements:
SEP-985 Implementation: Aligns OAuth 2.0 Protected Resource Metadata handling with RFC 9728 by making the WWW-Authenticate header optional and implementing graceful fallback behavior.
Scope Handling Fix: Fixes bug where MCP clients don't respect scope parameters from WWW-Authenticate headers and Protected Resource Metadata, as specified in the MCP OAuth specification.
Changes
SEP-985: Optional Protected Resource Metadata
discoverOAuthProtectedResourceMetadata()to returnundefinedinstead of throwing on 404, making protected resource metadata optionalauthInternal()to handle optional metadata with proper null checksPer SEP-985, clients now:
resource_metadataparameter/.well-known/oauth-protected-resourceif not presentScope Priority Implementation
extractChallengeScope()to parse scope from WWW-Authenticate header per RFC 6750selectScopes()helper implementing proper scope selection priority:scopes_supportedauth()andauthInternal()signatures to acceptchallengeScopeparameterscopes_supportedarray is now properly joined with spacesThis directly addresses the requirements from #672:
scopes_supportedfrom Protected Resource MetadataTest Coverage
Added comprehensive test suites:
SEP-985 tests (4 scenarios):
extractChallengeScope() tests (7 scenarios):
Scope selection priority tests (6 scenarios):
How Has This Been Tested?
$ npm testAll 869 tests pass (13 new tests added).
Related Issues
Fixes: #672
Related: #920
Implements: SEP-985 (modelcontextprotocol/modelcontextprotocol#971)
Breaking Changes
None - all changes are backward compatible and maintain existing behavior when new parameters are not provided.
Types of changes
Checklist
Additional Context
The scope handling implementation follows the MCP OAuth specification's requirements for Protected Resource Metadata discovery. The WWW-Authenticate
scopeparameter is now properly extracted and prioritized over other scope sources, ensuring clients request the correct scopes as dictated by the authorization server.