Guide

Supabase RLS not enabled: what it means

When Supabase row-level security is not enabled, every row in that table is readable, and often writable, by anyone with your public key, which ships in every app. It means your database is effectively public, and the fix is to enable RLS and add a policy that scopes each user to their own rows.

What RLS off actually exposes

The publishable key is in your app's JavaScript, so anyone can copy it. Row-level security is what decides whether that key can do anything useful. With it off, the key can list your users, read private records, and depending on your policies, insert or delete rows. This is not a theoretical risk. It is the first thing anyone probing a Supabase app tries.

It is the first thing anyone probing a Supabase app tries.

The fix, step by step

  • Enable row-level security on the table in the Supabase dashboard.
  • Add a select policy that matches rows to the signed-in user, for example auth.uid() = user_id.
  • Do inserts, updates, and deletes that need trust from your server using the secret key, not from the browser.
  • Repeat for every table that holds anything private.

Then confirm it worked by scanning the live app, so you are testing the deployed behaviour and not just the dashboard setting.

Frequently asked

What happens if I don't enable RLS in Supabase?

Your tables are readable, and often writable, by anyone with the public key, which is in your app's frontend. Enabling RLS is what limits access to the rows each user is allowed to see.

Is enabling RLS enough?

Enabling RLS turns on the gate, but you also need a policy that says who may see what. RLS on with no policy blocks everything; RLS on with a correct policy scopes each user to their own rows. Both steps are needed.

Related guides

Guide by Plaintext, the security scanner for AI-built apps.