All checks

Supabase RLS Disabled: How to Check and Fix It (2026)

GuideQuick + Deep· 3 min read· Last updated

SHORT ANSWER

If RLS is off on a Supabase table, anyone with your public `anon` key can read or change that table's data, and that key is in your frontend. Turn RLS on for every table in public and add policies that say who can read and write each row.

If Row Level Security (RLS) is off on a Supabase table, anyone who has your project's public anon key can read, change or delete that table's data. That key ships inside your frontend, so assume everyone has it.

This guide shows how to check whether you're affected and how to fix it.

Why it's dangerous

Supabase exposes your public schema through an automatic REST API. RLS is the rule layer that decides which rows each user may see or change. With RLS off, there are no rules, so the API answers anyone who asks.

A typical result: a stranger opens your site, copies the anon key from the browser's network tab, and downloads your whole users table.

How to check

1. Dashboard. Open Table Editor. Tables without RLS show an "RLS disabled" label. The Security Advisor (under Advisors) also lists them.

2. SQL. Run this in the SQL Editor to list every table and its RLS status:

SQL
select schemaname, tablename, rowsecurityfrom pg_tableswhere schemaname = 'public';

Any row with rowsecurity = false is open.

3. Test it like an attacker. Request a table using only your public key:

Shell
curl "https://YOUR-PROJECT.supabase.co/rest/v1/YOUR_TABLE?select=*" \  -H "apikey: YOUR_ANON_KEY" \  -H "Authorization: Bearer YOUR_ANON_KEY"

If you get rows back and the table shouldn't be public, you have a problem.

How to fix it

Step 1: turn RLS on.

SQL
alter table public.todos enable row level security;

With RLS on and no policies, nobody can read or write through the API. That's safe but locked, so you now add policies.

Step 2: add a policy for what users should be allowed to do. For example, let signed-in users read and edit only their own rows:

SQL
create policy "Users read own rows"on public.todos for selectto authenticatedusing ((select auth.uid()) = user_id); create policy "Users insert own rows"on public.todos for insertto authenticatedwith check ((select auth.uid()) = user_id); create policy "Users update own rows"on public.todos for updateto authenticatedusing ((select auth.uid()) = user_id);

Adjust the column name (user_id) to match your table.

Step 3: repeat for every table in public, then run the check query again.

Mistakes people make after enabling RLS

  • Policies that allow everything. using (true) on a table with private data is the same as having no RLS.
  • Using the service_role key in the frontend. It bypasses RLS completely. It belongs only on a server, never in browser code.
  • Forgetting views. Views can bypass RLS depending on how they were created. On Postgres 15+, create them with security_invoker = true.
  • Forgetting Storage. Buckets have their own policies. Check them too.
  • Tables created later. Tables made with raw SQL don't get RLS automatically. Check again after every migration.

Quick checklist

  • RLS enabled on every table in public
  • Every table has policies that match who should access it
  • No using (true) on private data
  • service_role key is not in any frontend code or repo
  • Storage bucket policies reviewed
  • Re-checked after the latest migration

Check your whole repo automatically

Manual checks are easy to forget as the app grows. SetRepo scans your repo for disabled RLS, exposed keys, secrets in git history and other common security mistakes, and tells you how to fix each one.

Built with Lovable or Base44? Those apps often run on Supabase. See what to check in Lovable apps and Base44 apps.

Run a free scan →

FAQ

Is the Supabase anon key supposed to be public?

Yes. It's designed to be in your frontend. That's exactly why RLS must be on: the anon key is only safe when RLS limits what it can do.

What happens if I enable RLS without adding policies?

All access through the API is denied. Add policies for the access your app needs.

Does RLS apply to the service_role key?

No. The service_role key bypasses RLS, so keep it server-side only.

How often should I check?

After every migration that adds a table, and before every launch.

Scan your Supabase app, free.

Start free scan