Supabase Publishable Key: Moving Off anon Keys

Supabase's publishable key (sb_publishable_...) replaces the anon key; the secret key (sb_secret_...) replaces service_role. Supabase is deprecating the old keys by the end of 2026. Keep RLS on.

Gary · Published · Updated · 9 min read

Isometric illustration of a server block with a locked padlock and a key dissolving into particles, an emerald path to an open door holding a small glowing key, and a usage gauge on dark slate.
On this page
  1. What to do before the end of 2026 (checklist)
  2. What's the difference between the old and new Supabase keys?
  3. Which key goes in the frontend, and which on the server?
  4. How do I migrate from anon and service_role?
  5. When do anon keys stop working?
  6. Is the publishable key safe in the browser?
  7. Do I need new RLS policies?
  8. Does Lovable or Bolt update this for me?
  9. FAQ
  10. Check your app

The Supabase publishable key (sb_publishable_...) is the new version of the anon key, and the secret key (sb_secret_...) is the new version of service_role. Supabase's docs say it is deprecating anon and service_role keys by the end of 2026. The publishable key goes in your frontend, and the secret key stays on your server. Row Level Security is still what protects your data.

By Gary, Greenlight My App · Updated Oct 29, 2026 · How we checked this: we read Supabase's API keys docs on Oct 29, 2026. We have not created publishable and secret keys in a test project for this post yet, so the dashboard steps are untested by us. Drafted with AI tools and reviewed by a person before publishing.

What to do before the end of 2026 (checklist)

Create a publishable key and a secret key, swap them into your app, confirm everything works, then disable the legacy keys. Supabase says the two key systems work side by side, so you can switch without downtime.

StepWhereNotes
1. Create a publishable key and a secret keyDashboard: Settings > API KeysDoesn't affect legacy keys
2. Swap the publishable key into frontend codeYour .env and host settingsReplaces the anon key
3. Swap the secret key into server codeHost's secret settingsReplaces service_role
4. Redeploy and test sign-in, reads and writesYour appCheck every feature
5. Disable the legacy keysDashboard: Settings > API KeysReversible, per Supabase
6. Re-check RLS on every tableSecurity AdvisorSame rules as before

What's the difference between the old and new Supabase keys?

The new keys are short strings, not JWTs, and they map to the same Postgres roles as the old keys. Supabase lists four key types: publishable and secret (new), and anon and service_role (legacy).

Publishable keySecret keyanon (legacy)service_role (legacy)
Starts withsb_publishable_sb_secret_eyJ (JWT)eyJ (JWT)
PrivilegesLowElevatedLowElevated
Safe in the browser?YesNoYesNo
Bypasses RLS?NoYesNoYes
Replacesanonservice_role——

Source: Supabase docs, API keys (external), read Oct 29, 2026.

Supabase's docs add a handy tip: if a tool, tutorial or AI assistant tells you to copy a long key starting with eyJ, it was written for the legacy keys.

Which key goes in the frontend, and which on the server?

Ask where the code runs. Anything you ship to users, like a web page or mobile app, gets the publishable key. Anything you control, like a server, Edge Function or cron job, gets the secret key.

Supabase's docs put it as a building: the publishable key is taped to the front door and opens the lobby. The secret key is the master key, and it stays in your pocket.

Here's the .env naming the docs suggest for a Next.js app:

Bash

NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=sb_publishable_XXXX

SUPABASE_URL=https://your-project.supabase.co
SUPABASE_SECRET_KEY=sb_secret_XXXX

Those values are fake placeholders. The important part is the prefix. A NEXT_PUBLIC_ or VITE_ prefix ships the value to the browser, so it must never go on the secret key. Our service role key guide (external) explains what happens if it does.

The new secret key also adds a safety check. Supabase says a secret key doesn't work in a browser: it matches on the User-Agent header and returns HTTP 401. That's a backstop, not permission to be careless. An attacker can still use a leaked secret key from other tools.

How do I migrate from anon and service_role?

Create the new keys, swap them in, test, then disable the legacy keys. Supabase says creating new keys doesn't revoke the old ones, and that disabling legacy keys is reversible, so you can turn them back on if you find a client you missed.

