Expose valid scopes from OAuthProxy metadata (#1717)

Co-authored-by: Jeremiah Lowin <153965+jlowin@users.noreply.github.com>
This commit is contained in:
Daniel Mikusa 2025-09-03 10:34:29 -04:00 committed by GitHub
commit 598a37e6c9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 16 additions and 1 deletions

View file

@ -242,6 +242,7 @@ class OAuthProxy(OAuthProvider):
service_documentation_url: AnyHttpUrl | str | None = None,
# Client redirect URI validation
allowed_client_redirect_uris: list[str] | None = None,
valid_scopes: list[str] | None = None,
):
"""Initialize the OAuth proxy provider.
@ -262,9 +263,14 @@ class OAuthProxy(OAuthProvider):
If None (default), only localhost redirect URIs are allowed.
If empty list, all redirect URIs are allowed (not recommended for production).
These are for MCP clients performing loopback redirects, NOT for the upstream OAuth app.
valid_scopes: List of all the possible valid scopes for a client.
These are advertised to clients through the `/.well-known` endpoints. Defaults to `reuqired_scopes` if not provided.
"""
# Always enable DCR since we implement it locally for MCP clients
client_registration_options = ClientRegistrationOptions(enabled=True)
client_registration_options = ClientRegistrationOptions(
enabled=True,
valid_scopes=valid_scopes or token_verifier.required_scopes,
)
# Enable revocation only if upstream endpoint provided
revocation_options = (

View file

@ -55,6 +55,10 @@ class TestOAuthProxyComprehensive:
assert str(proxy.base_url) == "https://api.example.com/"
assert str(proxy.issuer_url) == "https://issuer.example.com/"
assert str(proxy.service_documentation_url) == "https://docs.example.com/"
assert (
proxy.client_registration_options is not None
and proxy.client_registration_options.valid_scopes == ["read", "write"]
)
def test_initialization_with_all_parameters(self, jwt_verifier):
"""Test OAuthProxy initialization with all optional parameters."""
@ -69,6 +73,7 @@ class TestOAuthProxyComprehensive:
redirect_path="/auth/callback",
issuer_url="https://issuer.example.com",
service_documentation_url="https://docs.example.com",
valid_scopes=["open", "close"],
)
# Verify all parameters are set correctly
@ -83,6 +88,10 @@ class TestOAuthProxyComprehensive:
assert proxy._redirect_path == "/auth/callback"
assert str(proxy.issuer_url) == "https://issuer.example.com/"
assert str(proxy.service_documentation_url) == "https://docs.example.com/"
assert (
proxy.client_registration_options is not None
and proxy.client_registration_options.valid_scopes == ["open", "close"]
)
def test_redirect_path_normalization(self, jwt_verifier):
"""Test that redirect_path is normalized to start with /."""