Supabase and RLS: the flaw that shows up in almost every AI-built app
In Supabase, the public key sits in the browser — and the only thing between it and your data is RLS. It is also what we most often find misconfigured in AI-built apps.
13 October 2026
Almost every app built with Lovable, Bolt or v0 uses Supabase. It's an excellent choice: a PostgreSQL database, authentication and storage, ready in minutes. But it has a particularity most founders don't know about — and that AI tools often get wrong.
The public key really is public
The app talks to the database directly from the browser, with a public key ("anon", or "publishable" in newer projects) that anyone can see in the page's code. This is intentional: Supabase was designed this way.
What makes it safe is Row Level Security (RLS) — rules in PostgreSQL that decide, row by row, what each request can read or change. The Supabase documentation is clear: RLS should be enabled on every table exposed to the browser.
In other words: without RLS, the public key gives access to the whole table.
The mistakes we find most often
1. Tables without RLS enabled. The AI creates a new table for a feature and forgets to enable the rules. Supabase warns you in the dashboard — but only if someone looks.
2. Rules that let everything through. During development a permissions error appears and the fastest fix is a rule that allows everything. The feature starts working — and the rule stays forever.
3. Rules that trust the user. In multi-company apps, the rule checks whether the row belongs to the company named in the request. The problem: the user names the company. The rule must use the authenticated identity (auth.uid() and the memberships stored in the database), never a value sent by the browser.
4. The service key in the wrong place. The service_role key (or "secret", in newer projects) bypasses every rule. It is for the server, never the browser — but it shows up in frontend code more often than it should.
5. Correct rules, but slow ones. Rules that run subqueries without indexes execute on every row of every query. With real data, the app becomes slow and nobody knows why.
How to check your app
- Open the Security Advisor in the Supabase dashboard and confirm there are no tables without RLS.
- Search your frontend code for
service_role. - Create two test accounts in different companies and try to see one's data from the other.
- Review every rule that contains
truewithout conditions.
If any of these steps leaves you unsure, it's a good sign that someone should take a careful look.
What we do in an audit
We map the rules table by table, test access as different users and as an outsider, and leave automated tests for the rules in the pipeline — so a fixed leak doesn't come back with the next AI-generated change.
Do you have a Supabase app built with AI? Take the 2-minute diagnostic or book a 30-minute call.
See also: Audits and fixes for AI-built apps.
Source: Supabase — Row Level Security.