Row-Level Security (RLS)
Row-level security is a database feature — built into Postgres — that restricts which rows a query can see or modify based on a policy, so tenant isolation is enforced by the database itself rather than only by application code.
The conventional way to isolate tenants in a multi-tenant system is application-level: every query includes a WHERE tenant_id = ... clause, written and reviewed by hand, everywhere. That works until one query, in one code path, forgets the clause — and the database, having no concept of "tenant," happily returns rows from every tenant to whoever asked.
Row-level security moves that check into the database. A policy attached to a table says, in effect, "no query against this table may see rows outside the caller's tenant" — and Postgres enforces it automatically, regardless of what the application's query looked like. A bug in application code can no longer leak cross-tenant data, because the database refuses to return rows the policy excludes.
RLS doesn't replace application-level access checks — it's a second, independent layer beneath them. The value is specifically in what it catches: the class of bug where isolation logic exists but was missed in one place. Pushing that guarantee into the database removes the single point of failure that "remembering to add the WHERE clause everywhere" represents.
Row-Level Security (RLS), in the product
Aanty scopes every tenant-owned table with a Postgres RLS policy, and pairs it with FORCE row-level security so even the table owner can't bypass it (see FORCE Row-Level Security). Cross-tenant isolation is additionally covered by tests in CI — a cross-tenant read is a failing test, not a postmortem.
Related terms and pages
See Row-Level Security (RLS) in a real workspace
Bring a channel from wherever your team works today. In fifteen minutes we'll show what row-level security (rls) looks like on a real conversation, not a slide.