Integrations and ConnectorsConnectorsSetup GuidesExternal Token

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.

Supabase connector configuration screen

Getting the Signing Secret

Locating Supabase JWT 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:

  1. In the Custom Claims section of the connector configuration, click Add Claim
  2. Specify the Claim Name (the key that will appear in the JWT)
  3. Select the User Attribute from Descope that should be mapped to this claim
  4. Repeat for each custom claim you want to include

Common use cases for custom claims include:

  • User roles and permissions: Map user.customAttributes.role to role claim for authorization
  • Tenant/Organization ID: Map user.tenantIds to tenant_id claim for multi-tenancy
  • User metadata: Map custom attributes to claims for application-specific logic
  • Anonymous user flag: Configure the is_anonymous claim to identify anonymous users

Supported User Attributes

You can map the following Descope user attributes to custom claims:

  • user.userId - The Descope user ID
  • user.loginIds - User's login IDs (email, phone, username)
  • user.email - User's email address
  • user.phone - User's phone number
  • user.name - User's display name
  • user.tenantIds - List of tenant IDs the user belongs to
  • user.roleNames - List of role names assigned to the user
  • user.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:

  1. Add a custom claim with name: is_anonymous
  2. Map it to a boolean user attribute that indicates anonymous status
  3. 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.

Was this helpful?

On this page