Is my Supabase key safe to expose?
Supabase gives you two keys. One is meant to be public and one must never leave your server, and the only difference between them is a word buried inside the key. Paste one and find out which you have.
This runs entirely in your browser. The key is never sent anywhere, stored, or logged — there is no server involved in this page at all.
Two keys, one of which ends careers
anon key
also called the publishable key
Belongs in your frontend
Can only reach what your row-level security policies allow. On a table with security switched off, that is everything on it.
service_role key
also called the secret key
Server-side code only, never a browser
Ignores every policy you have written. Reads, changes and deletes anything in your database, including other people's rows.
Anon, service_role and what to do
Checking a whole app rather than one key? Scan your published site or see which variables reach the browser.
What is the difference between the anon key and the service_role key?
The anon key is designed to be public and ships in your frontend. What it can reach is decided by your row-level security policies. The service_role key ignores those policies entirely — it is an administrator key, meant for server-side code, and anyone holding it can read and change all of your data.
Is it a problem that my anon key is visible in my JavaScript?
No. That is what it is for, and every Supabase app works this way. The thing worth checking is not whether the key is visible but whether row-level security is enabled on your tables — with it off, that public key reads your data for anyone who asks.
I found a service_role key in my app. What now?
Rotate it in your Supabase dashboard immediately, before anything else. Assume the current value is known — a key that has been in a browser bundle is public whether or not anyone has used it yet. Then move whatever needed it into server-side code, such as an edge function.
Do you store the key I paste?
We cannot. This page has no server behind it: the check runs in your browser, in JavaScript you can read, and there is no request to send the key anywhere. You can disconnect from the internet and it will still work.
How did a service_role key end up in my app in the first place?
Usually by pasting it into an environment variable with a public prefix — NEXT_PUBLIC_ or VITE_ — because the app would not work without a key and that was the key to hand. It is a very easy mistake, and one audit of AI-built apps found roughly a third of them had made it.