All posts

Field guide

Supabase service_role key exposed: what to do right now

If your Supabase service_role key ended up in client code, a public repo, or a browser bundle, your whole database is exposed, because that key ignores Row Level Security and has full admin access. Here is exactly what to do, in order.

Last updated

This is the one Supabase mistake that is a genuine emergency. The service_role key bypasses Row Level Security entirely and has full admin access, so if it reached the browser or a public repo, anyone who found it can read, change, or delete everything in your database. Move quickly, in this order.

1. Rotate the key now

Do this first, before anything else. In your Supabase dashboard, generate a new service_role key and update it wherever your server reads it from, then the old key stops working. Every minute the exposed key is still valid is a minute someone can use it. Do not start by cleaning up the code; start by making the leaked value useless.

Want to see exactly what Prbl flags? Watch it scan a demo app, no repo or account needed.

See a live scan →

2. Get it out of the client and the repo

The service_role key must never be in client code or committed to a repository. Remove it from any client component or browser-reachable file, and if it was committed, remember that deleting the file does not remove it from git history, so you also need to purge it from history. The new key belongs only in a server-side environment variable.

3. Check for damage

Assume the key was found and used. Look for signs of abuse: rows that were added, changed, or deleted unexpectedly, unfamiliar activity in your logs, and any data that should not be there. The service_role key grants total access, so the range of possible damage is wide. If you hold sensitive user data, treat this as a potential breach and respond accordingly.

4. Fix the root cause: configure RLS

The service_role key usually ends up on the client because someone used it to skip Row Level Security. The real fix is to set RLS up so the client only ever needs the anon key. Enable RLS on every table with owner-scoped policies, and confirm an anonymous read returns nothing. The full walkthrough is in the Supabase RLS checklist.

Frequently asked questions

How bad is an exposed service_role key?

As bad as it gets for a Supabase project. The service_role key bypasses Row Level Security completely and has full admin access, so anyone who has it can read, change, or delete any data in your database, regardless of your policies. Unlike the anon key, which is public by design and limited by RLS, the service_role key is meant to stay server-side and grants total control. Treat an exposure as a full database compromise.

Is rotating the key enough, or do I need to do more?

Rotating is the essential first step, but assume the exposed key was already used. If it sat in a public repo or a browser bundle, bots may have found it, so after rotating, check for signs of abuse: unexpected data changes, new or deleted rows, and unfamiliar activity in your logs. Rotation stops future access with the old key; it does not undo anything already done with it.

How did the service_role key end up in my client code?

Usually an AI tool or a copied snippet used it to make an operation work without configuring Row Level Security, since the service_role key sidesteps RLS and just works. Then that code ran in the browser or got committed. The fix is not only to remove the key but to set up RLS so you never need the service_role key on the client in the first place.

Which key should the client actually use?

Only the anon key, which is designed to be public and is limited by your RLS policies. The service_role key belongs exclusively in server code, edge functions, or route handlers, read from an environment variable. If a client operation seems to need the service_role key, that is a sign RLS is not set up correctly, and the answer is to configure RLS, not to expose the admin key.

Confirm it's really gone

After rotating and cleaning up, verify the service_role key is not still sitting in a bundle or your history somewhere. A scan reads what your deployed app serves and the repo the way an attacker's bot does, and flags a service_role key that reached the client. Run a free scan to confirm.

Prbl scans your live app or your codebase for exactly the kinds of issues above.

Supabase service_role Key Exposed: What to Do Right Now: Prbl