RLS is enforced in addition to application-level tenant filtering. Both layers
work together to ensure data isolation.
How It Works
Session Variable
Each database request sets a session variable with the verified tenant ID:Policy Definition
RLS policies check that rows match the session tenant:Tenant Identity Source
The tenant ID is derived only from verified authentication context:- JWT claims (after signature verification)
- API key lookup (after hash validation)
- Never from client-provided headers like
X-Tenant-ID
Covered Tables
RLS is enabled on all tenant-scoped tables:| Table | Tenant Column | Policy |
|---|---|---|
issuers | tenant_id | ✓ Enabled |
issuer_keys | tenant_id | ✓ Enabled |
policies | tenant_id | ✓ Enabled |
tenant_api_keys | tenant_id | ✓ Enabled |
attestations | tenant_id | ✓ Enabled |
Fail-Closed Behavior
Ifapp.tenant_id is not set in the session:
- SELECT: Returns zero rows (not an error)
- INSERT: Fails with RLS policy violation
- UPDATE/DELETE: Affects zero rows
Verification
Run the RLS isolation test suite:Implementation Notes
Connection Pooling
When using connection pools, ensure thatSET LOCAL is used within a transaction.

