Guide

How to turn on Supabase row-level security, in plain English

Row-level security, or RLS, is the rule book your Supabase database checks before it returns a row. With it off, anyone holding your app's public key can read the whole table. With it on and a good policy, each user sees only their own data.

Updated · 7 min read

Why it matters

Supabase apps talk to the database straight from the browser, using a public key that is visible in your page source. That is by design. The thing that makes it safe is row-level security. Turn it off and the public key becomes a key to the whole table.

Step 1: turn it on for the table

In the Supabase dashboard, open the table and enable RLS, or run this in the SQL editor. Replace bookings with your table name.

SQL
alter table public.bookings enable row level security;

Step 2: add a policy

With RLS on and no policy, nobody can read the table through the API, which usually breaks a screen. Add a policy that lets each signed-in user read only the rows that belong to them. This assumes the table has a user_id column that stores the owner's id.

SQL
create policy "Owners can read their bookings"
on public.bookings
for select
to authenticated
using ((select auth.uid()) = user_id);

Step 3: cover inserts, updates and deletes

A select policy only covers reading. Add one policy per action you need, each limited to the owner. For inserts, the check goes in with check rather than using.

SQL
create policy "Owners can add bookings"
on public.bookings
for insert
to authenticated
with check ((select auth.uid()) = user_id);

Mistakes to avoid

  • using (true): this lets everyone read the table and is the same as RLS off.
  • Policies for the anon role on tables with personal data.
  • Turning RLS off to fix a permissions error. Fix the policy instead.
  • Views that query a protected table. Create them with security_invoker = true so they respect the caller's policies.

Check that it worked

Sign out of your app and try to load the data, or follow our guide on testing whether your tables are public with your own anon key. If a row comes back without signing in, the policy is still too open.

Common questions

Does turning on RLS break my app?

It can, until you add policies. Turn it on, add the policies your screens need, then test each screen while signed in as a normal user.

Does the service role key respect RLS?

No. The service role or secret key bypasses every policy. That is why it must never be in your frontend.

The checks behind this guide

Check your whole app in one go.

The Full Scan runs seven read-only checks and writes a fix prompt for every finding.

More guides