HomeGuidesSupabase anon key vs service role key

Guide

Supabase anon key vs service role key

Which Supabase key is safe in the browser, which one bypasses Row Level Security, and where each belongs in a Lovable, Bolt, or Next.js app.

2 min read

Independent notes from VibeLocked. Not a pentest, and not affiliated with the tools named below.

Supabase gives every project two kinds of API keys. One is meant for the public. The other can do anything. Mixing them up is one of the most common mistakes in apps generated by AI builders, so here is the short version.

Checked against the Supabase docs linked below on October 13, 2026.

The two keys in one table

anon / publishable key service_role / secret key
Safe in browser code Yes No, never
Row Level Security Enforced Bypassed
Typical home Frontend Supabase client Server routes, Edge Functions, cron jobs
If leaked Expected to be public. Your RLS policies are the protection Full access to data exposed through the API. Rotate immediately

Supabase now also offers newer key formats, publishable keys (sb_publishable_...) and secret keys (sb_secret_...). They play the same roles: publishable replaces anon, secret replaces service_role. Older projects still show the legacy anon and service_role JWT keys.

Why the anon key is fine to ship

The anon key identifies your project and maps requests to the anon Postgres role (or the authenticated role once a user signs in). What a request can actually read or write is decided by Row Level Security policies in Postgres. If RLS is off on a table in an exposed schema, the anon key can read and write that table. So the question is never "is my anon key hidden", it is "are my policies correct". Use the Supabase RLS checklist to check.

Why the service role key is dangerous

The service role key maps to a role that bypasses RLS. That is useful for admin jobs, webhooks, and background work where your own server code decides who is allowed to do what. It is a disaster in a browser bundle, a public repo, or a mobile app, because anyone can extract it.

How to check your app right now

  1. Search your code for the key names: service_role, SERVICE_ROLE, sb_secret_.
  2. Make sure no environment variable holding it starts with NEXT_PUBLIC_ or VITE_. Those prefixes put the value in the client bundle.
  3. Build the app and search the output folder (dist/, .next/static/) for the key prefix.
  4. In Lovable or Bolt projects, check which key the generated client uses. It should be the anon or publishable key.
  5. Open the Supabase dashboard and confirm RLS is enabled on every table in the public schema. The Security Advisor flags tables without it.

If you find a secret key anywhere public, follow the first hour after an API key leaks.

Official docs

Questions

Is the Supabase anon key a secret?

No. Supabase designs the anon key (and the newer publishable key) to be used in the browser. It is only safe when Row Level Security is enabled and has correct policies on every table exposed through the API.

Can the service role key be used in frontend code?

No. The service role key (and the newer secret key) bypasses Row Level Security. Anyone who has it can read and change all data exposed through the API. Keep it on a server, in an Edge Function, or in a secrets store.

What should I do if my service role key was in a public repo or bundle?

Treat it as compromised. Rotate or revoke it in the Supabase dashboard, update the servers that use it, and review your data and logs. Deleting the commit is not enough.