-
Notifications
You must be signed in to change notification settings - Fork 1.2k
SEP-985: Updating the Authorization spec to fallback to WWW-Authenticate when Protected Resource Metadata is not found #971
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SEP-985: Updating the Authorization spec to fallback to WWW-Authenticate when Protected Resource Metadata is not found #971
Conversation
|
I need to think a bit more deeply about this, but I almost feel like a @aaronpk @D-McAdams - thoughts? |
agree with @localden i think it might be better to enforce this for now. Philosophically, imo it is not necessary we be as open as the RFC i.e. we are a specific implementation of OAuth and hence can be more opinionated. |
|
As it stands, the MCP spec requires OAuth and OAuth mechanisms. If I'm understanding correctly, the proposal suggests making these OAuth components optional to accommodate situations where OAuth isn't being used. However, without a compelling use case that aligns with the spec's core security and interoperability goals, I don't believe we should modify the specification to make these requirements optional. |
|
This should be a Specification Enhancement Proposal tracked as an Github issue with this PR associated. |
b4c2c14 to
5ca0394
Compare
5ca0394 to
1a47dab
Compare
…Protected Resource Metadata is not found
1a47dab to
9cd99f4
Compare
|
Can we make this a MUST implement one of the following w/ WWW-Authenticate being one of the options? Would rather have a very clear / fixed set of options. |
|
I've made the changes to make the MUST clearer for the server, and updated the mermaid diagram similarly. @sunishsheth2009 can you check this works for you? @000-000-000-000-000 can you check the wording on this? |
Yes this makes sense to me. :) Thank you for the updating it. |
pcarleton
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Marking approved, this was voted on via async discord poll by the core-maintainers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be beneficial to specify an order of precedence for MCP Clients. As written, it says "MCP clients MUST support both discovery mechanisms..." and that would leave ambiguity on whether implementations must query all possible locations and reconcile conflicting results. I believe the desired order of preference is (1) Use the WWW-Authenticate information if it exists in the HTTP 401, (2) Else, fallback to the Well-Known URI the sub-path, (3) Finally, fallback to the Well-Known URI at the root.
|
|
||
| 2. **Well-Known URI**: Serve metadata at a well-known URI as specified in [RFC9728](https://datatracker.ietf.org/doc/html/rfc9728). This can be either: | ||
| - At a sub-path: `https://example.com/.well-known/oauth-protected-resource/mcp` | ||
| - At the root: `https://example.com/.well-known/oauth-protected-resource` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this fallback logic to the root part of RFC9728? Or, is this included because implementations haven't conformed to RFC9728 and we're practically adapting to that? I'd question this more if we're deviating from RFC9728 in order to meet non-compliant implementations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 to what @D-McAdams mentioned here - this feels like an "either or" choice that really should not be here, no? The metadata location should correspond to the server location.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good question. My understanding is that it is compliant with RFC9728, and makes it more explicit which "resource identifier" values MCP will consider. If we didn't have implementations with it at the root, I think we would leave it out.
Protected resources supporting metadata MUST make a JSON document containing metadata as specified in Section 2 available at a URL formed by inserting a well-known URI string into the protected resource's resource identifier between the host component and the path and/or query components, if any. By default, the well-known URI string used is /.well-known/oauth-protected-resource.
From what I understand, and from discussing with @aaronpk , the definition "resource identifier" in RFC 9728 is what this hinges on, which can vary and is not necessarily the MCP server URL (e.g. it can be at the root or at the /mcp path).
In a multi-tenant environment, I need to specify a resource identifier with a path in order to separate access between tenants. In a single tenant environment, I can choose which resource identifier makes the most sense for me, it might either be at the root of my domain, or it might be at the /mcp path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dumped some previous discussions on this in to this discord thread, but tl;dr is that I believe that "specific path" then "root" as written is compliant with RFC 9728 and RFC 8707
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@D-McAdams / @dend
I think realistically SDK's will need to support the fallback since the spec was ambiguous before this and many assumed the root was the proper place. I'd prefer then to have the spec be descriptive.
based on everything above, what's your take?
Should we be strict or lax here? i.e. require using the most specific, or allow a fallback to root?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'm OK with the fallback. For this to go wrong in production and result in an exploit, the server needs to make two mistakes: Forget to host a PRM document of it's own, and not validate the 'aud' in the token it subsequently receives.
|
|
||
| 2. **Well-Known URI**: Serve metadata at a well-known URI as specified in [RFC9728](https://datatracker.ietf.org/doc/html/rfc9728). This can be either: | ||
| - At a sub-path: `https://example.com/.well-known/oauth-protected-resource/mcp` | ||
| - At the root: `https://example.com/.well-known/oauth-protected-resource` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 to what @D-McAdams mentioned here - this feels like an "either or" choice that really should not be here, no? The metadata location should correspond to the server location.
Co-authored-by: Den Delimarsky <hi@den.dev>
Co-authored-by: Geoff Goodman <ggoodman@gmail.com>
|
Could I get a restamp @localden / @D-McAdams ? |
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)
Updating the Authorization spec to fallback to WWW-Authenticate when Protected Resource Metadata is not found
Motivation and Context
According to the current spec, it is a MUST to implement the OAuth 2.0 Protected Resource Metadata which aligns with the RFC.
Also according to the current spec,
it is a MUST to use the HTTP headerWWW-Authenticatewhen returning a _401 Unauthorized_ to indicate the location of the resource server metadata URL.This might not aligned with the RFC which states that:
A protected resource MAY use the WWW-Authenticate HTTP response header field, as discussed in RFC9110, to return a URL to its protected resource metadata to the client.Rationale
Many large-scale, dynamic, multi-tenant environments rely on a centralized authentication service separate from the backend resource servers. In such deployments, injecting WWW-Authenticate headers from backend services is non-trivial due to separation of concerns and infrastructure complexity.
In these scenarios, having the option to discover metadata via a well-known URL provides a practical path forward for easier MCP adoption. Requiring only the header would impose significant communication overhead between components, especially when hundreds or thousands of MCP instances are created and destroyed dynamically. Also if there are specific managed MCP servers, adopting headers across centralized system would add significant overhead.
While this increases complexity for clients—who must now implement logic to probe metadata endpoints—it reduces friction for server deployments and may encourage broader adoption. There are tradeoffs:
Pros for Server Developers: Avoid complex header injection; simplifies integration in distributed environments.
Cons for Client Developers: Clients must fall back to metadata discovery logic when the header is absent, increasing client complexity.
Proposed State
Update the MCP spec to:
The reason for deviating a bit on the RFC:
Go with SHOULD over MAY for WWW-Authenticate is that it makes supporting other features, such as incremental authorization easier (e.g. you make a request for a tool, but need additional scopes, and receive a WWW-Authenticate challenge indicating the scopes).
Based on the above, following the updated flow:
This change allows more flexible deployment models without removing existing capabilities.
How Has This Been Tested?
Have you tested this in a real application? Which scenarios were tested?
Updating the spec according to the RFC
Breaking Changes
Will users need to update their code or configurations?
Yes some clients would need to update if they solely rely on WWW-Authenticate header and rather use this as a fallback instead.
Types of changes
Checklist
Additional context