Supabase Connector
You can integrate Descope with Supabase to continue using Supabase's services while replacing its authentication system with Descope Flows. This is especially useful if your application is already built on Supabase but you want to take advantage of Descope's flexible and secure authentication experience.
With this integration, Descope can return a Supabase-compatible token as part of the response returned after authenticating with flows, SDKs, or the API.
Supabase also supports using external SAML providers, however this is only available to Supabase Pro tiers and up. If you're using the Free tier with Supabase, the approach used in this doc is the recommended approach for you.
Configuring the Supabase Connector
Find the Supabase connector on the Connectors page of the Descope Console.
- Connector Name: Provide a unique name for your connector. This assists in distinguishing it, especially when multiple connectors are derived from the same template.
- Connector Description: Briefly explain the purpose of this connector.
- Signing Secret: This is the JWT secret from your Supabase project. Read below on how to find this.
- Expiration Time: Duration in minutes for which the external token is valid.
- Custom Claims: (Optional) Map Descope user attributes to custom JWT claims in the Supabase token. See Custom Claims Configuration below.

Getting the Signing Secret

To find the Signing Secret for connector configuration, open your Supabase project and navigate to the project settings. Under the JWT Keys tab, reveal and copy the JWT secret, and then paste it into the Signing Secret input of the connector in Descope.
Custom Claims Configuration
The Supabase connector supports custom claims configuration, allowing you to map Descope user attributes to specific claims in the generated Supabase JWT. This enables you to include additional user information or metadata in the token that can be used by Supabase's Row Level Security (RLS) policies or your application logic.
Configuring Custom Claims
In the connector configuration, you can add custom claims by mapping Descope user attributes to JWT claim names:
- In the Custom Claims section of the connector configuration, click Add Claim
- Specify the Claim Name (the key that will appear in the JWT)
- Select the User Attribute from Descope that should be mapped to this claim
- Repeat for each custom claim you want to include
Common use cases for custom claims include:
- User roles and permissions: Map
user.customAttributes.roletoroleclaim for authorization - Tenant/Organization ID: Map
user.tenantIdstotenant_idclaim for multi-tenancy - User metadata: Map custom attributes to claims for application-specific logic
- Anonymous user flag: Configure the
is_anonymousclaim to identify anonymous users
Supported User Attributes
You can map the following Descope user attributes to custom claims:
user.userId- The Descope user IDuser.loginIds- User's login IDs (email, phone, username)user.email- User's email addressuser.phone- User's phone numberuser.name- User's display nameuser.tenantIds- List of tenant IDs the user belongs touser.roleNames- List of role names assigned to the useruser.customAttributes.*- Any custom attribute defined on the user
Example: Configuring is_anonymous Claim
Supabase uses the is_anonymous claim to distinguish between authenticated and anonymous users. To configure this in Descope:
- Add a custom claim with name:
is_anonymous - Map it to a boolean user attribute that indicates anonymous status
- Use this in your Supabase RLS policies to control access for anonymous users
When mapping user attributes that are arrays (like tenantIds or roleNames), the connector will serialize them appropriately in the JWT. For more information on Supabase custom access tokens, see Supabase's Custom Access Token documentation.
Enabling the Connector
Now that the connector is configured, it can be enabled under External Token in the Session Management section of your Descope Project Settings.
Learn more about using external tokens, like those from Supabase, with Descope in our external tokens doc.
The external token generated by Supabase will be included in the authentication response at the end of your flows. Here is an example of a post authentication response with an external token included:
{
"cookieDomain": "",
"cookieExpiration": 0,
"cookieMaxAge": 0,
"cookiePath": "/",
"externalToken": "SUPABASE_TOKEN",
"firstSeen": false,
"idpResponse": null,
"refreshJwt": "DESCOPE_REFRESH_TOKEN",
"sessionExpiration": 1750879215,
"sessionJwt": "DESCOPE_SESSION_TOKEN",
"user": {}
}This external token contains standard Supabase claims along with any custom claims you've configured. Here's an example of a Supabase token without custom claims:
{
"sub": "DESCOPE_USER_ID",
"exp": 1752785069
}And here's an example with custom claims configured:
{
"sub": "DESCOPE_USER_ID",
"email": "user@example.com",
"role": "authenticated",
"is_anonymous": false,
"tenant_id": "tenant_123",
"user_role": "admin",
"exp": 1752785069
}The custom claims (tenant_id, user_role, etc.) are populated from the Descope user attributes based on your connector configuration.
Using the Token
The token is accessible after authenticating with Descope using any method, and can be used when creating a Supabase client as a Authorization Bearer token:
createClient(
SUPABASE_PROJECT_URL,
SUPABASE_PROJECT_ANON_KEY,
{
global: {
headers: {
Authorization: `Bearer ${externalToken}`
}
}
}
);This approach does not create a new user record in Supabase. Instead, it leverages Descope-managed user details to apply fine-grained control over user permissions. You can use Descope to handle authentication while continuing to use Supabase features—such as database, storage, and real-time services—and enforce Supabase’s authorization rules to manage user access.
Using Custom Claims in Row Level Security (RLS)
Custom claims configured in the connector are included in the JWT and can be used in Supabase Row Level Security policies. For example, if you’ve configured a tenant_id custom claim, you can create RLS policies that filter data based on the tenant:
-- Example RLS policy using custom claim
CREATE POLICY "Users can only see their tenant’s data"
ON documents
FOR SELECT
USING (tenant_id = (auth.jwt() ->> ‘tenant_id’)::text);This allows you to implement multi-tenancy, role-based access control, or any other authorization logic using the custom claims from Descope user attributes.