77
88from __future__ import annotations
99
10+ from typing import Literal
11+
1012import httpx
1113from pydantic import AnyHttpUrl , field_validator
1214from pydantic_settings import BaseSettings , SettingsConfigDict
@@ -32,6 +34,7 @@ class SupabaseProviderSettings(BaseSettings):
3234
3335 project_url : AnyHttpUrl
3436 base_url : AnyHttpUrl
37+ algorithm : Literal ["HS256" , "RS256" , "ES256" ] = "ES256"
3538 required_scopes : list [str ] | None = None
3639
3740 @field_validator ("required_scopes" , mode = "before" )
@@ -52,13 +55,19 @@ class SupabaseProvider(RemoteAuthProvider):
5255 1. Supabase Project Setup:
5356 - Create a Supabase project at https://supabase.com
5457 - Note your project URL (e.g., "https://abc123.supabase.co")
55- - For projects created after May 1st, 2025, asymmetric RS256 keys are used by default
56- - For older projects, consider migrating to asymmetric keys for better security
58+ - Configure your JWT algorithm in Supabase Auth settings (HS256, RS256, or ES256)
59+ - Asymmetric keys (RS256/ES256) are recommended for production
5760
5861 2. JWT Verification:
5962 - FastMCP verifies JWTs using the JWKS endpoint at {project_url}/auth/v1/.well-known/jwks.json
6063 - JWTs are issued by {project_url}/auth/v1
6164 - Tokens are cached for up to 10 minutes by Supabase's edge servers
65+ - Algorithm must match your Supabase Auth configuration
66+
67+ 3. Authorization:
68+ - Supabase uses Row Level Security (RLS) policies for database authorization
69+ - OAuth-level scopes are an upcoming feature in Supabase Auth
70+ - Both approaches will be supported once scope handling is available
6271
6372 For detailed setup instructions, see:
6473 https://supabase.com/docs/guides/auth/jwts
@@ -71,6 +80,7 @@ class SupabaseProvider(RemoteAuthProvider):
7180 supabase_auth = SupabaseProvider(
7281 project_url="https://abc123.supabase.co",
7382 base_url="https://your-fastmcp-server.com",
83+ algorithm="ES256", # Match your Supabase Auth configuration
7484 )
7585
7686 # Use with FastMCP
@@ -83,6 +93,7 @@ def __init__(
8393 * ,
8494 project_url : AnyHttpUrl | str | NotSetT = NotSet ,
8595 base_url : AnyHttpUrl | str | NotSetT = NotSet ,
96+ algorithm : Literal ["HS256" , "RS256" , "ES256" ] | NotSetT = NotSet ,
8697 required_scopes : list [str ] | NotSetT | None = NotSet ,
8798 token_verifier : TokenVerifier | None = None ,
8899 ):
@@ -91,7 +102,11 @@ def __init__(
91102 Args:
92103 project_url: Your Supabase project URL (e.g., "https://abc123.supabase.co")
93104 base_url: Public URL of this FastMCP server
94- required_scopes: Optional list of scopes to require for all requests
105+ algorithm: JWT signing algorithm (HS256, RS256, or ES256). Must match your
106+ Supabase Auth configuration. Defaults to ES256.
107+ required_scopes: Optional list of scopes to require for all requests.
108+ Note: Supabase currently uses RLS policies for authorization. OAuth-level
109+ scopes are an upcoming feature.
95110 token_verifier: Optional token verifier. If None, creates JWT verifier for Supabase
96111 """
97112 settings = SupabaseProviderSettings .model_validate (
@@ -100,6 +115,7 @@ def __init__(
100115 for k , v in {
101116 "project_url" : project_url ,
102117 "base_url" : base_url ,
118+ "algorithm" : algorithm ,
103119 "required_scopes" : required_scopes ,
104120 }.items ()
105121 if v is not NotSet
@@ -114,7 +130,7 @@ def __init__(
114130 token_verifier = JWTVerifier (
115131 jwks_uri = f"{ self .project_url } /auth/v1/.well-known/jwks.json" ,
116132 issuer = f"{ self .project_url } /auth/v1" ,
117- algorithm = "ES256" , # Supabase uses ES256 for asymmetric keys
133+ algorithm = settings . algorithm ,
118134 required_scopes = settings .required_scopes ,
119135 )
120136
0 commit comments