-
Notifications
You must be signed in to change notification settings - Fork 3.1k
feat(auth): add unified auth protocol discovery and optional DPoP support #2003
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
Closed
nypdmax
wants to merge
72
commits into
modelcontextprotocol:main
from
nypdmax:pr/auth-ext-cherrypick
Closed
feat(auth): add unified auth protocol discovery and optional DPoP support #2003
nypdmax
wants to merge
72
commits into
modelcontextprotocol:main
from
nypdmax:pr/auth-ext-cherrypick
+9,184
−311
Conversation
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
…, WWW-Authenticate extensions
…iProtocolAuthProvider
…protocol, protocol_preferences
…vers_discovery_routes
…ig for examples/clients - Add examples/clients/simple-auth-multiprotocol-client (API Key + mTLS placeholder) - Pyright: include examples/clients; executionEnvironments + extraPaths for client packages - Fixes import resolution for mcp_simple_auth_multiprotocol_client.main in __main__.py
…rotocol integration test script - APIKeyVerifier: optional scopes param for AccessToken (satisfy required_scopes) - simple-auth-multiprotocol: build_multiprotocol_backend(api_key_scopes=[mcp_scope]) - scripts/run_phase2_multiprotocol_integration_test.sh: api_key (default), oauth (AS+RS+simple-auth-client), mutual_tls (placeholder)
…lign resource_metadata_url with 401 branch
…d optional http_client to discover_metadata
…erator and storage - Add DPoPKeyPair for ES256/RS256 key generation with configurable RSA key size - Add DPoPProofGeneratorImpl for generating DPoP proof JWTs per RFC 9449 - Add InMemoryDPoPStorage for key pair persistence - Add compute_jwk_thumbprint for RFC 7638 JWK Thumbprint calculation - Include comprehensive unit tests (12 test cases)
Add DPoPProofVerifier for validating DPoP proof JWTs per RFC 9449 Section 4.3, including replay protection, claim validation, and JWK thumbprint verification.
Add DPoP support to OAuth2Protocol implementing DPoPEnabledProtocol, inject DPoP proofs via MultiProtocolAuthProvider, and verify DPoP-bound tokens in OAuthTokenVerifier.
Add --dpop-enabled CLI flag and integrate DPoPProofVerifier with MultiProtocolAuthBackend for end-to-end DPoP verification.
- Add scripts/run_phase4_dpop_integration_test.sh for automated DPoP tests - Update test_oauth2_protocol: expect OAuthFlowError when http_client is None - Update simple-auth-multiprotocol-client: OAuth+DPoP support, InMemoryStorage - Update simple-auth-multiprotocol: DPoP logging, oauth2 protocol_version 2.0
- Add _oauth_401_flow.py: oauth_401_flow_generator, oauth_403_flow_generator - Refactor OAuthClientProvider.async_auth_flow to drive shared generators - Refactor MultiProtocolAuthProvider 401 handling to use shared OAuth flow - Fix OAuth2Protocol.authenticate to use fresh client when called outside flow - Fix OAuthTokenVerifier: use scope for HTTP method (HTTPConnection compat)
Prefer only locally injected protocol instances when selecting the auth protocol, and ensure the final response corresponds to the original request (avoid leaking discovery responses).
Add regression tests ensuring 401 handling falls back when the server default protocol isn't injected, and that discovery responses are never returned as the business request response.
Make api_key and mutual_tls runs non-interactive with clear PASS/FAIL, add oauth_dpop mode wiring, and allow forcing mutual_tls protocol injection for placeholder coverage.
…eAdapter and unit tests
…odule Centralize 5 server variants into a single VariantConfig-driven implementation; reduce variant packages to thin shims. Delete 8 redundant multiprotocol.py/token_verifier.py files.
…covery order
Fix path-relative URL to /.well-known/authorization_servers{path}.
Refactor async_auth_flow to try path-relative then root discovery
sequentially before falling back to PRM.
25787aa to
7a2e591
Compare
Contributor
|
Thanks for the effort here, but this is a very large PR introducing spec extensions without prior maintainer approval. Per our contributing guidelines, please open an issue first and get maintainer buy-in before submitting PRs of this scope. Features that touch the protocol (like new auth discovery mechanisms and DPoP) would also need a SEP. |
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 adds multi-protocol authentication support to the MCP Python SDK, centered around unified authorization
server discovery so clients can discover, select, and apply one of multiple supported auth protocols consistently.
Key capabilities:
/.well-known/authorization_serversplus RFC 9728 PRM fallback.oauth2,api_key) with optional default protocol andpreferences.
FastMCPcompatibility wrapper used by examples and updates multiprotocol examples.How Has This Been Tested?
Unit/integration tests:
PYTEST_DISABLE_PLUGIN_AUTOLOAD="" uv run --frozen pytestLint / typecheck:
uv run --frozen ruff format --check .uv run --frozen ruff check .uv run --frozen pyrightE2E examples (manual OAuth flow):
./examples/clients/simple-auth-multiprotocol-client/run_multiprotocol_test.sh./examples/clients/simple-auth-multiprotocol-client/run_dpop_test.sh./examples/clients/simple-auth-multiprotocol-client/run_oauth2_test.shSpec compliance notes (additive extensions)
This PR keeps MCP Authorization (2025-06-18) OAuth behavior intact (RFC 9728 PRM + RFC 8414 metadata + RFC 8707
resource indicators). It also adds optional extensions to support multi-protocol auth and stronger token binding:
Multi-protocol selection (extension):
/.well-known/authorization_serversendpoint (best-effort; client falls back if missing).mcp_auth_protocols,mcp_default_auth_protocol,mcp_auth_protocol_preferences.WWW-Authenticate: Bearer ...hint params:auth_protocols,default_protocol,protocol_preferences(ignored by spec-only clients).
DPoP (RFC 9449) (optional extension): adds opt-in DPoP proof generation/verification; standard Bearer flow remains
supported when disabled.
Interoperability: spec-only servers/clients can ignore these extensions and continue using the standard OAuth discovery
and Bearer token flow.
Breaking Changes
None expected. Changes are additive and aim to preserve existing behavior and public APIs.
Types of changes
Checklist
Additional context
Suggested review order (commit-by-commit):
FastMCPwrapper + updated examplesresolves #2024