AppInspected

Fix guides

Your Supabase service_role key is in your frontend. Here's what to do.

Last reviewed October 15, 2026 against the providers' current documentation.

The short version

Treat it as stolen. Create a new Supabase secret key, move every call that needs it to your server, then turn the old key off. Removing it from your code alone doesn't help, because the old key keeps working until you turn it off.

Why it matters

The service_role key (and its newer replacement, the sb_secret_ key) belongs to a database role that skips every Row Level Security policy. Anyone who opens your site can copy it from the JavaScript and read, change or delete every row in every table, including other users' data.

Fix it, in this order

  1. Confirm it's really the service_role key

    Supabase's legacy keys are long strings starting with eyJ. The middle part of the key (between the two dots) says which role it is. If it contains service_role, it's the dangerous one. New-style keys are easier: sb_secret_… is dangerous, sb_publishable_… is fine. Our free check decodes this for you.
  2. Create a new secret key

    In the Supabase dashboard, open Project Settings → API Keys and create a new secret key. Supabase now recommends these over the legacy service_role key, and switching to them avoids the downtime that rotating the legacy keys causes.
  3. Move the work to the server

    Find every place your app used the leaked key. Anything that needs admin rights has to run on a server: a Supabase Edge Function, a Next.js API route or server action, or your backend. Put the new secret key in that server's environment variables, never in a variable the browser can read (VITE_…, NEXT_PUBLIC_…, EXPO_PUBLIC_…).
  4. Use the publishable key in the browser

    Your frontend should use only the publishable key (sb_publishable_…) or the legacy anon key. Both are designed to be public, as long as Row Level Security is on for your tables.
  5. Deploy, then turn off the leaked key

    Deploy the fixed app and confirm it works. Then, on the same API Keys page, deactivate the legacy service_role key (or delete the leaked secret key). Do this only after the new setup works, because the change takes effect immediately.
  6. Check whether anyone used it

    Look at your tables for rows you don't recognize, missing data, or new admin users, and check the API logs in the Supabase dashboard for unusual activity. If you store personal data and see signs of access, you may have legal duties to notify users; ask a lawyer where you operate.

Or ask your AI tool to do it

Paste this into Lovable, Bolt, Cursor, Claude Code or whichever tool built your app. Review what it changes before you deploy.

My Supabase service_role key was exposed in frontend code. Find every place the app uses the service_role or secret key. Move each of those operations into a server-side function (Supabase Edge Function or an API route), read the key from a server-only environment variable, and make the frontend call that function instead. The browser must only use the publishable/anon key. Do not put the key in any VITE_, NEXT_PUBLIC_ or EXPO_PUBLIC_ variable. Then list the tables the frontend reads or writes so I can check their Row Level Security policies.

How this happens

It usually starts with a permission error. The app can't read a table because Row Level Security blocks it, and the quickest fix an AI tool finds is to swap in the key that ignores those rules. It works instantly, so it ships. The real fix was a Row Level Security policy that lets each user see their own rows.

Check that it's really fixed

After you deploy, run the free check. It reads your live site the way an attacker would and tells you if any secret key is still visible.

Check my app free

Questions

Is it enough to delete the key from my code and redeploy?

No. Copies of your old JavaScript stay in browser caches, search engine caches and anyone's downloads. The key itself must be turned off in Supabase.

Will my users get logged out?

Switching from the service_role key to a new secret key is designed to avoid downtime, and secret keys aren't the tokens your users log in with. Rotating the project's legacy JWT secret is a different, bigger step: Supabase says it immediately invalidates the existing keys and cuts connections until you deploy new ones. Avoid that path unless you need it.

Sources

Related guides