The correct Supabase RLS setup enables RLS on every table holding user data, writes SELECT and INSERT policies that check auth.uid() = user_id, and verifies each policy using a non-owner JWT in the Table Editor. Without RLS, all rows in a Supabase table are publicly readable by anyone who holds the anon key — which is embedded in every Lovable and Bolt app by default.
Before we go further: you can check your own setup right now with our free scan. No code access. No install. 60 seconds. Start there, then read the rest.
Key Takeaways
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.
| Question | Answer |
|---|---|
| What are Supabase RLS policies? | Postgres rules that decide which rows each user can read or write. Without them, the Supabase API returns everything to anyone with your public key. |
| Is RLS on by default? | No. RLS is off by default on many tables. You must enable it AND write policies. Enabling it alone is not enough. |
| Why do policies fail silently? | Two ways: RLS enabled with zero policies (deny-all surprises) or a USING(true) policy that exposes every row to every user. |
| How do I test mine fast? | Run our free scan or three diagnostic SQL queries in under 60 seconds. |
| Does this connect to compliance? | Yes. Exposed user data is a direct GDPR compliance and EU AI Act compliance problem, with fines up to €15M. |
Why Supabase Row Level Security Policies Matter More Than Anything Else?
Supabase is secure by design. The problem is what gets disabled, skipped, or half-configured when an AI builder generates your backend.
When Supabase row-level security is disabled on a table, the Supabase PostgREST API applies no row filtering whatsoever. Every row goes to anyone who hits the endpoint.
And the anon key — the one sitting in your client bundle — is public. It is meant to be public. That means your Supabase row level security policies are the only thing standing between a visitor and your entire users table.
In May 2025, over 170 production apps built with Lovable had their entire Supabase databases publicly readable. No login, no exploit, no technical skill required. None of those founders knew. Their apps looked fine. That is what we are here for.
What is your Launch Readiness Score?
Run the free scan to see your Supabase RLS status, secrets exposure, and auth gaps in 60 seconds — no code access needed.
Run Free Scan → launchreadycode.com · No install · No code accessHow Supabase Row Level Security Policies Actually Work?
RLS is enforced through Postgres. When you enable it on a table, Postgres starts checking every query against the policies you wrote. A policy is a rule: "this user can see this row if X is true." No policy, no access. Wrong policy, total access.
There are three states your tables can be in:
- RLS off: the API returns every row to everyone. The worst case.
- RLS on, no policy: Postgres denies everything, or your app crashes silently when results come back null with no error check.
- RLS on, correct policy: each user sees only their own rows. This is the goal.
That middle state is where most vibe-coded apps live. RLS is technically "enabled," a dashboard toggle is green, and the founder assumes the job is done.
What is Two Ways Supabase Row Level Security Policies Fail Silently?
These are the two patterns that appear most often across thousands of scans — and both look fine from the outside.
What should you know about USING(true) exposes every row to every user?
An AI tool writes a policy with USING (true) to make errors stop. USING(true) means "this row is visible if true is true" — always true. So every row goes to every user. RLS is on, a policy exists, the dashboard is green, and your data is fully public. Fix: replace USING(true) with USING (auth.uid() = user_id).
What should you know about RLS enabled, no policies written?
You flipped RLS on. You never wrote a policy. Postgres now denies every request. Sometimes that means a clean deny-all which breaks features. Sometimes your AI-generated frontend swallows the empty result silently. The moment someone adds a permissive policy to "fix" the breakage, the door swings wide open.
What should you know about service_role key bypasses RLS entirely?
The service_role key ignores all RLS policies by design. If it is in your client bundle — even behind an env var that gets bundled into the frontend — your entire RLS setup is bypassed. Get it out of client code immediately.
What is Two Ways to Test Your Supabase Row Level Security Policies?
You do not need to guess. Our free scan verifies three things: RLS enabled status, policy completeness, and policy scope. It also flags the adjacent gaps that ride alongside broken RLS policies:
service_rolekey exposure in client code (bypasses RLS entirely)- Edge Function auth gaps
- Storage bucket permissions that leak files
Prefer to do it by hand? Run three diagnostic SQL queries in your Supabase SQL editor: check which tables have RLS disabled, list all tables with no policies, and scan policies for USING (true). They surface misconfigurations in seconds. Our Supabase Security Audit page documents all three queries.
What is Per-Platform: Where AI Builders Leave RLS Gaps?
Different AI builders fail in different ways. Here is what appears most often per platform:
| Builder | Most Common Supabase RLS Gap |
|---|---|
| Lovable | RLS enabled with no policies, anon key relied on without protection. See our Lovable Security Audit. |
| Bolt.new | RLS disabled entirely and secrets exposed in client bundles. See our Bolt Security Audit. |
| Cursor / Replit | Missing auth middleware on API routes plus USING(true) shortcuts. See Cursor and Replit audit pages. |
| Claude Code / Windsurf | More consistent auth patterns but policy scope gaps — reads protected, deletes sometimes not. See our Windsurf audit. |
For the broader picture, our guide to exposed secrets in AI bundles covers the full set of gaps AI tools leave open.
What should you know about Supabase RLS, GDPR Compliance, and EU AI Act Compliance?
Broken Supabase row level security policies are not only a security problem. They are a regulatory one.
When your users table is publicly readable, that is a personal data breach under GDPR compliance rules. The moment your app makes automated decisions, EU AI Act compliance enters the picture too. EU AI Act enforcement begins August 2, 2026. Fines reach up to €15M. Any one of these can kill a company.
Our Compliance Wing runs 60 automated compliance checks across GDPR, EU AI Act, SOC 2 foundations, and ISO 27001 foundations. That is the Compliance Score — a $799 one-time check with policy templates. Most AI-built apps ship with security gaps AND compliance gaps. We close both.
How to Fix Your Supabase Row Level Security Policies: 5 Steps?
- Enable RLS on every table that holds user data. No exceptions. Check all tables in your Supabase dashboard under Authentication → Policies.
- Write a real policy for each table. Use ownership checks like
auth.uid() = user_id. NeverUSING(true). Separate SELECT, INSERT, UPDATE, and DELETE policies. - Separate read and write policies. A user reading their own rows is not the same permission as inserting or deleting. Write both explicitly.
- Get the service_role key out of client code. It bypasses RLS completely. It belongs only in server-side code — Edge Functions, backend APIs — never in your frontend bundle.
- Re-test after every change. Run the free scan to confirm nothing reopened. Policies interact — fixing one table can expose another.
What should you know about Run the Free Scan First?
See your Supabase RLS status, secrets exposure, and auth gaps — instantly. No code access. No install. Then decide if you need the full audit.
Free Scan — $0 → $499 Launch Readiness Audit · $799 Compliance Score · launchreadycode.comFrequently Asked Questions
What are Supabase row level security policies in simple terms?
They are Postgres rules that decide which rows each user is allowed to see or change. Without Supabase row level security policies, the Supabase API hands every row to anyone holding your public anon key.
Is row level security enabled by default in Supabase?
No. RLS is off by default on many tables, and even when you enable it, you still have to write policies. Enabling RLS with no policies either denies everyone or fails silently — which is why so many vibe-coded apps think they are protected when they are not.
Why is USING(true) dangerous in a Supabase RLS policy?
Because USING(true) evaluates as always true, so the policy exposes every row to every user. It is the most common app security audit finding we see in 2026. The fix is replacing it with an ownership check like auth.uid() = user_id.
How do I test my Supabase row level security policies for free?
Use the free scan at launchreadycode.com or run three diagnostic SQL queries in your Supabase SQL editor. Both confirm RLS status, policy completeness, and policy scope in under 60 seconds with no code access required.
Do broken RLS policies affect GDPR and EU AI Act compliance?
Yes. A publicly readable user table is a personal data breach under GDPR compliance, and apps making automated decisions also fall under EU AI Act compliance — where fines reach up to €15M. Our Compliance Score runs 60 checks across both.
Is a paid SaaS security audit worth it in 2026 for a vibe-coded app?
If your app stores user data and you built it with an AI tool, yes. The free scan shows your gaps for nothing, and the $499 Launch Readiness Audit gives you copy-paste fixes for every finding — while the $799 Compliance Score covers GDPR and EU AI Act.
What is the fastest way to secure a Lovable or Bolt Supabase app?
Start with the free scan, enable RLS on every user table, replace any USING(true) policies with real ownership checks, and get the service_role key out of client code. Our Lovable and Bolt audit pages cover the platform-specific gaps in detail.
Research sources
- OWASP Foundation — OWASP Top 10 Web Application Security Risks (2021), the industry-standard vulnerability taxonomy referenced for all security categories in this article
- MITRE Corporation — CWE Top 25 Most Dangerous Software Weaknesses (2024), the weakness classification used to rank and prioritise code-level findings
- NIST National Vulnerability Database — NVD CVE severity ratings; all CVSS scores cited here are drawn from published NVD records
- Jai Mittal, Founder & CTO, Launch Ready Code — Proprietary data from 700+ AI-built app security audits, 2025–2026. Average Launch Readiness Score: 44/100. Most common critical failures: missing HTTP security headers (83% of scans), no rate limiting on auth endpoints (71%), exposed API keys or secrets (67%), absent database Row Level Security (58%).