PlugLeakScan my app
← Guides

Supabase service_role key exposed? What it means and how to fix it (fast)

· PlugLeak

Found your Supabase service_role key in your frontend? Here's why it's critical, how to check, and the exact steps to rotate it and move it server-side.

Supabase gives every project two kinds of keys. The anon (or sb_publishable_…) key is designed to live in your frontend; it is only safe if Row Level Security (RLS) is enabled on your tables. The service_role (or sb_secret_…) key is different: it bypasses RLS completely. Anyone who has it can read, change or delete every row in your database and every file in storage.

How does a service_role key end up in the browser?

  • An AI builder hit an RLS error and "fixed" it by switching the client to the service_role key.
  • The key was put in an env var with a public prefix (VITE_, NEXT_PUBLIC_), which bundlers inline into the JavaScript every visitor downloads.
  • An admin page or script that uses the key was bundled with the public app.

How to check if yours is exposed

  1. Open your live app, press F12 → Sources, and search all files for eyJ (the start of a JWT) and sb_secret_.
  2. For each JWT, paste it into a JWT decoder and look at the role claim. anon is expected; service_role is an emergency.
  3. Remember to check lazy-loaded chunks, not just the first file — or run the free scan below, which decodes every JWT in every same-site chunk for you. How the scan works covers the file cap and the fact that it does not query your database.

Fix it in this order

  1. Rotate first. In Supabase → Project Settings → API, roll the service_role / secret key. Removing it from code is not enough: it is already in old bundles, caches and maybe bots' scrapes.
  2. Move privileged work server-side. Anything that truly needs elevated access goes into a Supabase Edge Function or your backend, reading the key from a server-only secret.
  3. Use the anon/publishable key in the client and write RLS policies so each user only sees their own rows.
  4. Check your data. Review the Supabase logs for unexpected activity since the key was first deployed.

Copy-paste prompt for Lovable / Bolt / Cursor

My Supabase service_role key is exposed in the frontend bundle. 
1) Remove every use of the service_role key from client-side code and public env vars (VITE_/NEXT_PUBLIC_).
2) Move any operation that needs elevated access into a Supabase Edge Function that reads the key from a server secret.
3) Make the client use only the anon/publishable key.
4) Enable RLS on every table and add policies so users can only access their own rows.
List every file you changed.

After rotating and redeploying, re-scan to confirm the old key is gone from every chunk.

Check your app now — free, passive, about 20 seconds.

Same scanner as the homepage scan. Paste the live URL. It reads what a visitor already downloads. It does not log in or query your database.

https://