Get an engineer for this one. Rotating is quick, moving the code server side is not
What you see. A scan, a developer or your own search of the live site's JavaScript found a key starting with sb_secret_ or a service_role token.
Why it happens
Supabase gives every project two kinds of keys. The publishable key (prefix sb_publishable_, or the older anon key) is designed to ship to the browser. Row Level Security, the rules on each table, decides what it can reach. The secret key (prefix sb_secret_, or the older service_role token) bypasses those rules completely. Supabase says to only use it in backend components of your app, and never in a browser, including on localhost.
AI builders put the secret key in the frontend when you ask them to make an admin page work or to get past a permission error. In a Vite app like a Lovable or Bolt export, every VITE_ variable is embedded at build time, so the key sits in a JavaScript file anyone can open. Whoever finds it can read, change or delete every row in every table, and the key keeps working from other tools until you retire it.
Fix it yourself
- Confirm it. Open your live site, press F12, open the Sources or Network tab and search the loaded JavaScript for
sb_secret_andservice_role. - Treat the key as leaked. In Supabase go to Settings > API Keys and create a new secret key. Do not delete the old one yet.
- Replace the old key everywhere it runs on a server, such as Edge Functions and webhook handlers. Only then delete the compromised key. Supabase warns that deleting cannot be undone.
- If the leaked key was a legacy service_role token, deactivate the legacy keys on the same page once nothing uses them. Deactivation is reversible if you missed a client.
- Ask your builder to move the admin logic into a server function that checks the caller is an admin, and to use the publishable key in the browser.
- Write proper table policies instead of bypassing them. See Users can see each other's data.
When to get an engineer
Hire an engineer when the key was live for more than a day, when more than one feature depends on it, or when you are not sure which server code uses it. Tell them when the key was deployed, which features broke when you removed it, and share the repository link. A single fix (rotation plus one feature moved server side) runs €99–$990. A cleanup where several admin features need server functions runs $1,500–$15,000. A one-off check for $49–$800 finds other leaks at the same time.
Top-rated companies for Supabase apps
Ranked by our score: published prices, scope of work, AI tools named, timing and a low-risk first step. How we score.
- 1Redlab10.0/10Best for: A full rescue by one team that keeps buildingFree first step · from $490
- 2Vibe Code Rescue (Lev Arakelyan)9.0/10Best for: A one-off check and a cleanupFrom $299
- 3LazyCodeLab9.0/10Best for: A one-off check and a cleanupFrom $399
Check these
No secret keys reach the browser
Open your live app, then DevTools, Sources, and search the loaded JavaScript for sb_secret_, sk_live_, sk-proj- and sk-ant-. Older Supabase keys are long tokens starting with eyJ: decode the middle part of each on your own machine, and if it contains "role":"service_role", your secret key is public. A publishable or anon key in the browser is expected.
Access rules are on for every table
In Supabase, open Table Editor: every table should show RLS enabled, with at least one policy. In Firebase, your rules should never say allow read, write: if true.
Admin actions are checked on the server
Hiding an admin button is not protection. Call the admin endpoint as a normal user and confirm it is refused.
Secrets live in the host's environment settings
Keys belong in environment variables on the server, not in the repository or in front-end code.
Questions
Is my publishable or anon key also a leak?
No. Supabase lists web pages and mobile apps as safe places for the publishable key. Your table policies, not the key, protect the data.
Can I just delete the key right now?
If server code still uses it, deleting it first takes your app down. Create the new key, swap it in, then retire the old one. Supabase also notes that creating new keys does not revoke the legacy ones.
Sources: Supabase docs: API keys; Supabase docs: Migrating to publishable and secret API keys; Supabase docs: Row Level Security; Lovable docs: Deploying and hosting outside Lovable.
