How to check if your Supabase tables are exposed to the public
How to check if your Supabase tables are exposed to the public
Supabase is fantastic for shipping fast. It is also the single most common place we see AI-built apps leak data, and almost always for the same reason: Row Level Security was never turned on, so anyone with the public key can read every row in your tables.
The catch is that your public key is not a secret. It ships inside your app's JavaScript, visible to every visitor. So if Row Level Security (RLS) is off, "anyone with the key" means "anyone on the internet."
Here is how to check, in a couple of minutes, whether your tables are open.
Why this happens
When Supabase creates a table, RLS is not automatically enforced with a policy that scopes rows to the right user. Builders like Lovable, Bolt, and Replit will happily wire up your frontend to read and write that table using the public anon key. Everything works in the demo, so the missing policy never gets noticed. The app ships, and the table stays readable by the world.
It is not a bug in Supabase or in the builder. It is a step that quietly gets skipped, and there is no error to tell you.
The manual check
- Open your Supabase dashboard, go to Authentication, then Policies (or Table Editor and look at each table's RLS status).
- For every table, confirm two things: RLS is enabled, and there is at least one policy that limits rows to the user who should see them (for example,
auth.uid() = user_id). - A table with RLS off, or with a policy like
truethat allows everyone, is readable by any visitor.
If you want to prove it to yourself, open your live app, view source, and search the bundle for your Supabase URL and anon key. That is the exact key any stranger has. Anyone can point it at your REST API and read whatever RLS is not protecting.
The fix
For each exposed table:
- Enable RLS.
- Add policies that scope reads and writes to the right user, never a blanket
true. - Treat the data as public until you have done this.
RLS is per-table, so a new table you add next week starts the cycle over. It is worth re-checking whenever your schema changes.
Check it in a few seconds
Doing this by hand is a good habit, but it is easy to miss a table. We built a free scanner that checks it for you: paste your app URL at task-bounty.com/scan and it tells you what your live app exposes to any visitor, including which Supabase tables the public key can read. It is read-only, never logs in, and never writes anything.
A clean result is not a guarantee you are bulletproof, but an open table is exactly the kind of thing that turns into a public incident. Find it before a stranger does.