Commit graph

70 commits

Author SHA1 Message Date
Jeremiah Lowin
de58bb0e6c
Add DebugTokenVerifier with custom sync/async validation (#2296)
* Add DebugTokenVerifier with custom sync/async validation

* move import
2025-10-31 10:38:01 -04:00
Jeremiah Lowin
1ca53b4134
Add base_authority parameter to AzureProvider for Azure Government support (#2306) 2025-10-29 14:06:21 -04:00
mhassaninmsft
b24d771457
Supporting Multiple Issuers For JWTVerifier Oauth Workflow (#2233)
* multiple issuers

* Update tests/server/auth/test_jwt_provider.py

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Fix static checks

---------

Co-authored-by: Jeremiah Lowin <153965+jlowin@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-10-27 18:13:40 -04:00
Jeremiah Lowin
15dbe7ecf0
Add custom token verifier support to OIDCProxy (#2279)
* Add custom token verifier support to OIDCProxy

OIDCProxy now accepts an optional token_verifier parameter to support
non-JWT token formats like opaque tokens from providers such as Clerk.

When provided, the custom verifier is used instead of creating a default
JWTVerifier. Parameters that only apply to JWTVerifier creation (algorithm,
required_scopes) raise clear errors when specified alongside a custom
verifier. Parameters with other purposes (audience for OAuth flow,
timeout_seconds for config fetch) remain allowed.

The custom verifier's required_scopes are automatically loaded and
advertised through OAuth discovery endpoints.

* Document custom token verifier support in OIDC proxy
2025-10-27 13:38:20 -04:00
Jeremiah Lowin
8a48146aad
Cleanly render oauth errors from proxy (#2268) 2025-10-26 21:08:05 -04:00
Jeremiah Lowin
ba47db9b8c
Fix Azure scope validation (#2269)
* Update docs for required scopes

* add scopes

* Fix Azure scope validation

Azure returns unprefixed scopes in JWT tokens but requires prefixed scopes in authorization requests. The previous implementation incorrectly validated tokens against prefixed scopes, causing "invalid_token" errors.

Simplified AzureProvider to use standard JWTVerifier with unprefixed scopes for validation. Scopes are only prefixed when building the Azure authorization URL via _build_upstream_authorize_url() override.

Closes #2263
2025-10-26 11:41:22 -04:00
William Easton
c002bc389c
Small Clean-up (#2247)
* Project Clean-up

* Move pytest-asyncio to dev dependencies and update agents.md
2025-10-24 19:11:01 -04:00
William Easton
063ffe9f64
Derive jwt_signing_key from Client Secret, default to Encrypted Disk Store (#2223)
* Checkpoint progress

* Checkpoint progress

* add derive b64 method

* PR clean-up

* refactor da proxy

* Updates to tests

* Make jwt_signing_key required for oauth proxy

* use typing_extensions and fix tests

* PR Cleanup

* also adjust integration tests

* Update docs, use client secret to derive jwt signing key

* You win some you lose some, gg claude

* check for both in derive

* update documentation / clean up

* Update http.mdx

---------

Co-authored-by: Jeremiah Lowin <153965+jlowin@users.noreply.github.com>
2025-10-24 19:08:58 -04:00
Jeremiah Lowin
a1a5cca765
Fix Azure scope mismatch causing MCP client validation errors (#2243)
* Fix Azure scope mismatch causing MCP client validation errors

The AzureProvider was prefixing scopes during authorization but not in
token validation or Protected Resource Metadata, causing MCP clients to
reject tokens with "Server granted unauthorized scopes".

Changes:
- Prefix required_scopes once during __init__ and use consistently
- Pass prefixed scopes to JWTVerifier for token validation
- PRM now advertises prefixed scopes to MCP clients
- Remove unnecessary idempotent prefixing logic in authorize()
- Update comprehensive documentation explaining scope handling
- Update tests to reflect corrected behavior

Closes #2151

* Clarify that identifier_uri is optional in docstring
2025-10-24 17:45:49 -04:00
Jeremiah Lowin
562e51b378
Improve OAuth error messages with custom handlers and middleware (#2221)
* Enhance OAuth Proxy error responses with branded HTML pages

OAuth Proxy authentication errors now show styled HTML error pages in browsers
instead of raw JSON, with content negotiation for API clients. Enhanced error
messages explain common causes (ephemeral storage, server restarts) and provide
clear remediation steps.

Changes:
- Created enhanced authorization handler that extends SDK's AuthorizationHandler
- Created enhanced auth middleware that extends SDK's RequireAuthMiddleware
- HTML error pages use server branding (icon, name) from FastMCP instance
- Added comprehensive troubleshooting section to OAuth Proxy docs
- Added FAQ entry linking to detailed troubleshooting

* Add comprehensive tests for enhanced OAuth error responses

Tests cover:
- HTML error pages for browser requests with server branding
- Enhanced JSON responses with registration endpoint hints
- Content negotiation between HTML and JSON
- Enhanced middleware error messages for invalid_token
- WWW-Authenticate header format consistency with SDK

* Update language for new storage defaults

* update docs

* Update tests for simplified error messages

* Clean up messages
2025-10-22 21:29:14 -04:00
Jeremiah Lowin
686082a5b5
Add platform-aware OAuth token persistence (#2218)
* Add comprehensive keyring integration tests

Prevents OS keyring pollution during testing by adding a global mock in
conftest.py. Tests verify keyring behavior across platforms and fallback
scenarios without writing to the actual system keyring.

- Add global mock_keyring fixture to tests/conftest.py
- Add TestOAuthProxyKeyring class with 6 keyring-specific tests
- Remove try/except ImportError for keyring (now required dependency)
- Add keyring extra to py-key-value-aio dependency
- Clean up extraneous implementation comments in oauth_proxy.py

* Update OAuth keyring documentation

Update all OAuth-related documentation to reflect keyring-based key management:
- Add version badges to jwt_signing_key, token_encryption_key, and client_storage parameters
- Standardize "Default behavior (`None`):" formatting with backticks
- Ensure consistent messaging about development-only defaults across all docs
- Update oauth-proxy.mdx, oidc-proxy.mdx, http.mdx, storage-backends.mdx, and upgrade-guide.mdx
2025-10-22 20:42:24 -04:00
Jeremiah Lowin
3321644ad3
Replace subprocess tests with in-process async servers (#2006)
* Use anyio as testing backend

* Remove asyncio markers

* Update streamable http tests

* Replace all subprocess tests

* Replace anyio task groups with asyncio context managers in tests

- Convert run_server_async from anyio task group pattern to asyncio.create_task with async context manager
- Remove task_group fixture from conftest
- Update all test fixtures to use async with run_server_async pattern
- Remove TaskGroup imports from all test files
- Tests now work with pytest-asyncio instead of pytest-anyio

* Update test_github_provider_integration.py
2025-10-19 10:47:54 -04:00
Jeremiah Lowin
9e78d755c2
Support custom server name, icons, and link in OAuth Proxy consent page (#2135)
* Implement icon support in fastmcp

* Fix icon feature tests

- Update snapshot for ResourceTemplate to include icons field
- Remove OAuth mounting tests (belong to PR #2119, not this feature)

* Update docs

* Customize consent screen

* Use server website link if available

* Anchor link shouldnt have trailing slash

* Remove 'a FastMCP server named' from consent page message

* Update docs
2025-10-18 11:49:26 -04:00
Jeremiah Lowin
330eaed11f
OAuth proxy issues its own tokens (#2109)
* OAuth proxy issues its own tokens

Implement token factory pattern where proxy issues FastMCP JWTs
instead of forwarding upstream tokens. Tokens are minimal references
(JTI) that map to encrypted upstream credentials stored server-side.

* Update run-tests.yml

* Update secret generation and docs

* Add upgrade guide
2025-10-17 14:31:53 -04:00
Jeremiah Lowin
d472e30765
Support mounting OAuth-protected servers under path prefixes (#2119)
* Add issuer_url parameter to OAuth providers for mounting scenarios

* Add get_well_known_routes

* Update docs

* Improve docs and tests

* Trigger CI

* Fix conditional test execution for Windows
2025-10-17 11:44:49 -04:00
Jeremiah Lowin
4a9f02c87c
Upgrade to MCP 1.17+ with RFC 9728 compliance (#2122)
* Upgrade to MCP 1.17+ with RFC 9728 compliance

Updates FastMCP to require MCP 1.17+ and implements RFC 9728-compliant
OAuth protected resource metadata URL handling.

The key change is that .well-known/oauth-protected-resource endpoints
are now registered at path-aware locations. For example, if an MCP
server is mounted at /mcp, the metadata endpoint is now at
/.well-known/oauth-protected-resource/mcp instead of
/.well-known/oauth-protected-resource.

This ensures proper OAuth discovery for path-based resource servers
and aligns with the MCP SDK's implementation of RFC 9728 §3.1.

Changes include:
- Update minimum MCP version from 1.12.4 to 1.17.0
- Use build_resource_metadata_url() for RFC 9728 compliance
- Configure CI to test with latest package versions (--upgrade)
- Update tests for path-aware metadata URLs
- Add icons field to Tool model (introduced in MCP 1.17)

* Fix RemoteAuthProvider integration tests for RFC 9728

* Fix parameterized test for nested base URL paths
2025-10-17 09:29:23 -04:00
Jeremiah Lowin
52e9af1214
Add RFC 7662 token introspection provider (#2074) 2025-10-16 10:57:06 -04:00
Jeremiah Lowin
7b7e277d5d
Prevent confused deputy attacks in OAuth proxy (#2056) 2025-10-11 10:53:54 -04:00
William Easton
93c41e815c
Merge branch 'main' into switch-kvstore 2025-10-09 09:20:55 -04:00
William Easton
de0c39c1b3
Add raise on validation error and set uniform collection names 2025-10-08 23:40:58 -04:00
Adam Azzam
a8d2a667d6
Add supabase auth (#1997) 2025-10-08 20:27:55 -04:00
William Easton
00ffa6006a
Merge branch 'main' into switch-kvstore 2025-10-08 18:07:05 -04:00
Anders Julton
82cf3888dd
Azure (Entra) OAuth: Validate token against FastMCP app, not Graph. (#1891)
Co-authored-by: Jeremiah Lowin <153965+jlowin@users.noreply.github.com>
2025-10-08 09:06:35 -04:00
William Easton
1a9f95299a
lint cuz i dont have precommit 2025-10-07 17:40:52 -04:00
William Easton
dd81a0beb3
Removing central storage configuration for now 2025-10-06 11:58:11 -05:00
William Easton
a9ee0b577a
Merge branch 'main' into switch-kvstore 2025-09-29 17:12:09 -05:00
Jeremiah Lowin
e8673b4d8b
Fix Python 3.13 websockets deprecation warning (#1949) 2025-09-29 15:24:20 -04:00
Jeremiah Lowin
d7c60511b9
Refactor OAuth 2.1 error handling with TokenHandler subclass (#1948) 2025-09-29 15:00:57 -04:00
Tomas Caraccia
1c323a8583
feat: Follow OAuth 2.1 spec requirements on auth failures (#1923)
Co-authored-by: Tomas <>
2025-09-29 14:10:59 -04:00
William Easton
55ac070a59
Merge branch 'main' into switch-kvstore 2025-09-28 21:35:46 -05:00
William Easton
ccd12c4b1b
Refactor for key-value 0.2.0 2025-09-28 21:35:22 -05:00
Akshay Parihar
7bcf8b562c
Add Scalekit Provider for Enterprise Authentication (#1927)
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Ravi Madabhushi <ravi.madabhushi@scalekit.com>
Co-authored-by: Ravi Madabhushi <innovativeravi@gmail.com>
Co-authored-by: saif-at-scalekit <saif.shaik@scalekit.com>
2025-09-26 16:58:03 -04:00
William Easton
7ca6bd422f
Merge branch 'main' into switch-kvstore 2025-09-25 12:47:39 -05:00
Stephan Eberle
5486b5a3b9
Add AWS Cognito OAuth Provider for Enterprise Authentication (#1873)
Co-authored-by: Jeremiah Lowin <153965+jlowin@users.noreply.github.com>
2025-09-25 11:08:45 -04:00
Jeremiah Lowin
fccd081758
Clean up code for creating the resource url (#1916) 2025-09-25 10:42:57 -04:00
raphael-linx
eb0db4fb77
Fix: get_resource_url nested URL handling (#1914) 2025-09-25 10:35:37 -04:00
William Easton
dee2bb51d9
Switch to DiskStore KV implementation 2025-09-24 18:07:57 -05:00
nate nowack
04831b75c2
optimize test suite (#1893)
Co-authored-by: Claude <noreply@anthropic.com>
2025-09-22 20:07:04 -04:00
Jeremiah Lowin
7176d4f293
Add persistent storage for OAuth client registrations (#1879) 2025-09-21 10:56:08 -04:00
Anvi Banga
59e250a98e
feat: Add support for Descope Authentication (#1853)
Co-authored-by: Jeremiah Lowin <153965+jlowin@users.noreply.github.com>
2025-09-19 13:46:44 -04:00
Ruhul Alam
16f380a8cf
fix: Improve URL handling in OIDCConfiguration (#1850)
Co-authored-by: Jeremiah Lowin <153965+jlowin@users.noreply.github.com>
2025-09-19 13:11:37 -04:00
Ruhul Alam
2df8a0f915
chore: Set redirect_path default in function (#1833) 2025-09-15 18:33:44 -04:00
Ruhul Alam
972521146f
feat: Add support for OIDC configuration (#1817) 2025-09-14 14:54:48 -04:00
William Easton
fe4f31c2c7
Enable more type checking rules (#1775) 2025-09-07 11:11:44 -04:00
Jeremiah Lowin
3dd7373680
feat: Add flexible parameter forwarding to OAuth proxy (#1771) 2025-09-06 15:50:29 -04:00
Jeremiah Lowin
cf3c8767d6
Clean up and reorganize OAuth proxy tests (#1738) 2025-09-03 12:34:00 -04:00
Jeremiah Lowin
46a5187398
Add token_endpoint_auth_method parameter to OAuthProxy (#1736) 2025-09-03 12:21:40 -04:00
Jeremiah Lowin
1045eb47c2
OAuth proxy PKCE forwarding (#1733) 2025-09-03 12:11:38 -04:00
Daniel Mikusa
598a37e6c9
Expose valid scopes from OAuthProxy metadata (#1717)
Co-authored-by: Jeremiah Lowin <153965+jlowin@users.noreply.github.com>
2025-09-03 10:34:29 -04:00
Jeremiah Lowin
d11e98fe4a
Fix OAuth proxy client storage and add retry logic (#1732) 2025-09-03 10:05:33 -04:00