diff --git a/docs/servers/auth/oauth-proxy.mdx b/docs/servers/auth/oauth-proxy.mdx index dd4751350..03727ec87 100644 --- a/docs/servers/auth/oauth-proxy.mdx +++ b/docs/servers/auth/oauth-proxy.mdx @@ -315,8 +315,10 @@ auth = OAuthProxy(..., client_storage=MemoryStore()) **`"remember"` — silent consent on return:** Users see the consent screen on first authorization; subsequent flows from the same browser for the same `(client_id, redirect_uri)` are silently approved via a signed cookie. Cross-site navigations (detected via `Sec-Fetch-Site`) fall back to the prompt. `Sec-Fetch-Site` is a browser-level heuristic rather than a protocol guarantee: an attacker who finds a way to initiate a non-cross-site navigation (XSS on a sibling origin, a same-site redirect chain, etc.) can reach the silent-consent path. `True` does not depend on this signal. See [Confused Deputy Attacks](#confused-deputy-attacks) for the underlying attack class. - **`"external"` — delegate to upstream:** - Skip the built-in consent page; consent is collected by the upstream IdP or a custom login page referenced via `upstream_authorization_endpoint`. No security warning is logged. + **`"external"` — externally managed:** + Follows the same authorization path as `False`: FastMCP skips its consent page and associated browser-binding protections, then redirects directly to the upstream provider. The difference is logging. `False` emits a security warning, while `"external"` suppresses that warning as an explicit acknowledgment that the operator is enforcing equivalent consent and transaction-binding protections elsewhere. FastMCP does not provide or verify those external protections. + + Ordinary upstream OAuth consent is generally not equivalent. It typically authorizes FastMCP's shared upstream application without identifying the downstream MCP client or binding approval to that client's transaction. Use `"external"` only when your surrounding authorization system supplies those protections. **`False` — disable entirely:** Authorization proceeds directly to the upstream provider without any consent UI. Logs a security warning. Only for local development or testing. @@ -336,7 +338,7 @@ auth = OAuthProxy(..., client_storage=MemoryStore()) ``` - Disabling consent removes an important security layer. Only disable for local development or testing environments where you fully control all connecting clients. + Both `False` and `"external"` disable FastMCP's consent and browser-binding protections. `False` warns about this configuration; `"external"` suppresses the warning because it is an operator acknowledgment that equivalent protections exist elsewhere. Prefer the default `True` unless you own that external authorization flow. diff --git a/docs/servers/auth/oidc-proxy.mdx b/docs/servers/auth/oidc-proxy.mdx index 006efc8d6..be4bcb22d 100644 --- a/docs/servers/auth/oidc-proxy.mdx +++ b/docs/servers/auth/oidc-proxy.mdx @@ -206,7 +206,7 @@ auth = OIDCProxy( - Consent screen behavior for authorization requests. Accepts `True` (default; always prompt — strongest protection), `"remember"` (silent consent on return visits via signed cookie, gated by `Sec-Fetch-Site` to block AS-in-the-middle attacks), `"external"` (consent handled by upstream IdP or custom page), or `False` (disable entirely; local/testing only). See the [OAuthProxy documentation](/servers/auth/oauth-proxy) for full details on each mode and the security trade-offs. + Consent screen behavior for authorization requests. Accepts `True` (default; always prompt — strongest protection), `"remember"` (silent consent on return visits via signed cookie, gated by `Sec-Fetch-Site` to block AS-in-the-middle attacks), `"external"` (same authorization path as `False`, but the warning is suppressed because the operator asserts that equivalent protections are enforced externally), or `False` (disable entirely; local/testing only). See the [OAuthProxy documentation](/servers/auth/oauth-proxy) for full details on each mode and the security trade-offs. diff --git a/docs/v2/servers/auth/oauth-proxy.mdx b/docs/v2/servers/auth/oauth-proxy.mdx index eef3bce1c..678c396b5 100644 --- a/docs/v2/servers/auth/oauth-proxy.mdx +++ b/docs/v2/servers/auth/oauth-proxy.mdx @@ -296,8 +296,10 @@ auth = OAuthProxy(..., client_storage=MemoryStore()) **`"remember"` — silent consent on return:** Users see the consent screen on first authorization; subsequent flows from the same browser for the same `(client_id, redirect_uri)` are silently approved via a signed cookie. Cross-site navigations (detected via `Sec-Fetch-Site`) fall back to the prompt. `Sec-Fetch-Site` is a browser-level heuristic rather than a protocol guarantee: an attacker who finds a way to initiate a non-cross-site navigation (XSS on a sibling origin, a same-site redirect chain, etc.) can reach the silent-consent path. `True` does not depend on this signal. See [Confused Deputy Attacks](#confused-deputy-attacks) for the underlying attack class. - **`"external"` — delegate to upstream:** - Skip the built-in consent page; consent is collected by the upstream IdP or a custom login page referenced via `upstream_authorization_endpoint`. No security warning is logged. + **`"external"` — externally managed:** + Follows the same authorization path as `False`: FastMCP skips its consent page and associated browser-binding protections, then redirects directly to the upstream provider. The difference is logging. `False` emits a security warning, while `"external"` suppresses that warning as an explicit acknowledgment that the operator is enforcing equivalent consent and transaction-binding protections elsewhere. FastMCP does not provide or verify those external protections. + + Ordinary upstream OAuth consent is generally not equivalent. It typically authorizes FastMCP's shared upstream application without identifying the downstream MCP client or binding approval to that client's transaction. Use `"external"` only when your surrounding authorization system supplies those protections. **`False` — disable entirely:** Authorization proceeds directly to the upstream provider without any consent UI. Logs a security warning. Only for local development or testing. @@ -317,7 +319,7 @@ auth = OAuthProxy(..., client_storage=MemoryStore()) ``` - Disabling consent removes an important security layer. Only disable for local development or testing environments where you fully control all connecting clients. + Both `False` and `"external"` disable FastMCP's consent and browser-binding protections. `False` warns about this configuration; `"external"` suppresses the warning because it is an operator acknowledgment that equivalent protections exist elsewhere. Prefer the default `True` unless you own that external authorization flow. diff --git a/docs/v2/servers/auth/oidc-proxy.mdx b/docs/v2/servers/auth/oidc-proxy.mdx index 750298298..a7988995e 100644 --- a/docs/v2/servers/auth/oidc-proxy.mdx +++ b/docs/v2/servers/auth/oidc-proxy.mdx @@ -199,7 +199,7 @@ auth = OIDCProxy( - Consent screen behavior for authorization requests. Accepts `True` (default; always prompt — strongest protection), `"remember"` (silent consent on return visits via signed cookie, gated by `Sec-Fetch-Site` to block AS-in-the-middle attacks), `"external"` (consent handled by upstream IdP or custom page), or `False` (disable entirely; local/testing only). See the [OAuthProxy documentation](/v2/servers/auth/oauth-proxy) for full details on each mode and the security trade-offs. + Consent screen behavior for authorization requests. Accepts `True` (default; always prompt — strongest protection), `"remember"` (silent consent on return visits via signed cookie, gated by `Sec-Fetch-Site` to block AS-in-the-middle attacks), `"external"` (same authorization path as `False`, but the warning is suppressed because the operator asserts that equivalent protections are enforced externally), or `False` (disable entirely; local/testing only). See the [OAuthProxy documentation](/v2/servers/auth/oauth-proxy) for full details on each mode and the security trade-offs. diff --git a/docs/v3/servers/auth/oauth-proxy.mdx b/docs/v3/servers/auth/oauth-proxy.mdx index e35f244eb..79ba7bf09 100644 --- a/docs/v3/servers/auth/oauth-proxy.mdx +++ b/docs/v3/servers/auth/oauth-proxy.mdx @@ -310,8 +310,10 @@ auth = OAuthProxy(..., client_storage=MemoryStore()) **`"remember"` — silent consent on return:** Users see the consent screen on first authorization; subsequent flows from the same browser for the same `(client_id, redirect_uri)` are silently approved via a signed cookie. Cross-site navigations (detected via `Sec-Fetch-Site`) fall back to the prompt. `Sec-Fetch-Site` is a browser-level heuristic rather than a protocol guarantee: an attacker who finds a way to initiate a non-cross-site navigation (XSS on a sibling origin, a same-site redirect chain, etc.) can reach the silent-consent path. `True` does not depend on this signal. See [Confused Deputy Attacks](#confused-deputy-attacks) for the underlying attack class. - **`"external"` — delegate to upstream:** - Skip the built-in consent page; consent is collected by the upstream IdP or a custom login page referenced via `upstream_authorization_endpoint`. No security warning is logged. + **`"external"` — externally managed:** + Follows the same authorization path as `False`: FastMCP skips its consent page and associated browser-binding protections, then redirects directly to the upstream provider. The difference is logging. `False` emits a security warning, while `"external"` suppresses that warning as an explicit acknowledgment that the operator is enforcing equivalent consent and transaction-binding protections elsewhere. FastMCP does not provide or verify those external protections. + + Ordinary upstream OAuth consent is generally not equivalent. It typically authorizes FastMCP's shared upstream application without identifying the downstream MCP client or binding approval to that client's transaction. Use `"external"` only when your surrounding authorization system supplies those protections. **`False` — disable entirely:** Authorization proceeds directly to the upstream provider without any consent UI. Logs a security warning. Only for local development or testing. @@ -331,7 +333,7 @@ auth = OAuthProxy(..., client_storage=MemoryStore()) ``` - Disabling consent removes an important security layer. Only disable for local development or testing environments where you fully control all connecting clients. + Both `False` and `"external"` disable FastMCP's consent and browser-binding protections. `False` warns about this configuration; `"external"` suppresses the warning because it is an operator acknowledgment that equivalent protections exist elsewhere. Prefer the default `True` unless you own that external authorization flow. diff --git a/docs/v3/servers/auth/oidc-proxy.mdx b/docs/v3/servers/auth/oidc-proxy.mdx index fde747e2b..81ca677a2 100644 --- a/docs/v3/servers/auth/oidc-proxy.mdx +++ b/docs/v3/servers/auth/oidc-proxy.mdx @@ -199,7 +199,7 @@ auth = OIDCProxy( - Consent screen behavior for authorization requests. Accepts `True` (default; always prompt — strongest protection), `"remember"` (silent consent on return visits via signed cookie, gated by `Sec-Fetch-Site` to block AS-in-the-middle attacks), `"external"` (consent handled by upstream IdP or custom page), or `False` (disable entirely; local/testing only). See the [OAuthProxy documentation](/servers/auth/oauth-proxy) for full details on each mode and the security trade-offs. + Consent screen behavior for authorization requests. Accepts `True` (default; always prompt — strongest protection), `"remember"` (silent consent on return visits via signed cookie, gated by `Sec-Fetch-Site` to block AS-in-the-middle attacks), `"external"` (same authorization path as `False`, but the warning is suppressed because the operator asserts that equivalent protections are enforced externally), or `False` (disable entirely; local/testing only). See the [OAuthProxy documentation](/servers/auth/oauth-proxy) for full details on each mode and the security trade-offs. diff --git a/fastmcp_slim/fastmcp/server/auth/oauth_proxy/proxy.py b/fastmcp_slim/fastmcp/server/auth/oauth_proxy/proxy.py index 2ca7fa311..760552bcc 100644 --- a/fastmcp_slim/fastmcp/server/auth/oauth_proxy/proxy.py +++ b/fastmcp_slim/fastmcp/server/auth/oauth_proxy/proxy.py @@ -397,8 +397,10 @@ class OAuthProxy(OAuthProvider, ConsentMixin): redirect_uri) in the same browser. Cross-site navigations are still prompted to block AS-in-the-middle attacks. Lower UX friction, but weaker protection than True. - - "external": skip the built-in consent screen; consent is handled - externally (e.g. by the upstream IdP or a custom login page). + - "external": follow the same authorization path as False, but + suppress the warning as an operator acknowledgment that equivalent + consent and transaction-binding protections are enforced externally. + FastMCP does not provide or verify those external protections. - False: skip consent entirely. SECURITY WARNING: only set to False for local development or testing environments. consent_csp_policy: Content Security Policy for the consent page. diff --git a/fastmcp_slim/fastmcp/server/auth/oidc_proxy.py b/fastmcp_slim/fastmcp/server/auth/oidc_proxy.py index e2bda58ab..5e4086c7a 100644 --- a/fastmcp_slim/fastmcp/server/auth/oidc_proxy.py +++ b/fastmcp_slim/fastmcp/server/auth/oidc_proxy.py @@ -306,8 +306,9 @@ class OIDCProxy(OAuthProxy): require_authorization_consent: Whether to require user consent before authorizing clients (default True). When True, users see a consent screen before being redirected to the upstream IdP. When False, authorization proceeds directly without user confirmation. - When "external", the built-in consent screen is skipped but no warning is - logged, indicating that consent is handled externally (e.g. by the upstream IdP). + When "external", authorization follows the same direct path as False, + but the warning is suppressed as an operator acknowledgment that + equivalent protections are enforced externally. SECURITY WARNING: Only set to False for local development or testing environments. consent_csp_policy: Content Security Policy for the consent page. If None (default), uses the built-in CSP policy with appropriate directives. diff --git a/fastmcp_slim/fastmcp/server/auth/providers/auth0.py b/fastmcp_slim/fastmcp/server/auth/providers/auth0.py index 0a3120a2b..29cc02a88 100644 --- a/fastmcp_slim/fastmcp/server/auth/providers/auth0.py +++ b/fastmcp_slim/fastmcp/server/auth/providers/auth0.py @@ -135,8 +135,9 @@ class Auth0Provider(OIDCProxy): require_authorization_consent: Whether to require user consent before authorizing clients (default True). When True, users see a consent screen before being redirected to Auth0. When False, authorization proceeds directly without user confirmation. - When "external", the built-in consent screen is skipped but no warning is - logged, indicating that consent is handled externally (e.g. by the upstream IdP). + When "external", authorization follows the same direct path as False, + but the warning is suppressed as an operator acknowledgment that + equivalent protections are enforced externally. SECURITY WARNING: Only set to False for local development or testing environments. fallback_refresh_token_expiry_seconds: Lifetime for the FastMCP-issued refresh token when the upstream provider omits `refresh_expires_in` diff --git a/fastmcp_slim/fastmcp/server/auth/providers/aws.py b/fastmcp_slim/fastmcp/server/auth/providers/aws.py index 01b1bcbd5..553c9b705 100644 --- a/fastmcp_slim/fastmcp/server/auth/providers/aws.py +++ b/fastmcp_slim/fastmcp/server/auth/providers/aws.py @@ -175,8 +175,9 @@ class AWSCognitoProvider(OIDCProxy): require_authorization_consent: Whether to require user consent before authorizing clients (default True). When True, users see a consent screen before being redirected to AWS Cognito. When False, authorization proceeds directly without user confirmation. - When "external", the built-in consent screen is skipped but no warning is - logged, indicating that consent is handled externally (e.g. by the upstream IdP). + When "external", authorization follows the same direct path as False, + but the warning is suppressed as an operator acknowledgment that + equivalent protections are enforced externally. SECURITY WARNING: Only set to False for local development or testing environments. fallback_refresh_token_expiry_seconds: Lifetime for the FastMCP-issued refresh token when the upstream provider omits `refresh_expires_in` diff --git a/fastmcp_slim/fastmcp/server/auth/providers/azure.py b/fastmcp_slim/fastmcp/server/auth/providers/azure.py index b8d4332e2..b0cf9d360 100644 --- a/fastmcp_slim/fastmcp/server/auth/providers/azure.py +++ b/fastmcp_slim/fastmcp/server/auth/providers/azure.py @@ -173,8 +173,9 @@ class AzureProvider(OAuthProxy): require_authorization_consent: Whether to require user consent before authorizing clients (default True). When True, users see a consent screen before being redirected to Azure. When False, authorization proceeds directly without user confirmation. - When "external", the built-in consent screen is skipped but no warning is - logged, indicating that consent is handled externally (e.g. by the upstream IdP). + When "external", authorization follows the same direct path as False, + but the warning is suppressed as an operator acknowledgment that + equivalent protections are enforced externally. SECURITY WARNING: Only set to False for local development or testing environments. http_client: Optional httpx2.AsyncClient for connection pooling in JWKS fetches. When provided, the client is reused for JWT key fetches and the caller diff --git a/fastmcp_slim/fastmcp/server/auth/providers/clerk.py b/fastmcp_slim/fastmcp/server/auth/providers/clerk.py index 6378e5de8..cb7a20660 100644 --- a/fastmcp_slim/fastmcp/server/auth/providers/clerk.py +++ b/fastmcp_slim/fastmcp/server/auth/providers/clerk.py @@ -327,8 +327,9 @@ class ClerkProvider(OAuthProxy): into a 32-byte key. If not provided, the upstream client secret will be used to derive a 32-byte key using PBKDF2. require_authorization_consent: Whether to require user consent before authorizing - clients (default True). When "external", the built-in consent screen is skipped - but no warning is logged, indicating that consent is handled externally by Clerk. + clients (default True). When "external", authorization follows the same direct + path as False, but the warning is suppressed as an operator acknowledgment that + equivalent protections are enforced externally. consent_csp_policy: Custom CSP policy for the consent page. extra_authorize_params: Additional parameters to forward to Clerk's authorization endpoint. Example: {"prompt": "login"} to force re-authentication. diff --git a/fastmcp_slim/fastmcp/server/auth/providers/discord.py b/fastmcp_slim/fastmcp/server/auth/providers/discord.py index bdb922fa2..8a6b657b6 100644 --- a/fastmcp_slim/fastmcp/server/auth/providers/discord.py +++ b/fastmcp_slim/fastmcp/server/auth/providers/discord.py @@ -241,8 +241,9 @@ class DiscordProvider(OAuthProxy): require_authorization_consent: Whether to require user consent before authorizing clients (default True). When True, users see a consent screen before being redirected to Discord. When False, authorization proceeds directly without user confirmation. - When "external", the built-in consent screen is skipped but no warning is - logged, indicating that consent is handled externally (e.g. by the upstream IdP). + When "external", authorization follows the same direct path as False, + but the warning is suppressed as an operator acknowledgment that + equivalent protections are enforced externally. SECURITY WARNING: Only set to False for local development or testing environments. http_client: Optional httpx2.AsyncClient for connection pooling in token verification. When provided, the client is reused across verify_token calls and the caller diff --git a/fastmcp_slim/fastmcp/server/auth/providers/github.py b/fastmcp_slim/fastmcp/server/auth/providers/github.py index db6718922..214d24c3b 100644 --- a/fastmcp_slim/fastmcp/server/auth/providers/github.py +++ b/fastmcp_slim/fastmcp/server/auth/providers/github.py @@ -257,8 +257,9 @@ class GitHubProvider(OAuthProxy): require_authorization_consent: Whether to require user consent before authorizing clients (default True). When True, users see a consent screen before being redirected to GitHub. When False, authorization proceeds directly without user confirmation. - When "external", the built-in consent screen is skipped but no warning is - logged, indicating that consent is handled externally (e.g. by the upstream IdP). + When "external", authorization follows the same direct path as False, + but the warning is suppressed as an operator acknowledgment that + equivalent protections are enforced externally. SECURITY WARNING: Only set to False for local development or testing environments. http_client: Optional httpx2.AsyncClient for connection pooling in token verification. When provided, the client is reused across verify_token calls and the caller diff --git a/fastmcp_slim/fastmcp/server/auth/providers/google.py b/fastmcp_slim/fastmcp/server/auth/providers/google.py index 7a9e4ba18..a8536b223 100644 --- a/fastmcp_slim/fastmcp/server/auth/providers/google.py +++ b/fastmcp_slim/fastmcp/server/auth/providers/google.py @@ -290,8 +290,9 @@ class GoogleProvider(OAuthProxy): require_authorization_consent: Whether to require user consent before authorizing clients (default True). When True, users see a consent screen before being redirected to Google. When False, authorization proceeds directly without user confirmation. - When "external", the built-in consent screen is skipped but no warning is - logged, indicating that consent is handled externally (e.g. by Google's own consent). + When "external", authorization follows the same direct path as False, + but the warning is suppressed as an operator acknowledgment that + equivalent protections are enforced externally. SECURITY WARNING: Only set to False for local development or testing environments. extra_authorize_params: Additional parameters to forward to Google's authorization endpoint. By default, GoogleProvider sets {"access_type": "offline", "prompt": "consent"} to ensure diff --git a/fastmcp_slim/fastmcp/server/auth/providers/workos.py b/fastmcp_slim/fastmcp/server/auth/providers/workos.py index bf955e821..18c0a763a 100644 --- a/fastmcp_slim/fastmcp/server/auth/providers/workos.py +++ b/fastmcp_slim/fastmcp/server/auth/providers/workos.py @@ -213,8 +213,9 @@ class WorkOSProvider(OAuthProxy): require_authorization_consent: Whether to require user consent before authorizing clients (default True). When True, users see a consent screen before being redirected to WorkOS. When False, authorization proceeds directly without user confirmation. - When "external", the built-in consent screen is skipped but no warning is - logged, indicating that consent is handled externally (e.g. by the upstream IdP). + When "external", authorization follows the same direct path as False, + but the warning is suppressed as an operator acknowledgment that + equivalent protections are enforced externally. SECURITY WARNING: Only set to False for local development or testing environments. extra_authorize_params: Additional parameters to forward to WorkOS's authorization endpoint. Useful for forcing scopes like `offline_access` so WorkOS issues a refresh token,