Expand description
OAuth 2.1 client for proxy MCP upstream authentication (issue #306).
Implements the client half of the MCP authorization spec against any OAuth-2.1-compliant server, using only the standard RFCs the server already advertises — no vendor-specific logic:
- Discovery (
discover): RFC 9728 protected-resource metadata (located via the upstream’sWWW-Authenticatechallenge) → RFC 8414 authorization- server metadata. - Dynamic registration (RFC 7591), the device grant (RFC 8628) and refresh
(RFC 6749 §6) build on the
AuthServerMetadatadiscovered here.
Structs§
- Auth
Server Metadata - RFC 8414 §2 — Authorization Server Metadata (subset we consume).
- Client
Registration Response - RFC 7591 §3.2.1 registration response (subset — we only need
client_id). - Device
Auth Response - RFC 8628 §3.2 device authorization response.
- OAuth
Tokens - A persisted OAuth token set for one proxy upstream. Serialized as JSON into
the credential store under a per-server key (e.g.
proxy.<name>.oauth). - Protected
Resource Metadata - RFC 9728 §3.2 — OAuth Protected Resource Metadata (subset we consume).
- Token
Response - RFC 6749 §5.1 successful token response (device_code + refresh grants).
Enums§
- Device
Poll Outcome - One device-token poll outcome (RFC 8628 §3.5).
- OAuth
Error - Failures across the OAuth client flow.
Functions§
- discover
- Discover authorization-server metadata for an upstream, starting from its
WWW-Authenticatechallenge (RFC 9728 → RFC 8414). - fetch_
as_ metadata - Fetch RFC 8414 authorization-server metadata. Per RFC 8414 §3.1 / RFC 8615
the well-known segment goes after the authority and before any issuer
path (
https://host/tenant→https://host/.well-known/oauth-authorization-server/tenant), not naively appended. The advertisedissueris verified to match (§3.3), and every endpoint the AS advertises is scheme/host-guarded before we POST secrets to it. - poll_
device_ token_ once - Poll the token endpoint once with the device_code grant (RFC 8628 §3.4/§3.5).
authorization_pending/slow_downmap to non-terminal outcomes; other error codes (access_denied,expired_token, …) surface asOAuthError::Oauth. - refresh
- RFC 6749 §6 refresh-token grant — exchange a refresh_token for a fresh set.
- register_
client - Register a public device-flow client via RFC 7591 and return its
client_id. Callers persist the id intoProxyOAuthConfig.client_idso re-login reuses it. - request_
device_ authorization - POST the RFC 8628 §3.1 device authorization request (form-encoded).