Do I need Row Level Security?
If any table holds data that should not be public, yes. Row Level Security is the setting that decides who can read or change each row. With it off, anyone holding your public key (which ships in every browser) can read the whole table.
The only tables that are fine without it are ones you intend to be fully public, like a list of blog posts or product names you would happily show a stranger. Even then, turning RLS on with a simple 'anyone can read' policy is clearer than leaving it off, because 'off' and 'public on purpose' look identical from the outside.
The rule of thumb: enable RLS on every table, then write a policy for each. Private tables get a policy limiting reads to the right user; public tables get a policy that says so out loud.
See which of your tables are unprotected
What it means
Your database tables can be read by anyone, not just logged-in users. Someone could open your app's data — customer emails, orders, private records — without ever creating an account.
Why AI tools cause it
Supabase only protects a table once you turn on Row Level Security (RLS) and write access rules for it. AI tools frequently build a working app without doing that, so the tables are wide open by default.
How xlogs checks it
xlogs finds your public Supabase URL and anon key in your app (the same ones your frontend uses), asks the database as an anonymous user which tables it can read, and flags any that return real rows. Read-only: it never writes or deletes.
How to fix it
The goal: Row Level Security is enabled on every table, with policies so a table only returns rows to users allowed to see them; no table returns private data to an anonymous request.
- Enable Row Level Security (RLS) on every table, especially the affected spot
- Add a policy per table so only authenticated users can read/write their own rows (keep intentionally-public tables public on purpose)
- Re-check that an anonymous request no longer returns private rows
In my app (the spot the scan shows): anyone can read this database table. Please make this true: Row Level Security is enabled on every table, with policies so a table only returns rows to users allowed to see them; no table returns private data to an anonymous request. Steps: Enable Row Level Security (RLS) on every table, especially the spot the scan shows; Add a policy per table so only authenticated users can read/write their own rows (keep intentionally-public tables public on purpose); Re-check that an anonymous request no longer returns private rows. Then tell me exactly what you changed, and do not print any secret values back to me.
Then verify: After you deploy the policies, xlogs repeats the same anonymous read test and confirms the table no longer returns data without a login.
Full step-by-step fix guide, with a copy-paste block for each AI tool →
Common questions
Does turning on RLS break my app?
Only if you enable it without policies, so add them at the same time: enable RLS, then add a policy allowing users to read their own rows, and keep any intentionally public tables public on purpose. Then re-scan to confirm private tables no longer leak.
