Supabase
The Supabase anon key, explained: yes, it is meant to be public.
The Supabase anon key is designed to live in your front-end code and be seen by everyone. It is not a leaked secret. The one catch is that it is only safe when row-level security is enabled, because without RLS that public key can read and write your entire database.
The key is not the problem. The missing rule is.
People find the anon key in their page source, panic, and try to hide it. That is the wrong fix, because the key is public by design and cannot be hidden from a browser that needs to use it. The real question is what the key can reach. With row-level security on, it can only do what your policies allow. With RLS off, a key that is meant to be shared becomes a master key to data that is not.
What the anon key is for
Supabase gives every project two main keys. The anon key is the public one: it identifies your project and lets the front end talk to Supabase on behalf of anonymous or logged-in users. It is meant to ship in client code, the same way a publishable API key does. Anyone can read it out of your app, and that is expected.
The anon key carries no special power of its own. It acts as whatever user is currently authenticated, or as an anonymous visitor if no one is logged in. What it can actually do is decided entirely by your row-level security policies.
Why it is only safe with RLS on
Here is the catch that turns a safe public key into a serious exposure. If a table has no row-level security, the anon key can read and write every row in it, because there is no policy telling the database to refuse. So a stranger who copies your anon key, which takes seconds, can query that table directly and receive its entire contents, or insert forged rows into it.
This is the most common serious finding in Supabase apps, and it is why the key showing up in your page source is a red herring. The exposure is never the visible key. It is the invisible missing policy behind it.
How to check your anon key is safe
Confirm row-level security is enabled on every table that holds real data, and that each table has policies scoped to what it should allow. Then verify from the outside: use the anon key to query your tables the way a stranger would, and confirm each returns only public data or nothing. If a table hands back private rows to the bare anon key, that table has no working policy.
The service role key is the opposite story. That one is a true secret, it bypasses RLS entirely, and it must never leave your server. If you find the service role key in front-end code, rotate it today.
Common questions.
- Someone found my Supabase anon key. Am I compromised?
- Not by the key being visible, because it is public by design. Whether you are exposed depends on your row-level security. If RLS is on and your policies are correct, the visible key can only do what you allowed. If RLS is off, the key can reach everything, and that needs fixing now, but by adding policies, not by hiding the key.
- What is the difference between the anon key and the service role key?
- The anon key is public and respects row-level security. The service role key is secret, bypasses RLS entirely, and must stay on the server. Confusing the two, or shipping the service role key to the browser, is a critical mistake.
- Can you check whether my anon key exposes anything?
- Yes. Our Supabase security audit queries every table with the anon key exactly as an attacker would and tells you what, if anything, comes back that should not.
Related services.
Let's build something real.
Tell us about your app or idea. You'll get a clear plan and a fixed quote back within 24 hours.
