Your tenant policies exist. Your tests pass. Production still bypasses them.
The usual cause: migrations, tests, and runtime all use the role that owns the tables.
PostgreSQL table owners normally bypass RLS unless FORCE ROW LEVEL SECURITY applies.
A safer acceptance test uses the exact serving role and proves:
- it owns no tenant tables
- it has no BYPASSRLS or superuser attribute
- tenant context comes from authenticated state
- context is transaction-scoped with SET LOCAL
- cross-tenant rows, joins, and aggregates fail closed
- rollback and pool reuse cannot leak the previous tenant
Run the same matrix as the serving role and the migration owner. The difference should be visible and deliberate.
Catalog flags are configuration evidence. A negative query under the production identity is enforcement evidence.
Full guide: PostgreSQL RLS serving-role acceptance tests for AI agents
Top comments (0)