How to check if your Lovable app leaks your Supabase key (2-minute test)
A two-minute browser test for a Lovable app: tell a Supabase anon key, which belongs in the page, from a service_role or sb_secret key that does not.
Lovable puts a Supabase anon key in the app on purpose. That key is supposed to ship to the browser. The leak is a second key beside it: a JWT whose role is service_role, or a secret that starts with sb_secret_. Either one bypasses row-level security.
This test looks at the published site, not the Lovable editor. It also applies to Bolt, Cursor, Replit, and v0 apps, because the check is the JavaScript a stranger can already download.
The two-minute test
- Open the live URL your customers use. Skip the editor preview if it is a different host.
- Open DevTools, then the Network tab. Reload and filter by JS, or use Sources and open the app bundle.
- Search the file for
service_role,sb_secret_, andeyJ. The homepage HTML counts too, not only the script files. - For each JWT (three chunks separated by dots), decode the middle chunk locally. Do not paste the token into a website.
- Read
role.anonmay stay in the client.service_rolemay not. A value starting withsb_secret_may not, even without a JWT.
function payload(token) {
const part = token.split(".")[1];
const json = atob(part.replace(/-/g, "+").replace(/_/g, "/"));
return JSON.parse(json);
}
payload("eyJhbGciOiJIUzI1NiJ9.PASTE_THE_MIDDLE_CHUNK.signature");What the role means
anonin the bundle is expected. Safety depends on row-level security. Continue with the RLS checker.service_role, orsb_secret_, is already public if it is in that file. Follow the 10-minute rotation steps before you edit features.- A project URL like
https://abcd.supabase.cois normal. The URL alone is not a key.
Prompt to paste into Lovable
Search this project for a Supabase service_role key and for any value that starts with sb_secret_.
Remove those from client components and from any variable prefixed with VITE_ or NEXT_PUBLIC_.
The browser may keep the anon key (JWT role "anon") or a publishable key.
Put the service role only in server code that is not bundled for the browser.
After I rotate the key in Supabase, update the server env and redeploy.What the free scan actually checks
AppPulse downloads the public homepage and up to six script files linked from it, same-origin files first. In that text it flags a JWT when the payload role is service_role and the token looks like Supabase (the issuer contains “supabase”, or the payload has a project ref). It also flags a value matching sb_secret_. An anon JWT is not reported as a leak.
The scan does not open your Lovable project, your Supabase dashboard, or an environment variable that never shipped in those files. It does not use a service key to query the database. A key hidden in a seventh script, or only in chat history, will not show up.
Questions
Is a Supabase anon key in a Lovable app a leak?
No. The anon key is meant to be in the browser. It is safe only when row-level security stops it from reading private tables. A service_role JWT or a key starting with sb_secret_ in that same bundle is a leak.
Does this test open my Lovable project?
No. You inspect the published site, the JavaScript the browser already downloads. The same limit applies to the free scan: homepage HTML plus up to six linked script files.
Is my Lovable app secure if this test finds only an anon key?
Not yet. An anon key still has to be paired with row-level security. Use the RLS checker next. This test does not look at your Lovable account, server logs, or environment variables that never shipped to the browser.
Other guides
Run it against your live URL
The free scan reads the public site only. No account, no writes, and no use of a service key if one is sitting in the bundle.
Scan your URL