What Is Row-Level Security (RLS)?
Row-Level Security is a Postgres feature that restricts which database rows a user can read or write — enforced at the database level, not in application code.
RLS attaches access control policies directly to Postgres tables. Even if your API has a bug that omits a WHERE clause, the database automatically filters rows based on the active policy — no data leaks.
Why database-level security matters:
Application-level guards are fragile. A single missing where user_id = $1 in one query exposes every row in that table to every user. RLS makes that impossible — the database enforces the rule regardless of what the application sends.
Enabling RLS in Supabase:
ALTER TABLE bookings ENABLE ROW LEVEL SECURITY;
CREATE POLICY "tenant_isolation" ON bookings
FOR ALL
USING (tenant_id = current_setting('app.tenant_id')::uuid);
Multi-tenant SaaS pattern:
Every table gets a tenant_id column. RLS policies enforce that queries only return rows matching the authenticated tenant. One application, completely isolated data per customer.
RLS performance:
RLS adds negligible overhead when the filtering column is indexed. Always index tenant_id and user_id columns. Without the index, full table scans happen on every query — a silent performance killer at scale.