A worked example for a typical small app with a web frontend and one server route:

  1. In the dashboard, go to Settings > API Keys and create a publishable key and a secret key.
  2. Frontend: replace the anon key value with the publishable key. In code, it's still passed to createClient.
  3. Server route: replace the service_role key with the secret key, read from a server-only variable.
  4. Edge Functions: Supabase's docs say SUPABASE_ANON_KEY and SUPABASE_SERVICE_ROLE_KEY in the Edge runtime still carry the legacy keys, so reading them keeps you on the old path. The docs point to SUPABASE_SECRET_KEYS or the @supabase/server SDK instead.
  5. Headers: Supabase says to send the new keys on the apikey header, not Authorization: Bearer, because they aren't JWTs.
  6. Redeploy and test sign-in, reads, writes and any Edge Functions.
  7. Disable the legacy keys in Settings > API Keys once everything works.

Want to check what your live app exposes? Run Greenlight My App's free scan on your live URL.

When do anon keys stop working?

Supabase's docs say it is deprecating the anon and service_role keys "by the end of 2026". The docs page we read on Oct 29, 2026, doesn't give an exact day. Until you disable them, the legacy keys keep working alongside the new ones.

Don't wait for the last week of December. Plan the switch now, while both systems run side by side. To catch an exact date if Supabase publishes one, check its API keys page and changelog.

This is a separate change from Supabase's Oct 30 default for new tables. If you're seeing permission denied errors, our 42501 guide (external) covers that one.

Is the publishable key safe in the browser?

Yes. Supabase's docs say the publishable key is safe to expose online, including in web pages, mobile apps and source code. It's safe because Row Level Security decides what it can reach. Without RLS, any key is a problem.

Supabase lists things the publishable key does not protect against, because anyone can read it:

  • Code analysis and reverse engineering.
  • The browser's network inspector.
  • Cross-site request forgery, cross-site scripting and phishing.
  • Man-in-the-middle attacks.

For full protection, the docs say to enable RLS on all tables and review your policies for the anon and authenticated roles regularly. Our guide to whether your Supabase anon key is safe (external) covers the same idea for the legacy key.

Do I need new RLS policies?

No. Supabase's docs say every key resolves to a built-in Postgres role. The publishable key maps to anon when no user is signed in and authenticated when one is, the same as the legacy key. Your existing policies keep working.

KeyUser signed in?Postgres role
Publishable keyNoanon
Publishable keyYesauthenticated
Secret keyNot applicableservice_role

Source: Supabase API keys docs, Oct 29, 2026.

That also means the switch doesn't fix weak policies. If a table has no RLS, or a policy uses using (true), it's just as open with the new key. Our Postgres row level security guide (external) walks through checking them.

Does Lovable or Bolt update this for me?

We don't know yet, and we haven't tested it. Check where your builder stores your Supabase keys, usually a secrets or environment panel, and whether it shows the new sb_publishable_ key or a long eyJ key.

If you see an eyJ key, you're on the legacy key. Swap in the publishable key wherever the builder stores it, then follow the steps above for any server code.

FAQ

When do anon keys stop working? Supabase says it's deprecating anon and service_role keys by the end of 2026. The docs we read on Oct 29, 2026, give no exact day. For now, legacy keys keep working until you disable them, but they are being deprecated, so switch early.

Is the publishable key safe in the browser? Yes, according to Supabase's docs, as long as Row Level Security is on for every table. The key itself is public. RLS is what decides what it can read or write.

Do I need new RLS policies? No. The publishable key maps to the same anon and authenticated roles as the legacy key. Existing policies keep working, and weak policies stay weak, so review them anyway.

Does Lovable update this for me? We haven't tested it. Check your builder's secrets or environment panel. A key starting with eyJ is a legacy key; swap in the sb_publishable_ key.

Is the secret key the same as service_role? It does the same job. Supabase says the secret key bypasses Row Level Security through the service_role role, but adds checks, like returning 401 when used from a browser.

Check your app

Switching keys is a good moment to check what your live app exposes. Run Greenlight My App's free scan on your live URL. It checks your homepage and up to five API paths it finds in your homepage and up to 15 of the scripts it loads for secret keys that shouldn't be there. The scan is automated, read-only and educational, not a security audit, and "nothing found" isn't a guarantee that nothing is exposed.

Sources

On this site

Related posts

Greenlight My App is independent and not affiliated with or endorsed by Supabase, Lovable, StackBlitz (Bolt) or Vercel (Next.js). Product names are trademarks of their owners. Supabase facts are paraphrased from its API keys docs as read on Oct 29, 2026. The docs say legacy keys are deprecated by the end of 2026 with no exact date. We have not created these keys in a test project, so the dashboard steps are untested by us. This page is general information, not professional security advice, legal advice, a security audit or a guarantee. Check your own setup against the vendor's current docs.