VibeSecurity

Comparison

Clerk vs Supabase Auth security: sessions and tokens

Clerk is a hosted authentication service. Supabase Auth is the authentication layer built into a Supabase project. Both issue signed tokens, and they document different session designs. This page sets those designs side by side. We have no affiliation with either.

By the VibeSecurity team4 min read

Documented behaviour side by side

Taken from each vendor's own documentation on the date above.
AspectClerkSupabase Auth
Where users liveIn Clerk's hosted service. The Supabase integration guide notes that user records are not synchronised to your database without webhooks.In a dedicated schema inside your project's Postgres database.
Session tokenA Clerk-signed JWT in the __session cookie on your domain, expiring after 60 seconds and refreshed in the background by the frontend SDK.An access token JWT with a default lifetime of one hour. The docs discourage values below five minutes.
Long-lived credentialA client token in the __client cookie on Clerk's Frontend API domain, documented as HttpOnly with SameSite Lax.A refresh token that can be used only once, with a short reuse interval for cases such as server-side rendering.
Readable by JavaScriptThe __session cookie is not HttpOnly because Clerk's client SDKs need it. Clerk says the one-minute lifetime is there to mitigate XSS. The __client cookie is HttpOnly.The JavaScript client can persist the session to local storage. With the server-side package, sessions are kept in cookies, and the docs say HttpOnly is not necessary for them.
Session revocationThe client token is described as the source of truth for authentication state, with the short token refreshed from it.The docs say an unexpired access token stays valid even when the session behind it was revoked, and that getUser() is the way to detect a session that ended server-side.
Session limitsConfirm current options and plan requirements in the vendor's documentation.Time-boxed sessions, inactivity timeouts and single session per user are documented as available on Pro plans and up.
Database access rulesWorks with Supabase as a third-party provider. Policies read the Clerk user id with auth.jwt()->>'sub'.Integrates directly with Row Level Security through auth.uid().

What Clerk leaves to you

  • Verifying the session token on your server for every protected route and API handler. A signed-in screen is not an access check.
  • Authorisation. Clerk tells you who the user is, and your code or database policies decide what they may do.
  • If you use Supabase for data, registering Clerk as a third-party provider and writing RLS policies against the sub claim yourself.
  • Keeping the Clerk secret key on the server only.
  • Preventing XSS in your own app. Clerk's docs call XSS incredibly serious, and a short token lifetime reduces the damage without removing it.

What Supabase Auth leaves to you

  • Enabling Row Level Security and writing policies. Supabase Auth identifies the user, and the policies enforce access.
  • Choosing how the server trusts a request. The docs distinguish verifying a token's signature and expiry from fetching the user to confirm the session still exists.
  • Deciding on token storage. In a browser-only app the session can sit in local storage, where any injected script can read it.
  • Setting session limits if your plan includes them and your app needs forced expiry.
  • Reviewing auth settings such as email confirmation, password rules and allowed redirect URLs in the dashboard.

The decision that matters more than the vendor

Both services answer the question of who the user is. Neither can answer what that user is allowed to touch in your data. Most real incidents in generated apps come from that second question: a missing policy, an API route that trusts a user id from the request body, or an admin page hidden in the UI but open on the server.

Pick the service that fits your stack, then spend your review time on the checks below.

What to check whichever you pick

  • Every API route and server function verifies the token on the server, not only in the browser.
  • The user id used in queries comes from the verified token, never from the request body or URL.
  • A second test account cannot read or change the first account's data.
  • Signing out, or revoking a session, actually ends access within the time you expect.
  • Secret keys for either service are absent from the client bundle and git history.
  • Redirect URLs after sign-in are limited to your own domains.
  • Your app has an XSS review, because both designs keep at least one token readable by JavaScript in common setups.

Frequently asked questions

Is Clerk more secure than Supabase Auth?

Neither vendor's documentation supports a ranking. They document different session designs, and both depend on your server checks and database policies. Compare the token lifetimes and storage above against your own needs.

Can I use Clerk with Supabase Row Level Security?

Yes. Clerk documents a Supabase integration where Clerk is registered as a third-party auth provider and policies read the user id with auth.jwt()->>'sub'. You still write the policies.

How long does a Clerk session token last?

Clerk's docs say the session token expires after 60 seconds and is refreshed in the background by the frontend SDK, with a longer-lived HttpOnly client cookie as the source of truth.

Does Supabase Auth store tokens in localStorage?

The JavaScript client's persistSession option saves the session to local storage. The server-side package stores the session in cookies. Check which one your app uses.

Sources

  1. 1.Clerk docs: How Clerk works
  2. 2.Clerk docs: XSS leak protection
  3. 3.Clerk docs: Supabase integration
  4. 4.Supabase docs: Auth
  5. 5.Supabase docs: User sessions
  6. 6.Supabase docs: Server-side auth advanced guide
  7. 7.Supabase docs: JavaScript client initialisation
  8. 8.Supabase docs: Row Level Security