Skip to content

feat: enhance auth server discovery with OAuth2 and OpenID metadata support #797

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

xiaoyijun
Copy link
Contributor

Add OpenID Connect Discovery Support for Authorization Server Discovery

Note: this PR reopens #677

Motivation and Context

This PR enhances the authorization server discovery mechanism by adding support for OpenID Connect Discovery 1.0 alongside the existing OAuth 2.0 Authorization Server Metadata.

OpenID Connect (OIDC) is built on top of OAuth 2.0, extending it with standardized identity functionality. Many modern authorization servers implement OIDC as their primary protocol, making it crucial for MCP to support both discovery mechanisms. Popular authorization providers such as Keycloak, Auth0, and Logto all implement OIDC discovery by default.

Key benefits:

  • Better compatibility with OIDC-based authorization servers
  • Maintains full OAuth 2.0 compatibility since OIDC is an extension of OAuth 2.0
  • Enables seamless integration with popular identity providers
  • No breaking changes to existing OAuth 2.0 implementations

How Has This Been Tested?

N/A

Breaking Changes

None. This change is fully backwards compatible:

  • Existing OAuth 2.0 metadata discovery continues to work as before
  • Authorization servers can choose which discovery mechanism to implement
  • MCP clients must support both mechanisms but will automatically use the correct one

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

The addition of OIDC discovery support is particularly valuable because:

  1. OIDC is the de-facto standard for modern identity providers
  2. The .well-known/openid-configuration endpoint is widely supported
  3. OIDC providers automatically support OAuth 2.0 flows since OIDC is built on top of OAuth 2.0
  4. This enables MCP to work seamlessly with popular authorization servers like Keycloak, Auth0, and Logto without additional configuration
@joshcanhelp
Copy link

joshcanhelp commented Jun 19, 2025

$0.02 on this ... I 100% support the OIDC metadata fallback but RFC8414 already mentions this fallback. Supporting that RFC fully would mean that the fallback support is required and wouldn't need to be spelled out explicitly. I think the spec could say something to the effect of:

MUST support RFC8414 to provide at least one mechanism for obtaining AS metadata

... or thereabouts. Edit: Latest spec (2025-06-18) feels like it gets the wording right:

https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization#server-metadata-discovery

Maybe the diagram could note the fallback but that's not critical in my mind. Original wording was too prescriptive and current is definitely an improvement.

Related PRs/discussions:

@xiaoyijun
Copy link
Contributor Author

Hi @joshcanhelp thank you for the feedback and suggestions.

However, I believe that treating “support for RFC 8414” as a blanket requirement misses a key architectural consideration, for the following reasons:

As you noted, Section 3 of RFC 8414 states:

Different applications utilizing OAuth authorization servers in application-specific ways may define and register different well-known URI suffixes used to publish authorization server metadata as used by those applications.

The spec mentions that for an auth server used by a specific application (e.g., "example"), its metadata endpoint could be /.well-known/example-configuration. This is for application-specific scenarios. This approach introduces a new challenge: you would need a clearer way for developers to know how to construct this URL from an application's identifier, which would require more specification work to guide auth server discovery.

For the MCP spec, considering its goal of ecosystem compatibility (to adapt to general-purpose auth servers), the more appropriate choice is the default discovery endpoint, which RFC 8414 also mentions:

...many such applications will use the default well-known URI string “/.well-known/oauth-authorization-server”, which is the right choice for general-purpose OAuth authorization servers, and not register an application-specific one.

Regarding /.well-known/openid-configuration, the RFC states:

Some OAuth applications will choose to use the well-known URI suffix “openid-configuration”. As described in Section 5, despite the identifier “/.well-known/openid-configuration”, appearing to be OpenID specific, its usage in this specification is actually referring to a general OAuth 2.0 feature that is not specific to OpenID Connect.

So, from the perspective of RFC 8414, there isn't really an "OIDC concept" at play here. The name openid-configuration is just a string that happens to fit the example-configuration pattern.

This distinction frames our decision as a choice between two architectural paths:

  1. (The path I rejected): The application-specific route. This would introduce unnecessary complexity by forcing us to define how clients discover these custom URLs.
  2. (The path I chose): Supporting a widely adopted, de facto industry standard (OIDC Discovery). This is a pragmatic and robust choice for our ecosystem.

