Tenant isolation
Guaranteeing one customer's data can never appear in another customer's account, no matter which query, cache, or background job touches it.
See it
What it is
One app, many customers, and a hard promise: nothing belonging to one tenant may ever surface inside another. Three common shapes, in increasing cost and increasing separation: a shared table with a 'tenant_id' column on every row, a schema per tenant, or a database per tenant. Most SaaS starts with the shared table because it is cheap to operate, and then enforces the boundary at the database with Postgres row-level security so a forgotten WHERE clause fails closed instead of returning everything.
Make the safe path the default one. Set the current tenant per request or per transaction, deny by default in policy, put 'tenant_id' first in your composite indexes, and add a test that logs in as tenant B and tries to fetch every one of tenant A's object IDs, expecting 404 on all of them.
Gotcha: the leak almost never comes from the main query, which everyone reviews. It comes from the places nobody classifies as data access: a cached HTML fragment keyed without the tenant, a shared search index, a background job that inherited a stale tenant context, a CSV export, an internal admin endpoint, a webhook replay, or an autoincrement ID someone can guess in the URL.
Ask AI for it
Enforce tenant isolation in this application. Add a non-null 'tenant_id' to every tenant-scoped table with a foreign key, put it first in every composite index and unique constraint, and enable Postgres row-level security on those tables with a deny-by-default policy that compares 'tenant_id' to a per-transaction setting like 'app.current_tenant'. Wire middleware that sets that value from the authenticated session at the start of every request and clears it after, and make background jobs carry the tenant explicitly rather than inherit it. Replace sequential IDs in URLs with UUIDs, key every cache entry by tenant, and add an integration test that authenticates as tenant B and asserts 404 for every tenant A resource.