LeakPatrol › Guides

Supabase service_role key exposed? What to do in the next hour

By LeakPatrol · Updated 4 November 2026

If your Supabase service_role key (or a new-style sb_secret_… key) is in your site's JavaScript, a public repo or a screenshot, treat it as stolen. Unlike the anon key, it skips Row Level Security entirely: anyone who has it can read, change and delete every row in every table, every file in Storage, and every user account. Here is what to do, in order.

1. Confirm where it leaked

The usual ways it gets out in apps built with Lovable, Bolt or Cursor:

To check your live site: open it, press F12, go to Sources (Chrome) or Debugger (Firefox), search all files for service_role and sb_secret_. A legacy key is a long JWT starting with eyJ; paste it into our key checker and it tells you whether it is the anon or the service_role key, in your browser, without sending it anywhere.

2. Move the code that needs it to the server

Revoking the key breaks whatever used it, so first move that code into a Supabase Edge Function (or your own server), where the key stays secret, and make the browser call the function instead. Then make the frontend use only the anon or sb_publishable_ key.

3. Revoke the leaked key

If you use the new API keys (sb_secret_…): in the Supabase dashboard, open Project Settings → API Keys, create a new secret key, put it in your Edge Function secrets, then delete the leaked one. Nothing else changes.

If you use the legacy JWT keys (service_role starting with eyJ): you can't revoke just that key. Either switch to the new publishable and secret keys and then disable the legacy keys, or rotate the project's JWT secret, which also replaces the anon key and signs every user out. Switching to the new keys is usually less disruptive.

Removing the key from your code or Git history does not fix the leak on its own. Copies already exist. Only revoking it does.

4. Check whether anyone used it

A prompt to paste into Lovable, Bolt or Cursor

My Supabase service_role key is exposed in the frontend. Fix it:
1. Find every place the service_role or sb_secret_ key is used in
   frontend code or VITE_ / NEXT_PUBLIC_ variables and list them.
2. Move each operation that really needs it into a Supabase Edge
   Function that checks the user is signed in and allowed to do it,
   and reads the key from Edge Function secrets.
3. Make the frontend use only the anon / publishable key, and make
   it work through Row Level Security policies instead of bypassing them.
4. Do not disable RLS or loosen policies to make things work.
Show me the changes before applying them. I will revoke the old key
in the Supabase dashboard myself.

Once it is fixed, LeakPatrol's free scan reads the JavaScript your live site loads and flags service_role, sb_secret_ and other secret keys in about a minute, so you can confirm it is gone.

Check your app in a minute

Free, read-only, no sign-up. Every problem comes with a plain-English fix and a prompt for your AI tool.

Get the 10-point checklist

Every check we run on AI-built apps, with how to do each one yourself. Straight to your inbox.

Questions

What happens if my Supabase service_role key is exposed?

Anyone who has it bypasses Row Level Security and can read, change and delete every row in every table, every file in Storage, and manage user accounts. Treat it as stolen and revoke it.

Is removing the key from my code enough?

No. Anyone who already copied it can keep using it. You have to revoke it in the Supabase dashboard, after moving the code that needs it to an Edge Function.

How do I rotate a legacy Supabase service_role key?

A legacy JWT service_role key cannot be revoked on its own. Switch to the new publishable and secret API keys and disable the legacy keys, or rotate the JWT secret, which also changes the anon key and signs all users out.

Is the Supabase anon key safe to expose?

Yes, the anon or publishable key is meant to be public, but only if Row Level Security is on with correct policies for every table. The service_role and sb_secret_ keys must never be in the browser.

More guides