Overview
Row Level Security (RLS) in Postgres via Supabase is the most important control for multi-tenant apps. A single missing policy can expose every tenant's data.
Policy pattern
enable + policy
alter table invoices enable row level security;
create policy "tenant isolation"
on invoices
for all
using (tenant_id = current_setting('app.tenant_id')::uuid)
with check (tenant_id = current_setting('app.tenant_id')::uuid);Set
app.tenant_id from your verified session on every connection. Never trust a client-supplied tenant id.Multi-tenant
Use a shared schema with a tenant_id column and RLS, or separate schemas per tenant for stronger isolation. Start shared; split only when compliance demands it.
Gotchas
- Joins bypass intuition — policy applies per table.
- Service roles skip RLS; never use them from the client.
- Test policies with two tenants in your test suite.
FAQ
See the FAQ section above.