How do I check if my Supabase tables are readable by anyone?
Ask your own database for rows using only the public anon key, the way a visitor's browser does. If rows come back from a table that should be private, Row Level Security is off or a policy is too loose.
Why
Every Supabase table in the public schema is reachable through the REST API. Row Level Security decides what each request may see. A table with RLS off, or with a SELECT policy whose condition is always true, returns every row to anyone holding the anon key, which is in your site's code.
The Supabase dashboard's Security Advisor flags tables with RLS turned off (lint 0013) and policies that are always true. It won't tell you whether a table that has RLS but a loose policy leaks private rows, so test with the anon key too.
How to check
- Run the request below against your own project, once per table, with your anon key. An empty list [] means RLS blocked it (or the table is empty); rows mean anyone can read them.
- For every private table, enable RLS and add policies that match rows to the signed-in user, for example auth.uid() = user_id.
- Or scan your app with Shippable, which finds the table names your app uses and runs this check on each one, read-only.
More on this: Database tables anyone can read, from the Vibe-Code Top 10.
Check your app
Your first app is free, and it is read-only. You prove the app is yours with a one-line tag first.
More questions
- Is the Supabase anon key safe to expose?
- Is my Lovable app secure?
- Does verify_jwt protect my Supabase edge functions?
- Which environment variables end up in my app's browser code?
Updated 2026-10-06.