This PR deliberately chooses the second path.

@localden @aaronpk @D-McAdams I'd be interested to hear your point of view on this.

@joshcanhelp
Copy link

joshcanhelp commented Jun 23, 2025

At the end of the day, we want these applications to be able to get the authorization server metadata so they're able to log in. Whether it's one of specific URLs stated or an application-specific one doesn't matter. I don't think we should be deciding that one of those two paths, both of which are currently being used, is the right way when the goal is the same. The question, in my mind, is ... does allowing the application-specific path limit this in any way or affect developers that aren't using it? The RFC solves the problem, I suggest we just point there and leave it at that.

Appreciate the thoughtful conversation, either way!

@pwwpche
Copy link

pwwpche commented Jun 24, 2025

At the end of the day, we want these applications to be able to get the authorization server metadata so they're able to log in. Whether it's one of specific URLs stated or an application-specific one doesn't matter. I don't think we should be deciding that one of those two paths, both of which are currently being used, is the right way when the goal is the same. The question, in my mind, is ... does allowing the application-specific path limit this in any way or affect developers that aren't using it? The RFC solves the problem, I suggest we just point there and leave it at that.

Appreciate the thoughtful conversation, either way!

If I understand correctly from RFC 8414:

The well-known URI suffix used MUST be registered in the IANA "Well-Known URIs" registry

This limits that even for application-specific URLs, they have to be listed in IANA. Also regarding allowing application specific path (that may not be on the IANA list), could you suggest a few use cases? I'm struggling to understand the value it provides, given that OIDC is the de-facto standard for modern identity providers.

@pwwpche
Copy link

pwwpche commented Jun 24, 2025

@xiaoyijun
This looks great to me, thanks for putting it up!

Regarding a remaining question from previous PR:

how clients should handle the difference in fields between OICD and OAuth 2.0 AS metadata

AS Metadata and OIDC config requires different fields. See the comparison that @localden shared:
https://gist.github.com/localden/26d8bcf641703c08a5d8741aa9c3336c

I've took a glance and it doesn't seem to me that supporting OIDC requires handling the difference. However could you help with a second eye on checking if any of the differences are required by Auth implementations like modelcontextprotocol/python-sdk@17f9c00?

