Leaked an API key? › Supabase
Leaked Supabase service_role or secret key: what to do in the next 10 minutes
Last updated: October 24, 2026. Steps checked against Supabase's own docs on October 24, 2026.
Short answer: A secret key bypasses every Row Level Security policy, so treat your data as exposed. Supabase's order: stop the leak at its source, create a new secret key, switch everything to it, then delete the leaked key.
Which Supabase keys are secret?
- Secret: Secret keys: sb_secret_...
- Secret: Legacy service_role key (a long JWT starting with eyJ)
- Meant to be public: Publishable keys (sb_publishable_...) and the legacy anon key are meant to be public; Row Level Security is what protects your data.
The next 10 minutes
Times are a rough guide. Do the first step before anything else.
1. Stop the leak at its source (Minutes 0-2)
- Supabase's guidance starts with "Don't rush": fix the root cause before you rotate, or the new key leaks the same way. Remove the key from any VITE_, NEXT_PUBLIC_ or other browser-side code and from committed files.
- Your browser code should use only the publishable (or legacy anon) key.
2. Create a new secret key and switch to it (Minutes 2-5)
- In the Dashboard, open Settings → API Keys and create a new secret key.
- Replace the leaked key everywhere your server-side code uses it (Edge Functions, API routes, cron jobs). If the leaked key was the legacy service_role JWT, replace it with the new secret key, then confirm every component uses the new key.
3. Retire the leaked key (Minutes 5-7)
- For an sb_secret_ key: delete it in Settings → API Keys. Supabase notes deleting can't be undone, so only do it once everything uses the new key.
- For the legacy service_role key: deactivate the legacy keys in the same section. Deactivation is reversible if you find a client you missed. It applies to the legacy keys, so move browser code from the anon key to a publishable key first.
4. Check your data and turn on RLS (Minutes 7-10)
- Look for rows that were changed or deleted and auth users you didn't create, and check your project logs.
- Make sure Row Level Security is on for every table, then run Security Advisor and fix its error-level findings.
Good to know
- New sb_secret_ keys are rejected (HTTP 401) when sent from a browser, but Supabase notes an attacker can still use a leaked one from other tools, so delete it.
- Supabase is deprecating the legacy anon and service_role keys by the end of 2026 in favor of publishable and secret keys.
After the first 10 minutes
Move the code that needs the key to the server (an API route, serverless function or Supabase Edge Function), keep the key in a server-only environment variable, redeploy, and re-check your live site. The general plan, with a prompt you can paste into Lovable, Bolt, Cursor or Claude Code, is in I leaked an API key in my vibe-coded app. What do I do now?
What SniffPup checks, and what it doesn't
A free SniffPup scan reads only what your live site serves to the public: secret key patterns in HTML and same-origin JavaScript (masked in the report) and public files such as /.env and /.git/config. It never uses a key it finds. It can't see your repo, your server or Supabase's logs, so the steps above are always on you. A clean report is not a guarantee of security.
Sources
Supabase can change its dashboard and steps at any time. If something here doesn't match what you see, follow Supabase's docs and tell us.