Can I use Clerk, Auth0 or Firebase Auth instead of Supabase Auth?
Not as a drop-in. SupaHost projects only accept JWTs signed by the project itself, so third-party tokens can't drive RLS directly. Here are the patterns that do work.
Not as a drop-in replacement. On SupaHost, the Data API, Storage and Realtime accept JWTs signed with your project's own secret (the anon key, the service_role key and the access tokens Supabase Auth issues). There's no setting to register Clerk, Auth0 or Firebase as a trusted token issuer, so their tokens won't be accepted for RLS. You can still use another identity provider, with your own server code in between, or move users to Supabase Auth.
Your options
| Approach | How it works | Trade-off |
|---|---|---|
| Use Supabase Auth | Email/password, magic links, 19 OAuth providers, anonymous sign-ins, TOTP MFA, built into every project | You move users once (from Auth0, from Firebase) |
| Keep your provider, gate data in server code | Your server or an Edge Function verifies the provider's token, then queries with the service_role key and filters by user |
RLS can't see the user, so every query must filter correctly in code |
| Keep your provider for sign-in, add Supabase Auth through OAuth | If your provider can act as an OAuth/OIDC identity provider supported here (for example Keycloak or WorkOS), users sign in to Supabase Auth through it | Only for the providers in the OAuth list |
Example: Clerk with an Edge Function
The function verifies the Clerk session token against Clerk's JWKS, then reads only that user's rows:
// index.ts of a function named my-invoices (Functions tab → New function)
import { createClient } from 'npm:@supabase/supabase-js@2'
import { createRemoteJWKSet, jwtVerify } from 'npm:jose@5'
const jwks = createRemoteJWKSet(new URL(Deno.env.get('CLERK_JWKS_URL')!))
const admin = createClient(Deno.env.get('SUPABASE_URL')!, Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!)
Deno.serve(async (req) => {
const token = req.headers.get('x-clerk-token') ?? ''
try {
const { payload } = await jwtVerify(token, jwks)
const { data, error } = await admin
.from('invoices')
.select('id, total, due_on')
.eq('clerk_user_id', payload.sub)
if (error) throw error
return Response.json(data)
} catch {
return new Response('Unauthorized', { status: 401 })
}
})
Add CLERK_JWKS_URL in the Functions tab's Secrets card. The function's "Require JWT" check only accepts project JWTs (such as the anon key), so either call it with the anon key in Authorization and the Clerk token in a separate header as above, or turn "Require JWT" off for this function and rely on your own check.
FAQ
Can I use the Supabase third-party auth integration on SupaHost?
No. There's no setting for it, and keys and the JWT secret can't be changed, so tokens from other issuers aren't accepted by the Data API.
Will Realtime and Storage work with my provider?
Only through your own server code using the service_role key, or with users signed in to Supabase Auth. Their policies rely on project-signed JWTs.
Is it hard to switch to Supabase Auth?
Usually not. The admin API accepts bcrypt and Firebase scrypt password hashes, so users can often keep their passwords.