diff --git a/docs/servers/auth/bearer.mdx b/docs/servers/auth/bearer.mdx index 15df171f6..7db7085a6 100644 --- a/docs/servers/auth/bearer.mdx +++ b/docs/servers/auth/bearer.mdx @@ -53,6 +53,7 @@ from fastmcp.server.auth import BearerAuthProvider auth = BearerAuthProvider( jwks_uri="https://my-identity-provider.com/.well-known/jwks.json", issuer="https://my-identity-provider.com/", + algorithm="RS512", audience="my-mcp-server" ) @@ -74,6 +75,10 @@ mcp = FastMCP(name="My MCP Server", auth=auth) Expected JWT `iss` claim value + + Algorithm for decoding JWT token. Defaults to 'RS256' + + Expected JWT `aud` claim value diff --git a/src/fastmcp/server/auth/providers/bearer.py b/src/fastmcp/server/auth/providers/bearer.py index edb7abb3f..9d5d40f7e 100644 --- a/src/fastmcp/server/auth/providers/bearer.py +++ b/src/fastmcp/server/auth/providers/bearer.py @@ -113,6 +113,7 @@ class RSAKeyPair: Returns: Signed JWT token string """ + # TODO : Add support for configurable algorithms jwt = JsonWebToken(["RS256"]) now = int(time.time()) @@ -151,7 +152,7 @@ class RSAKeyPair: class BearerAuthProvider(OAuthProvider): """ Simple JWT Bearer Token validator for hosted MCP servers. - Uses RS256 asymmetric encryption. Supports either static public key + Uses RS256 asymmetric encryption by default but supports all JWA algorithms. Supports either static public key or JWKS URI for key rotation. Note that this provider DOES NOT permit client registration or revocation, or any OAuth flows. @@ -163,6 +164,7 @@ class BearerAuthProvider(OAuthProvider): public_key: str | None = None, jwks_uri: str | None = None, issuer: str | None = None, + algorithm: str | None = None, audience: str | list[str] | None = None, required_scopes: list[str] | None = None, ): @@ -173,6 +175,7 @@ class BearerAuthProvider(OAuthProvider): public_key: RSA public key in PEM format (for static key) jwks_uri: URI to fetch keys from (for key rotation) issuer: Expected issuer claim (optional) + algorithm: Algorithm to use for verification (optional, defaults to RS256) audience: Expected audience claim - can be a string or list of strings (optional) required_scopes: List of required scopes for access (optional) """ @@ -181,6 +184,24 @@ class BearerAuthProvider(OAuthProvider): if public_key and jwks_uri: raise ValueError("Provide either public_key or jwks_uri, not both") + if not algorithm: + algorithm = "RS256" + if algorithm not in { + "HS256", + "HS384", + "HS512", + "RS256", + "RS384", + "RS512", + "ES256", + "ES384", + "ES512", + "PS256", + "PS384", + "PS512", + }: + raise ValueError(f"Unsupported algorithm: {algorithm}.") + # Only pass issuer to parent if it's a valid URL, otherwise use default # This allows the issuer claim validation to work with string issuers per RFC 7519 try: @@ -196,11 +217,12 @@ class BearerAuthProvider(OAuthProvider): required_scopes=required_scopes, ) + self.algorithm = algorithm self.issuer = issuer self.audience = audience self.public_key = public_key self.jwks_uri = jwks_uri - self.jwt = JsonWebToken(["RS256"]) + self.jwt = JsonWebToken([self.algorithm]) # Use RS256 by default self.logger = get_logger(__name__) # Simple JWKS cache diff --git a/src/fastmcp/server/auth/providers/bearer_env.py b/src/fastmcp/server/auth/providers/bearer_env.py index 308f5fcd7..dfbd96146 100644 --- a/src/fastmcp/server/auth/providers/bearer_env.py +++ b/src/fastmcp/server/auth/providers/bearer_env.py @@ -17,6 +17,7 @@ class EnvBearerAuthProviderSettings(BaseSettings): public_key: str | None = None jwks_uri: str | None = None issuer: str | None = None + algorithm: str | None = None audience: str | None = None required_scopes: list[str] | None = None @@ -33,6 +34,7 @@ class EnvBearerAuthProvider(BearerAuthProvider): public_key: str | None | EllipsisType = ..., jwks_uri: str | None | EllipsisType = ..., issuer: str | None | EllipsisType = ..., + algorithm: str | None | EllipsisType = ..., audience: str | None | EllipsisType = ..., required_scopes: list[str] | None | EllipsisType = ..., ): @@ -43,6 +45,7 @@ class EnvBearerAuthProvider(BearerAuthProvider): public_key: RSA public key in PEM format (for static key) jwks_uri: URI to fetch keys from (for key rotation) issuer: Expected issuer claim (optional) + algorithm: Algorithm to use for verification (optional) audience: Expected audience claim (optional) required_scopes: List of required scopes for access (optional) """ @@ -50,6 +53,7 @@ class EnvBearerAuthProvider(BearerAuthProvider): "public_key": public_key, "jwks_uri": jwks_uri, "issuer": issuer, + "algorithm": algorithm, "audience": audience, "required_scopes": required_scopes, }