TL;DR: Your Supabase app may be leaking data right now. RLS is the fix. Most AI tools skip it. Here is how to check — and how to close the gap fast.

If you built your product with an AI tool and shipped it on Supabase, your row level security policies are the single line between "private data" and "public data." Most vibe-coded apps get this wrong — and they ship anyway.

AI tools write code that works. They don't always write code that holds up. Supabase RLS is the layer those tools skip most. The risks are real. 31 of 47 vibe-coded apps we scanned had RLS disabled.

Check your own setup right now with the free scan. No code access. No install. 60 seconds. Start there, then read the rest.

QuestionAnswer
What are Supabase RLS policies?
Postgres rules that decide which rows each user can read or write. Without them, the API returns everything to anyone with your public key.
Is RLS on by default?
No. RLS is off by default on many tables. Even when turned on, it blocks all access unless you write the access rules too.
What does a correct policy look like?
USING (auth.uid() = user_id) — limits each query to the logged-in user's own rows only.
How do I verify my setup?
Run a free scan at launchreadycode.com/#top. Live URL, no code access, 60 seconds.

What is Three States Your RLS Can Be In?

The vulnerability class described here is formally documented. OWASP A01:2021 — Broken Access Control is the most prevalent web application risk and the root cause of RLS and permission misconfigurations. CWE-284 (Improper Access Control) is the MITRE weakness taxonomy entry used by vulnerability databases to classify these findings.

Launch Ready Code benchmark: most Supabase projects we scan have Row Level Security disabled on at least one table containing user data — the single most common critical finding we issue. — LRC scan data, 2026

Launch Ready Code has scanned 700+ applications. Most ship with at least one critical finding, and the average Launch Readiness Score is ~44 out of 100 — LRC scan data, 2026.

Most founders think of RLS as a binary: on or off. It's actually three states:

P0 Finding — critical

RLS disabled on all tables. Any logged-in user can run SELECT * FROM users and get the full customer list. Found in 31 of 47 vibe-coded apps scanned. See the Quittr Firebase breach postmortem for a real example of what this looks like in production.

Most vibe-coded apps live in the middle state. RLS is "enabled." The toggle is green. The founder thinks the job is done. But the AI wrote USING(true) to silence errors. That rule lets every user in. It defeats the whole point.

What is Two Ways RLS Fails Silently?

What is Failure 1: RLS On With No Rules Set?

You flipped RLS on. You never wrote a policy. Postgres blocks all access. Your AI-generated frontend catches the empty response and either shows a blank state or falls back to cached data. The app "works" in testing. In production, real users see each other's data or see nothing at all.

What is Failure 2: USING(true) Shortcuts?

The AI wrote a policy to stop the errors. It wrote USING(true). This is a valid Postgres policy. But it means "allow all rows for all users." It's the opposite of security. It looks fine in the Supabase dashboard. It leaks all your data.

The fix is one line: swap USING(true) for USING(auth.uid() = user_id). That scopes each query to the user's own rows.

What is Right Rule for Each Table?

For any table that stores user data: turn RLS on in the Supabase dashboard, then add one policy per action. This is the SELECT policy:

-- One rule per action (SELECT, INSERT, UPDATE, DELETE)
CREATE POLICY "select_own" ON public.your_table
  FOR SELECT USING (auth.uid() = user_id);

Copy the same pattern for INSERT, UPDATE, and DELETE. Each one scopes to the user's own rows.

Apply this to every table with a user_id column. Tables with no user data — lookup tables, public configs — can keep RLS off. But any table touched by user actions needs this.

What Vibe-Coded Platforms Leave Open?

Lovable — builds Supabase fast. RLS is rarely in the first scaffold. See our Lovable Audit for the gaps it leaves.

Bolt.new — RLS is off in most Bolt projects. Often the secrets leak in the client bundle too. See our Bolt Security Audit.

Cursor / Replit — missing auth on API routes is the most common issue. USING(true) shortcuts are frequent.

Our Supabase Audit covers RLS, service_role leaks, JWT checks, and bucket access.

Our guide on the Supabase anon key vs service_role key explains exactly which key is safe to expose and which never is.

If you used any of these platforms, your Supabase RLS config deserves a direct check. The builder optimized for "it works," not "it holds."

Check your RLS config now?

Free scan. Live URL. No code access. Results in 60 seconds.

Run the free scan

What Comes After the Free Scan?

The free scan gives you a Launch Readiness Score. It flags the top issues across all four scan areas. RLS issues show up under Security as P0 or P1 based on what data is at risk.

Want a full fix list with time per issue? The Launch Readiness Audit ($499) covers every gap. Want the fixes done as PRs you approve? The DFY Technical Setup handles that. RLS is part of the full auth fix package.

Frequently Asked Questions

What are Supabase RLS policies in plain terms?

Postgres rules that decide which rows each user can see or change. Without them, Supabase hands every row to anyone with your public anon key.

Is RLS on by default in Supabase?

No. RLS is off by default on tables you create. You must enable it per table and then write policies. Turning on RLS with no policies blocks all access. That breaks the app without making it safe.

How do I check if my Supabase RLS is configured correctly?

Run a free scan at launchreadycode.com. It checks your live app for disabled RLS, USING(true) shortcuts, and leaked keys — no code access required, results in 60 seconds.

Does Lovable set up RLS for you?

Not by default. Lovable builds the Supabase client code but rarely sets up RLS policies. This is the most common finding in Lovable-built apps.

Research sources