Glossary

Row Level Security (RLS)

Row Level Security (RLS) is a Postgres feature that filters which rows each user can read or write, enforced by the database itself rather than your application code.

Row Level Security (RLS) is a Postgres feature that decides, per row, whether a given role is allowed to select, insert, update, or delete it. The rules live in the database as policies, so they apply no matter how the table is queried — from the API, a SQL client, or an Edge Function.

Supabase relies on RLS as its primary authorization layer. When RLS is enabled on a table, every request is checked against its policies using the caller's JWT claims (available through auth.uid() and auth.jwt()), so a user can only ever see their own rows.

-- Turn RLS on, then a user may only read their own rows
alter table public.notes enable row level security;

create policy "read own notes"
  on public.notes for select
  to authenticated
  using (auth.uid() = user_id);

Two things matter when you migrate:

  • Enabling RLS without a policy denies everything. A table with RLS on and no matching policy returns zero rows to normal roles — which looks like data loss but isn't.
  • The service_role key bypasses RLS. Server-side migration steps use it precisely so they can read and write every row; that key must never reach the browser. See the service_role key.

RLS policies are part of your schema, so a complete migration must recreate every policy on the destination — see schema replay.

Related terms