Supabase anon key vs service_role key (and publishable vs secret keys)
Supabase has two kinds of API key, plus legacy versions of each. Getting this wrong is the single most damaging mistake in vibe-coded Supabase apps, because the wrong key in the browser hands every visitor full database access.
Scan your live app free Passive, no signup, never touches your database.
1. The short answer
Browser, mobile app, anything you ship: the publishable key (sb_publishable_…) or legacy anon key. Server, Edge Function or cron job you control: the secret key (sb_secret_…) or legacy service_role key. Supabase's docs put it this way: the publishable key only reaches what Row Level Security allows; the secret key bypasses Row Level Security, so it must never leave your control.
2. How to tell which key you have
New keys start with sb_publishable_ or sb_secret_ and are short strings, not JWTs. Legacy keys are long JWTs starting with eyJ; decode the payload (for example at a JWT decoder you trust, or locally) and read the role claim: "anon" or "service_role". Unspill decodes this for you and flags any service_role JWT or sb_secret_ key it finds in your site's code.
3. Why the anon/publishable key is safe, if RLS is right
Each key maps to a Postgres role: publishable/anon requests run as anon (or authenticated once a user signs in), and your RLS policies decide what those roles can do. With RLS off, or with a policy like USING (true), the public key can read everything. Run the SQL in our Supabase RLS check.
4. Why the service_role/secret key must stay server-side
Both map to the service_role Postgres role, which has BYPASSRLS, so no policy applies. Per Supabase's docs, the new secret keys return HTTP 401 when used from a browser (matched on User-Agent), but an attacker can still use a leaked one from other tools.
5. If a secret or service_role key leaked
Supabase's documented procedure: fix the root cause first, create a new secret key in Settings → API Keys, replace the old key everywhere, confirm every component uses the new one, then retire the old key. Delete a leaked secret key (irreversible), or deactivate the legacy anon/service_role keys (reversible).
6. Plan for the legacy key deprecation
Supabase's docs say the anon and service_role keys are being deprecated by the end of 2026 in favour of publishable and secret keys. Both systems work side by side until you disable the legacy ones, so migrate deliberately.
7. Name your env vars safely
Public: NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY (or VITE_ equivalents). Server only, never prefixed: SUPABASE_SECRET_KEY. Supabase's docs warn that prefixing a secret makes your bundler ship it.
# Safe to expose to the browser
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=sb_publishable_...
# Server-only: never add a NEXT_PUBLIC_ or VITE_ prefix
SUPABASE_SECRET_KEY=sb_secret_...Fix guides for these issues
- Supabase service_role key exposed: A Supabase service_role (or sb_secret_) key in front-end code gives anyone full read/write access to your database, bypassing Row Level Security. Here is how to rotate it and fix the leak.
- Verify Supabase Row Level Security: Your Supabase anon key is public by design, so Row Level Security is the only thing protecting your tables. Run these SQL checks to find tables with RLS off or policies that let anyone read everything.
FAQ
Is it OK that my Supabase anon key is visible in my website's code?
Yes, it's designed to be public. It's only safe if Row Level Security is enabled on every exposed table with correct policies.
Can I use the service_role key in the browser if my app is small or private?
No. It bypasses all Row Level Security, so anyone who opens DevTools gets full read and write access to your database.
What's the difference between anon and publishable keys?
The publishable key (sb_publishable_) is the newer replacement for the legacy anon JWT; both map to the anon/authenticated roles. Likewise, the secret key (sb_secret_) replaces service_role.
Sources
Last checked against these sources on 2026-10-19. Platforms change; when in doubt, the official docs win.