From 980d0516a7e7f65526c5cfb9fa7b115b679d6268 Mon Sep 17 00:00:00 2001 From: Jeremiah Lowin <153965+jlowin@users.noreply.github.com> Date: Wed, 22 Oct 2025 21:51:37 -0400 Subject: [PATCH] Expose OAuth token management parameters in all providers (#2222) All OAuth providers and OIDCProxy now expose jwt_signing_key, token_encryption_key, and client_storage parameters for production deployments requiring persistent token management across server restarts. --- docs/integrations/auth0.mdx | 38 +++++++++++++++++++++ docs/integrations/aws-cognito.mdx | 38 +++++++++++++++++++++ docs/integrations/azure.mdx | 38 +++++++++++++++++++++ docs/integrations/github.mdx | 36 +++++++++++++++++++ docs/integrations/google.mdx | 37 ++++++++++++++++++++ docs/integrations/workos.mdx | 38 +++++++++++++++++++++ src/fastmcp/server/auth/oidc_proxy.py | 11 ++++++ src/fastmcp/server/auth/providers/auth0.py | 10 ++++++ src/fastmcp/server/auth/providers/aws.py | 10 ++++++ src/fastmcp/server/auth/providers/azure.py | 10 ++++++ src/fastmcp/server/auth/providers/github.py | 10 ++++++ src/fastmcp/server/auth/providers/google.py | 10 ++++++ src/fastmcp/server/auth/providers/workos.py | 10 ++++++ 13 files changed, 296 insertions(+) diff --git a/docs/integrations/auth0.mdx b/docs/integrations/auth0.mdx index f02594178..b6b359e87 100644 --- a/docs/integrations/auth0.mdx +++ b/docs/integrations/auth0.mdx @@ -149,6 +149,44 @@ When you run the client for the first time: 2. After you authorize the app, you'll be redirected back 3. The client receives the token and can make authenticated requests +## Production Configuration + + + +For production deployments with persistent token management across server restarts, configure `jwt_signing_key`, `token_encryption_key`, and `client_storage`: + +```python server.py +import os +from fastmcp import FastMCP +from fastmcp.server.auth.providers.auth0 import Auth0Provider +from key_value.aio.stores.redis import RedisStore + +# Production setup with persistent token storage +auth_provider = Auth0Provider( + config_url="https://.../.well-known/openid-configuration", + client_id="tv2ObNgaZAWWhhycr7Bz1LU2mxlnsmsB", + client_secret="vPYqbjemq...", + audience="https://...", + base_url="https://your-production-domain.com", + + # Production token management + jwt_signing_key=os.environ["JWT_SIGNING_KEY"], # Secret for signing JWT tokens + token_encryption_key=os.environ["TOKEN_ENCRYPTION_KEY"], # Secret for encrypting tokens at rest + client_storage=RedisStore( # Persistent storage for client registrations + host=os.environ["REDIS_HOST"], + port=int(os.environ["REDIS_PORT"]) + ) +) + +mcp = FastMCP(name="Production Auth0 App", auth=auth_provider) +``` + + +All three parameters (`jwt_signing_key`, `token_encryption_key`, and `client_storage`) work together to ensure tokens and client registrations survive server restarts. Store secrets in environment variables and use a persistent storage backend like Redis or PostgreSQL for distributed deployments. + +For complete details on these parameters, see the [OAuth Proxy documentation](/servers/auth/oauth-proxy#configuration-parameters). + + The client caches tokens locally, so you won't need to re-authenticate for subsequent runs unless the token expires or you explicitly clear the cache. diff --git a/docs/integrations/aws-cognito.mdx b/docs/integrations/aws-cognito.mdx index 2fa97b155..c06884414 100644 --- a/docs/integrations/aws-cognito.mdx +++ b/docs/integrations/aws-cognito.mdx @@ -196,6 +196,44 @@ When you run the client for the first time: The client caches tokens locally, so you won't need to re-authenticate for subsequent runs unless the token expires or you explicitly clear the cache. +## Production Configuration + + + +For production deployments with persistent token management across server restarts, configure `jwt_signing_key`, `token_encryption_key`, and `client_storage`: + +```python server.py +import os +from fastmcp import FastMCP +from fastmcp.server.auth.providers.aws import AWSCognitoProvider +from key_value.aio.stores.redis import RedisStore + +# Production setup with persistent token storage +auth_provider = AWSCognitoProvider( + user_pool_id="eu-central-1_XXXXXXXXX", + aws_region="eu-central-1", + client_id="your-app-client-id", + client_secret="your-app-client-secret", + base_url="https://your-production-domain.com", + + # Production token management + jwt_signing_key=os.environ["JWT_SIGNING_KEY"], # Secret for signing JWT tokens + token_encryption_key=os.environ["TOKEN_ENCRYPTION_KEY"], # Secret for encrypting tokens at rest + client_storage=RedisStore( # Persistent storage for client registrations + host=os.environ["REDIS_HOST"], + port=int(os.environ["REDIS_PORT"]) + ) +) + +mcp = FastMCP(name="Production AWS Cognito App", auth=auth_provider) +``` + + +All three parameters (`jwt_signing_key`, `token_encryption_key`, and `client_storage`) work together to ensure tokens and client registrations survive server restarts. Store secrets in environment variables and use a persistent storage backend like Redis or PostgreSQL for distributed deployments. + +For complete details on these parameters, see the [OAuth Proxy documentation](/servers/auth/oauth-proxy#configuration-parameters). + + ## Environment Variables For production deployments, use environment variables instead of hardcoding credentials. diff --git a/docs/integrations/azure.mdx b/docs/integrations/azure.mdx index 5bd84b648..61dbfa2c5 100644 --- a/docs/integrations/azure.mdx +++ b/docs/integrations/azure.mdx @@ -205,6 +205,44 @@ When you run the client for the first time: The client caches tokens locally, so you won't need to re-authenticate for subsequent runs unless the token expires or you explicitly clear the cache. +## Production Configuration + + + +For production deployments with persistent token management across server restarts, configure `jwt_signing_key`, `token_encryption_key`, and `client_storage`: + +```python server.py +import os +from fastmcp import FastMCP +from fastmcp.server.auth.providers.azure import AzureProvider +from key_value.aio.stores.redis import RedisStore + +# Production setup with persistent token storage +auth_provider = AzureProvider( + client_id="835f09b6-0f0f-40cc-85cb-f32c5829a149", + client_secret="your-client-secret", + tenant_id="08541b6e-646d-43de-a0eb-834e6713d6d5", + base_url="https://your-production-domain.com", + required_scopes=["your-scope"], + + # Production token management + jwt_signing_key=os.environ["JWT_SIGNING_KEY"], # Secret for signing JWT tokens + token_encryption_key=os.environ["TOKEN_ENCRYPTION_KEY"], # Secret for encrypting tokens at rest + client_storage=RedisStore( # Persistent storage for client registrations + host=os.environ["REDIS_HOST"], + port=int(os.environ["REDIS_PORT"]) + ) +) + +mcp = FastMCP(name="Production Azure App", auth=auth_provider) +``` + + +All three parameters (`jwt_signing_key`, `token_encryption_key`, and `client_storage`) work together to ensure tokens and client registrations survive server restarts. Store secrets in environment variables and use a persistent storage backend like Redis or PostgreSQL for distributed deployments. + +For complete details on these parameters, see the [OAuth Proxy documentation](/servers/auth/oauth-proxy#configuration-parameters). + + ## Environment Variables diff --git a/docs/integrations/github.mdx b/docs/integrations/github.mdx index 3822e9dc5..6682cde10 100644 --- a/docs/integrations/github.mdx +++ b/docs/integrations/github.mdx @@ -135,6 +135,42 @@ When you run the client for the first time: The client caches tokens locally, so you won't need to re-authenticate for subsequent runs unless the token expires or you explicitly clear the cache. +## Production Configuration + + + +For production deployments with persistent token management across server restarts, configure `jwt_signing_key`, `token_encryption_key`, and `client_storage`: + +```python server.py +import os +from fastmcp import FastMCP +from fastmcp.server.auth.providers.github import GitHubProvider +from key_value.aio.stores.redis import RedisStore + +# Production setup with persistent token storage +auth_provider = GitHubProvider( + client_id="Ov23liAbcDefGhiJkLmN", + client_secret="github_pat_...", + base_url="https://your-production-domain.com", + + # Production token management + jwt_signing_key=os.environ["JWT_SIGNING_KEY"], # Secret for signing JWT tokens + token_encryption_key=os.environ["TOKEN_ENCRYPTION_KEY"], # Secret for encrypting tokens at rest + client_storage=RedisStore( # Persistent storage for client registrations + host=os.environ["REDIS_HOST"], + port=int(os.environ["REDIS_PORT"]) + ) +) + +mcp = FastMCP(name="Production GitHub App", auth=auth_provider) +``` + + +All three parameters (`jwt_signing_key`, `token_encryption_key`, and `client_storage`) work together to ensure tokens and client registrations survive server restarts. Store secrets in environment variables and use a persistent storage backend like Redis or PostgreSQL for distributed deployments. + +For complete details on these parameters, see the [OAuth Proxy documentation](/servers/auth/oauth-proxy#configuration-parameters). + + ## Environment Variables diff --git a/docs/integrations/google.mdx b/docs/integrations/google.mdx index 5cf398776..15d8123ca 100644 --- a/docs/integrations/google.mdx +++ b/docs/integrations/google.mdx @@ -148,6 +148,43 @@ When you run the client for the first time: The client caches tokens locally, so you won't need to re-authenticate for subsequent runs unless the token expires or you explicitly clear the cache. +## Production Configuration + + + +For production deployments with persistent token management across server restarts, configure `jwt_signing_key`, `token_encryption_key`, and `client_storage`: + +```python server.py +import os +from fastmcp import FastMCP +from fastmcp.server.auth.providers.google import GoogleProvider +from key_value.aio.stores.redis import RedisStore + +# Production setup with persistent token storage +auth_provider = GoogleProvider( + client_id="123456789.apps.googleusercontent.com", + client_secret="GOCSPX-abc123...", + base_url="https://your-production-domain.com", + required_scopes=["openid", "https://www.googleapis.com/auth/userinfo.email"], + + # Production token management + jwt_signing_key=os.environ["JWT_SIGNING_KEY"], # Secret for signing JWT tokens + token_encryption_key=os.environ["TOKEN_ENCRYPTION_KEY"], # Secret for encrypting tokens at rest + client_storage=RedisStore( # Persistent storage for client registrations + host=os.environ["REDIS_HOST"], + port=int(os.environ["REDIS_PORT"]) + ) +) + +mcp = FastMCP(name="Production Google App", auth=auth_provider) +``` + + +All three parameters (`jwt_signing_key`, `token_encryption_key`, and `client_storage`) work together to ensure tokens and client registrations survive server restarts. Store secrets in environment variables and use a persistent storage backend like Redis or PostgreSQL for distributed deployments. + +For complete details on these parameters, see the [OAuth Proxy documentation](/servers/auth/oauth-proxy#configuration-parameters). + + ## Environment Variables diff --git a/docs/integrations/workos.mdx b/docs/integrations/workos.mdx index b0f90b684..47892f256 100644 --- a/docs/integrations/workos.mdx +++ b/docs/integrations/workos.mdx @@ -126,6 +126,44 @@ When you run the client for the first time: The client caches tokens locally, so you won't need to re-authenticate for subsequent runs unless the token expires or you explicitly clear the cache. +## Production Configuration + + + +For production deployments with persistent token management across server restarts, configure `jwt_signing_key`, `token_encryption_key`, and `client_storage`: + +```python server.py +import os +from fastmcp import FastMCP +from fastmcp.server.auth.providers.workos import WorkOSProvider +from key_value.aio.stores.redis import RedisStore + +# Production setup with persistent token storage +auth = WorkOSProvider( + client_id="client_YOUR_CLIENT_ID", + client_secret="YOUR_CLIENT_SECRET", + authkit_domain="https://your-app.authkit.app", + base_url="https://your-production-domain.com", + required_scopes=["openid", "profile", "email"], + + # Production token management + jwt_signing_key=os.environ["JWT_SIGNING_KEY"], # Secret for signing JWT tokens + token_encryption_key=os.environ["TOKEN_ENCRYPTION_KEY"], # Secret for encrypting tokens at rest + client_storage=RedisStore( # Persistent storage for client registrations + host=os.environ["REDIS_HOST"], + port=int(os.environ["REDIS_PORT"]) + ) +) + +mcp = FastMCP(name="Production WorkOS App", auth=auth) +``` + + +All three parameters (`jwt_signing_key`, `token_encryption_key`, and `client_storage`) work together to ensure tokens and client registrations survive server restarts. Store secrets in environment variables and use a persistent storage backend like Redis or PostgreSQL for distributed deployments. + +For complete details on these parameters, see the [OAuth Proxy documentation](/servers/auth/oauth-proxy#configuration-parameters). + + ## Environment Variables diff --git a/src/fastmcp/server/auth/oidc_proxy.py b/src/fastmcp/server/auth/oidc_proxy.py index b7fd7e72b..40196a7c7 100644 --- a/src/fastmcp/server/auth/oidc_proxy.py +++ b/src/fastmcp/server/auth/oidc_proxy.py @@ -215,6 +215,9 @@ class OIDCProxy(OAuthProxy): # Client configuration allowed_client_redirect_uris: list[str] | None = None, client_storage: AsyncKeyValue | None = None, + # JWT and encryption keys + jwt_signing_key: str | bytes | None = None, + token_encryption_key: str | bytes | None = None, # Token validation configuration token_endpoint_auth_method: str | None = None, # Consent screen configuration @@ -241,6 +244,12 @@ class OIDCProxy(OAuthProxy): If empty list, all redirect URIs are allowed (not recommended for production). These are for MCP clients performing loopback redirects, NOT for the upstream OAuth app. client_storage: An AsyncKeyValue-compatible store for client registrations, registrations are stored in memory if not provided + jwt_signing_key: Secret for signing FastMCP JWT tokens (any string or bytes). + None (default): Auto-managed via system keyring (Mac/Windows) or ephemeral (Linux). + Explicit value: For production deployments. Recommended to store in environment variable. + token_encryption_key: Secret for encrypting upstream tokens at rest (any string or bytes). + None (default): Auto-managed via system keyring (Mac/Windows) or ephemeral (Linux). + Explicit value: For production deployments. Recommended to store in environment variable. token_endpoint_auth_method: Token endpoint authentication method for upstream server. Common values: "client_secret_basic", "client_secret_post", "none". If None, authlib will use its default (typically "client_secret_basic"). @@ -301,6 +310,8 @@ class OIDCProxy(OAuthProxy): "service_documentation_url": self.oidc_config.service_documentation, "allowed_client_redirect_uris": allowed_client_redirect_uris, "client_storage": client_storage, + "jwt_signing_key": jwt_signing_key, + "token_encryption_key": token_encryption_key, "token_endpoint_auth_method": token_endpoint_auth_method, "require_authorization_consent": require_authorization_consent, } diff --git a/src/fastmcp/server/auth/providers/auth0.py b/src/fastmcp/server/auth/providers/auth0.py index 04f625eb5..e43fd586a 100644 --- a/src/fastmcp/server/auth/providers/auth0.py +++ b/src/fastmcp/server/auth/providers/auth0.py @@ -96,6 +96,8 @@ class Auth0Provider(OIDCProxy): redirect_path: str | NotSetT = NotSet, allowed_client_redirect_uris: list[str] | NotSetT = NotSet, client_storage: AsyncKeyValue | None = None, + jwt_signing_key: str | bytes | None = None, + token_encryption_key: str | bytes | None = None, require_authorization_consent: bool = True, ) -> None: """Initialize Auth0 OAuth provider. @@ -113,6 +115,12 @@ class Auth0Provider(OIDCProxy): allowed_client_redirect_uris: List of allowed redirect URI patterns for MCP clients. If None (default), all URIs are allowed. If empty list, no URIs are allowed. client_storage: An AsyncKeyValue-compatible store for client registrations, registrations are stored in memory if not provided + jwt_signing_key: Secret for signing FastMCP JWT tokens (any string or bytes). + None (default): Auto-managed via system keyring (Mac/Windows) or ephemeral (Linux). + Explicit value: For production deployments. Recommended to store in environment variable. + token_encryption_key: Secret for encrypting upstream tokens at rest (any string or bytes). + None (default): Auto-managed via system keyring (Mac/Windows) or ephemeral (Linux). + Explicit value: For production deployments. Recommended to store in environment variable. 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. @@ -174,6 +182,8 @@ class Auth0Provider(OIDCProxy): "required_scopes": auth0_required_scopes, "allowed_client_redirect_uris": settings.allowed_client_redirect_uris, "client_storage": client_storage, + "jwt_signing_key": jwt_signing_key, + "token_encryption_key": token_encryption_key, "require_authorization_consent": require_authorization_consent, } diff --git a/src/fastmcp/server/auth/providers/aws.py b/src/fastmcp/server/auth/providers/aws.py index b3ff650c3..32df70f83 100644 --- a/src/fastmcp/server/auth/providers/aws.py +++ b/src/fastmcp/server/auth/providers/aws.py @@ -135,6 +135,8 @@ class AWSCognitoProvider(OIDCProxy): required_scopes: list[str] | NotSetT = NotSet, allowed_client_redirect_uris: list[str] | NotSetT = NotSet, client_storage: AsyncKeyValue | None = None, + jwt_signing_key: str | bytes | None = None, + token_encryption_key: str | bytes | None = None, require_authorization_consent: bool = True, ): """Initialize AWS Cognito OAuth provider. @@ -152,6 +154,12 @@ class AWSCognitoProvider(OIDCProxy): allowed_client_redirect_uris: List of allowed redirect URI patterns for MCP clients. If None (default), all URIs are allowed. If empty list, no URIs are allowed. client_storage: An AsyncKeyValue-compatible store for client registrations, registrations are stored in memory if not provided + jwt_signing_key: Secret for signing FastMCP JWT tokens (any string or bytes). + None (default): Auto-managed via system keyring (Mac/Windows) or ephemeral (Linux). + Explicit value: For production deployments. Recommended to store in environment variable. + token_encryption_key: Secret for encrypting upstream tokens at rest (any string or bytes). + None (default): Auto-managed via system keyring (Mac/Windows) or ephemeral (Linux). + Explicit value: For production deployments. Recommended to store in environment variable. 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. @@ -220,6 +228,8 @@ class AWSCognitoProvider(OIDCProxy): redirect_path=redirect_path_final, allowed_client_redirect_uris=allowed_client_redirect_uris_final, client_storage=client_storage, + jwt_signing_key=jwt_signing_key, + token_encryption_key=token_encryption_key, require_authorization_consent=require_authorization_consent, ) diff --git a/src/fastmcp/server/auth/providers/azure.py b/src/fastmcp/server/auth/providers/azure.py index 4b429bf64..dcb070bee 100644 --- a/src/fastmcp/server/auth/providers/azure.py +++ b/src/fastmcp/server/auth/providers/azure.py @@ -109,6 +109,8 @@ class AzureProvider(OAuthProxy): additional_authorize_scopes: list[str] | None | NotSetT = NotSet, allowed_client_redirect_uris: list[str] | NotSetT = NotSet, client_storage: AsyncKeyValue | None = None, + jwt_signing_key: str | bytes | None = None, + token_encryption_key: str | bytes | None = None, require_authorization_consent: bool = True, ) -> None: """Initialize Azure OAuth provider. @@ -132,6 +134,12 @@ class AzureProvider(OAuthProxy): allowed_client_redirect_uris: List of allowed redirect URI patterns for MCP clients. If None (default), all URIs are allowed. If empty list, no URIs are allowed. client_storage: An AsyncKeyValue-compatible store for client registrations, registrations are stored in memory if not provided + jwt_signing_key: Secret for signing FastMCP JWT tokens (any string or bytes). + None (default): Auto-managed via system keyring (Mac/Windows) or ephemeral (Linux). + Explicit value: For production deployments. Recommended to store in environment variable. + token_encryption_key: Secret for encrypting upstream tokens at rest (any string or bytes). + None (default): Auto-managed via system keyring (Mac/Windows) or ephemeral (Linux). + Explicit value: For production deployments. Recommended to store in environment variable. 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. @@ -221,6 +229,8 @@ class AzureProvider(OAuthProxy): or settings.base_url, # Default to base_url if not specified allowed_client_redirect_uris=settings.allowed_client_redirect_uris, client_storage=client_storage, + jwt_signing_key=jwt_signing_key, + token_encryption_key=token_encryption_key, require_authorization_consent=require_authorization_consent, ) diff --git a/src/fastmcp/server/auth/providers/github.py b/src/fastmcp/server/auth/providers/github.py index 7db1bc7ee..e80d0a977 100644 --- a/src/fastmcp/server/auth/providers/github.py +++ b/src/fastmcp/server/auth/providers/github.py @@ -206,6 +206,8 @@ class GitHubProvider(OAuthProxy): timeout_seconds: int | NotSetT = NotSet, allowed_client_redirect_uris: list[str] | NotSetT = NotSet, client_storage: AsyncKeyValue | None = None, + jwt_signing_key: str | bytes | None = None, + token_encryption_key: str | bytes | None = None, require_authorization_consent: bool = True, ): """Initialize GitHub OAuth provider. @@ -222,6 +224,12 @@ class GitHubProvider(OAuthProxy): allowed_client_redirect_uris: List of allowed redirect URI patterns for MCP clients. If None (default), all URIs are allowed. If empty list, no URIs are allowed. client_storage: An AsyncKeyValue-compatible store for client registrations, registrations are stored in memory if not provided + jwt_signing_key: Secret for signing FastMCP JWT tokens (any string or bytes). + None (default): Auto-managed via system keyring (Mac/Windows) or ephemeral (Linux). + Explicit value: For production deployments. Recommended to store in environment variable. + token_encryption_key: Secret for encrypting upstream tokens at rest (any string or bytes). + None (default): Auto-managed via system keyring (Mac/Windows) or ephemeral (Linux). + Explicit value: For production deployments. Recommended to store in environment variable. 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. @@ -285,6 +293,8 @@ class GitHubProvider(OAuthProxy): or settings.base_url, # Default to base_url if not specified allowed_client_redirect_uris=allowed_client_redirect_uris_final, client_storage=client_storage, + jwt_signing_key=jwt_signing_key, + token_encryption_key=token_encryption_key, require_authorization_consent=require_authorization_consent, ) diff --git a/src/fastmcp/server/auth/providers/google.py b/src/fastmcp/server/auth/providers/google.py index 814f9b1e8..f000b6213 100644 --- a/src/fastmcp/server/auth/providers/google.py +++ b/src/fastmcp/server/auth/providers/google.py @@ -222,6 +222,8 @@ class GoogleProvider(OAuthProxy): timeout_seconds: int | NotSetT = NotSet, allowed_client_redirect_uris: list[str] | NotSetT = NotSet, client_storage: AsyncKeyValue | None = None, + jwt_signing_key: str | bytes | None = None, + token_encryption_key: str | bytes | None = None, require_authorization_consent: bool = True, ): """Initialize Google OAuth provider. @@ -241,6 +243,12 @@ class GoogleProvider(OAuthProxy): allowed_client_redirect_uris: List of allowed redirect URI patterns for MCP clients. If None (default), all URIs are allowed. If empty list, no URIs are allowed. client_storage: An AsyncKeyValue-compatible store for client registrations, registrations are stored in memory if not provided + jwt_signing_key: Secret for signing FastMCP JWT tokens (any string or bytes). + None (default): Auto-managed via system keyring (Mac/Windows) or ephemeral (Linux). + Explicit value: For production deployments. Recommended to store in environment variable. + token_encryption_key: Secret for encrypting upstream tokens at rest (any string or bytes). + None (default): Auto-managed via system keyring (Mac/Windows) or ephemeral (Linux). + Explicit value: For production deployments. Recommended to store in environment variable. 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. @@ -304,6 +312,8 @@ class GoogleProvider(OAuthProxy): or settings.base_url, # Default to base_url if not specified allowed_client_redirect_uris=allowed_client_redirect_uris_final, client_storage=client_storage, + jwt_signing_key=jwt_signing_key, + token_encryption_key=token_encryption_key, require_authorization_consent=require_authorization_consent, ) diff --git a/src/fastmcp/server/auth/providers/workos.py b/src/fastmcp/server/auth/providers/workos.py index d5d7081eb..d73eedf13 100644 --- a/src/fastmcp/server/auth/providers/workos.py +++ b/src/fastmcp/server/auth/providers/workos.py @@ -172,6 +172,8 @@ class WorkOSProvider(OAuthProxy): timeout_seconds: int | NotSetT = NotSet, allowed_client_redirect_uris: list[str] | NotSetT = NotSet, client_storage: AsyncKeyValue | None = None, + jwt_signing_key: str | bytes | None = None, + token_encryption_key: str | bytes | None = None, require_authorization_consent: bool = True, ): """Initialize WorkOS OAuth provider. @@ -189,6 +191,12 @@ class WorkOSProvider(OAuthProxy): allowed_client_redirect_uris: List of allowed redirect URI patterns for MCP clients. If None (default), all URIs are allowed. If empty list, no URIs are allowed. client_storage: An AsyncKeyValue-compatible store for client registrations, registrations are stored in memory if not provided + jwt_signing_key: Secret for signing FastMCP JWT tokens (any string or bytes). + None (default): Auto-managed via system keyring (Mac/Windows) or ephemeral (Linux). + Explicit value: For production deployments. Recommended to store in environment variable. + token_encryption_key: Secret for encrypting upstream tokens at rest (any string or bytes). + None (default): Auto-managed via system keyring (Mac/Windows) or ephemeral (Linux). + Explicit value: For production deployments. Recommended to store in environment variable. 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. @@ -261,6 +269,8 @@ class WorkOSProvider(OAuthProxy): or settings.base_url, # Default to base_url if not specified allowed_client_redirect_uris=allowed_client_redirect_uris_final, client_storage=client_storage, + jwt_signing_key=jwt_signing_key, + token_encryption_key=token_encryption_key, require_authorization_consent=require_authorization_consent, )