Skip to content

feat: add OAuth 2.0 client certificate authentication (private_key_jwt)#1169

Open
harishkaushal30 wants to merge 1 commit intomodelcontextprotocol:mainfrom
harishkaushal30:feat/oauth-certificate-auth
Open

feat: add OAuth 2.0 client certificate authentication (private_key_jwt)#1169
harishkaushal30 wants to merge 1 commit intomodelcontextprotocol:mainfrom
harishkaushal30:feat/oauth-certificate-auth

Conversation

@harishkaushal30
Copy link
Copy Markdown

Summary

Add support for OAuth 2.0 certificate-based authentication using the \private_key_jwt\ method (RFC 7523) as an alternative to client secret. This enables MCP servers protected by OAuth providers that require certificate auth (e.g., Azure AD/Entra ID with SNI).

Changes

Server

  • *\POST /oauth/token/certificate* — Server-side endpoint that builds a JWT client assertion (RS256, with \x5t\ thumbprint and \x5c\ certificate chain claims), then exchanges the authorization code for tokens at the provider's token endpoint. Private keys never touch the browser.
  • *\GET /oauth/discover?url=...* — Proxy endpoint for CORS-free OAuth endpoint discovery. Fetches .well-known/oauth-protected-resource\ metadata from the MCP server and resolves authorization/token endpoints via OIDC .well-known/openid-configuration. Tries multiple well-known URL patterns (path-prepended, path-appended, root fallback).

Client

  • Auth method toggle — Secret/Certificate selector in the OAuth section of the sidebar
  • Endpoint discovery toggle — Auto-discover from metadata (default) or enter manually
  • Certificate fields — Certificate file path, private key file path inputs
  • Transport auth bypass — For cert auth, the SDK's built-in auth provider is not passed to transports, preventing CORS issues and Azure AD's
    esource\ parameter conflict (\AADSTS9010010). Auth is handled via \handleAuthError\ using the proxy discovery endpoint.
  • State management — All cert config persisted to localStorage before OAuth redirect, read back by OAuthCallback on return

Tests

  • 10 new Sidebar tests for certificate auth UI (method selector, cert/key fields, endpoint source toggle, auto-discover vs manual, input callbacks)
  • Updated existing Sidebar test defaultProps with cert auth fields
  • All 497 tests pass (28 suites)

Documentation

  • Updated README.md Authentication section with subsections for Bearer Token, OAuth with Client Secret, and OAuth with Client Certificate

Compatibility

Works with any OAuth 2.0 provider supporting \private_key_jwt\ client authentication:

  • Azure AD / Microsoft Entra ID (tested, including SNI)
  • Okta
  • Auth0
  • Keycloak

How to test

  1. Configure an OAuth app with certificate credentials on your provider
  2. Select Client Certificate in the Authentication Method dropdown
  3. Provide Client ID, cert path, key path, and scope
  4. Choose auto-discover (if MCP server publishes protected resource metadata) or enter endpoints manually
  5. Click Connect — the inspector handles the full Authorization Code + PKCE flow with JWT client assertion

Add support for OAuth 2.0 certificate-based authentication using the
private_key_jwt method (RFC 7523) as an alternative to client secret.

Server changes:
- Add POST /oauth/token/certificate endpoint for JWT client assertion
  signing and token exchange (server-side, private keys never touch browser)
- Add GET /oauth/discover endpoint for CORS-free OAuth endpoint discovery
  via protected resource metadata and OIDC configuration
- JWT includes x5t (thumbprint) and x5c (certificate chain) claims for
  SNI support

Client changes:
- Add Secret/Certificate toggle in OAuth authentication section
- Add auto-discover/manual toggle for OAuth endpoint configuration
- Auto-discovery fetches .well-known/oauth-protected-resource from MCP
  server and resolves endpoints via OIDC .well-known/openid-configuration
- Certificate auth bypasses SDK auth provider to avoid resource parameter
  conflicts with Azure AD and CORS issues with remote servers
- Add OAuthClientAuthMethod type and session storage constants
- Wire cert config through App.tsx state, Sidebar, useConnection,
  OAuthCallback, AuthDebugger, and oauth-state-machine

Tests:
- Add 10 new Sidebar tests for certificate auth UI behavior
- Update existing Sidebar test defaultProps with cert auth fields
- All 497 tests pass (28 suites)

Documentation:
- Update README.md Authentication section with Bearer Token,
  OAuth with Client Secret, and OAuth with Client Certificate subsections

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant