Guide · Supabase
Supabase says “RLS disabled in public”. What it means and how to fix it.
It means a table in your database has no rule about who may use it. Supabase treats this as its most serious kind of warning, because anyone who has your project’s address can read, change or delete everything in that table, without signing in. The fix is to switch the rule on for each table, then say who is allowed in.
What does “RLS disabled in public” mean?
RLS stands for row level security. It is a rule on a table that says who is allowed to read or change each row in it. Public is the part of your database your app talks to straight from the visitor’s browser. Put together, the warning says: this table can be reached from any browser, and nothing checks who is asking.
Supabase labels it “Table publicly accessible” and marks it as an error, not a suggestion. In its own words, anyone with your project’s address can read, edit, and delete all data in this table.
Is it really that serious?
It depends on what is in the table, and on one thing people miss. If the table holds anything about a person (names, emails, phone numbers, bookings, messages, payments), a stranger can copy all of it in one request. That is the kind of leak you may have to tell every customer about.
If the table only holds things that are already on your public pages, like a product list or a menu, being readable is fine. Being changeable is not. Without the rule, a stranger can also rewrite your prices or delete the list, so even a table of public information needs it switched on, with a rule that lets anyone read and nobody else change.
How did my app end up like this?
Nobody chooses it. A table made with a written instruction, which is how Lovable, Bolt, Cursor and the rest make them, starts with no rule unless the instruction adds one. And an app with no rules works perfectly on the first try, so the tool has every reason to leave them off and nothing tells you. The key your app hands every visitor is not the mistake; Supabase means it to be public. The missing rule is the part that was supposed to stop a stranger.
How do I fix it?
1. See which tables it is
In your Supabase dashboard, open Advisors, then Security Advisor. Every table with the warning is listed by name. Write the names down; you will check them again at the end.
2. Ask the tool that built your app to fix it
Paste this into Lovable, Bolt, Cursor or whichever tool you used:
Turn on row level security for every table in the public schema of my Supabase database. Then add rules so that signed in users can only read and change their own rows, and visitors who are not signed in can only read the tables that are meant to be public, such as a product list. Never put the service role key or any secret key in code that runs in the browser. When you are done, list every table you changed and the rule you gave it.
Read the list it gives back. Every table you wrote down should be on it, and any table holding people should only be readable by the person it belongs to.
3. Or do it yourself in Supabase
In the dashboard, open the SQL Editor and run one line per table, with your table’s name in place of bookings:
alter table public.bookings enable row level security;Your app will stop showing that table straight away. That is expected: the rule is now on, and it lets nobody in until you say who may. For a table where each row belongs to one signed in person, this is the rule Supabase’s own guide gives, with your table’s name and its owner column in place of todos and user_id:
create policy "Individuals can view their own todos."
on todos for select
to authenticated
using ( (select auth.uid()) = user_id );If writing rules by hand is not something you want to do, step 2 is the better route. The tool knows which column holds the owner; you do not have to.
4. Check that it worked
Run the Security Advisor again; the tables should be gone from the list. Then check from the outside, the way a stranger would: our free database check takes your web address, finds your app’s public key the way a visitor’s browser does, and tells you which tables a stranger can still read, with every value blanked past its first two characters.
Should I hide my Supabase key too?
No, not the one your app already shows. The anon key (Supabase now also calls it the publishable key) is meant to be in the browser, and on its own it is harmless; it only becomes dangerous when a table has no rule. The one that must never be in the browser is the service role key, or any secret key. Supabase says it skips every rule, so whoever has it can do anything to your database. If yours was ever in your app’s code, replace it in the Supabase dashboard today.
How common is it?
In our 30 October 2026 study of 50 public apps built with Lovable and Bolt, we could test the database of 6 of them. 1 of the 6 had a table a stranger could read. That is a small sample and we say so; the study page explains how the apps were chosen and what the numbers cannot tell you.
GuardCue checks apps built with AI tools and explains what it finds in plain English, for the person who built it rather than for a developer. Check your database, free.