- OAuth 2.0 Authorization Server Metadata ([RFC8414](https://datatracker.ietf.org/doc/html/rfc8414))
- [OpenID Connect Discovery 1.0](https://openid.net/specs/openid-connect-discovery-1_0.html)

MCP clients **MUST** support both discovery mechanisms to obtain the information required to interact with the authorization server.
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need guidance on how to support both simultaneously in a client?

For example, is it safe for an SDK to automatically fall back from RFC8414 to OIDC 1.0 if one isn't present? Is the discovery mechanism allowed to be implicit at all, or should it always be explicit? Does it matter which one we check first, and is it acceptable for SDKs to diverge in that behavior?

SDKs will likely diverge here if this isn't specified, but I'm not sure if that's acceptable or not.

Copy link
Contributor

Choose a reason for hiding this comment

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

Similarly, supporting OIDC 1.0 and RFC8414 in the same code path requires a third step when the OIDC metadata is not hosted at the base URL. As noted in section 5 of RFC 8414:

However, when deployed in legacy environments in which the OpenID Connect Discovery 1.0 transformation is already used, it may be necessary during a transition period to publish metadata for issuer identifiers containing a path component at both locations. During this transition period, applications should first apply the transformation defined in this specification and attempt to retrieve the authorization server metadata from the resulting location; only if the retrieval from that location fails should they fall back to attempting to retrieve it from the alternate location obtained using the transformation defined by OpenID Connect Discovery 1.0.

This means that if I have OIDC metadata located at https://example.com/issuer1/.well-known/openid-configuration instead of https://example.com/.well-known/openid-configuration/issuer1, I might have a query order like this for an issuer https://example.com/issuer1:

  1. https://example.com/.well-known/oauth-authorization-server/issuer1 (RFC8414 metadata)
  2. https://example.com/.well-known/openid-configuration/issuer1 (OIDC 1.0 metadata following RFC8414 conventions)
  3. https://example.com/issuer1/.well-known/openid-configuration (OIDC 1.0 metadata following OIDC 1.0 conventions)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi @LucaButBoring , thanks for your thorough analysis.

You're absolutely right that the current specification creates ambiguity around client implementation, which could lead to interoperability issues between different SDKs.

I'm currently working on updating the specification to cover the metadata discovery flow more comprehensively.

@pavinduLakshan
Copy link

$0.02 on this ... I 100% support the OIDC metadata fallback but RFC8414 already mentions this fallback. Supporting that RFC fully would mean that the fallback support is required and wouldn't need to be spelled out explicitly. I think the spec could say something to the effect of:

@joshcanhelp I doubt falling back to OIDC discovery is same as the fallback mentioned in the authorization server metadata spec. This is much noticeable in scenarios where issuer has a path component. The Authz server metadata spec defines the URL to be /.well-known/example-configuration/issuer-path-components[1], while OIDC spec defines it as issuer-path-components/.well-known/oidc-configuration[2].

[1] https://datatracker.ietf.org/doc/html/rfc8414#:~:text=formed%20by%20inserting%0A%20%20%20%22/.well%2Dknown/example%2Dconfiguration%22%20between%20the%20host%20and%20path%0A%20%20%20components%20of%20the%20authorization%20server%27s%20issuer%20identifier.
[2] https://openid.net/specs/openid-connect-discovery-1_0.html#:~:text=%C2%A0TOC-,4.1.%C2%A0%20OpenID%20Provider%20Configuration%20Request,-An%20OpenID%20Provider%27s

@xiaoyijun xiaoyijun force-pushed the spec-support-oidc-discovery branch from 29720c3 to f23c328 Compare July 3, 2025 08:31
@xiaoyijun
Copy link
Contributor Author

Hi @LucaButBoring , thanks for your review, I’ve updated the spec to address your concerns, PTAL. ❤️

@xiaoyijun xiaoyijun requested a review from LucaButBoring July 3, 2025 08:34
@softnado
Copy link

softnado commented Jul 4, 2025

$0.02 on the subject.

https://modelcontextprotocol.io/specification/draft/basic/authorization#sequence-diagram

Current Auth Server discovery sequence require /.well-known/oauth-authorization-server be hosted under Auth Server domain.
Which is not supported and isn't practical in my opinion for Enterprise Auth Server like Microsoft Entra.
For such centralized and shared Auth Server, it is more practical for Resource Server owner to host the /.well-known/oauth-authorization-server or alternative metadata and ensure its correctness for discovery.

Plus, it opens the possibilities for Resource Server to provide its own Dynamic Client Registration Endpoint while other Endpoints remain pointed to the Enterprise Auth Server.
It reduces the need of create wrapping or re-create Auth Endpoints under Resource Server domain (Which usually isn't allowed under Enterprise Scenario). And the custom Dynamic Client Registration Endpoint give more control to Resource Owner for auditing, also unblock scenario when the compliant Enterprise Auth Server doesn't support Dynamic Client Registration yet. (In that situation, the client returned can be proactively created and permission scoped by Resource Server owner)

Looking forward to learning more about your thoughts and other common Enterprise Auth Server support of this scenario.

@pavinduLakshan
Copy link

pavinduLakshan commented Jul 4, 2025

For such centralized and shared Auth Server, it is more practical for Resource Server owner to host the /.well-known/oauth-authorization-server or alternative metadata and ensure its correctness for discovery.

Please Correct me if Im missing something, but isn't this already covered by the protected resource metadata spec[1]?

[1] https://datatracker.ietf.org/doc/rfc9728/

@softnado
Copy link

softnado commented Jul 4, 2025

For such centralized and shared Auth Server, it is more practical for Resource Server owner to host the /.well-known/oauth-authorization-server or alternative metadata and ensure its correctness for discovery.

Please Correct me if Im missing something, but isn't this already covered by the protected resource metadata spec[1]?

[1] https://datatracker.ietf.org/doc/rfc9728/

It depends on the Auth Server required by Enterprise Context, for Auth Server like Microsoft Entra, there is no support for /.well-known/oauth-authorization-server, and personally I believe that is not practical for such Auth Server which targeted for multi tenants/enterprises.

The current spec's assumption of Auth Server I believe assumed the Auth Server have strong flexibility to the Resource Server owner which isn't the case for Enterprise Scenarios.

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