← session · LOG ENTRY ·
Row-level security: making tenant isolation the database's problem
Multi-tenant systems fail the same way: a missing WHERE tenant_id clause, written by a tired engineer, discovered by the wrong customer. Application-level tenancy is a promise every query must keep individually. Postgres row-level security turns it into a rule the database enforces globally, the query that forgets the clause returns nothing instead of everything.
The mechanics: policies on every tenant-owned table, keyed to a session variable the connection layer sets from the authenticated context. Application code stops carrying the isolation burden; it literally cannot read across tenants, including through joins, subqueries, and the clever paths nobody code-reviews. Defense in depth where the depth is free at query time.
The discipline is in the edges. Migrations must be RLS-aware (31 production migrations on one linear chain, custom CI lints enforcing idempotent DDL). Background jobs need explicit tenant context, a worker with superuser convenience is a hole in the fence. And tests must include the adversarial case: connect as tenant A, attempt tenant B's rows, assert emptiness. That test failing loudly in CI is worth more than any architecture diagram.
For agent systems this is non-negotiable. Agents generate queries and actions with a model in the loop; the blast radius of a confused agent must be bounded by something harder than a prompt. RLS means the worst case of an agent gone sideways is scoped to one tenant, which is the difference between an incident and an extinction event.
— end of log entry. back to session · handoff to human