Security & compliance
How one project's data stays isolated from every other
Isolation here is two mechanisms, not one. Every query filters on the tenant's own id at the application layer, and Postgres row-level security sits underneath as a second refusal — deliberately not as a replacement for the first.
Open Trust centre in the consoleTwo layers, on purpose
Isolation is two mechanisms stacked deliberately, and the second is not a licence to skip the first.
- Application-layer filteringEvery query against tenant-owned data filters on the project or organization id explicitly. This is the layer the application is responsible for and the one code review checks.
- Row-level securityPostgres row-level security refuses rows outside the request's tenant context independently of the query. It is defence in depth — a second refusal if the first is ever forgotten.
Which tables the pilot covers
RLS is piloted on the tables that carry a tenant id directly. Tables that are only tenant-scoped through a parent relationship are explicitly outside that pilot and rely on the application-layer filter — a disclosed scope, not an oversight.
What a cross-tenant read returns
Asking for another tenant's record does not return a permission error that confirms the record exists. It comes back as though the row is not there — which is the right answer, because a 403 on a resource you cannot see still tells you it exists.
How isolation is tested
Cross-tenant leakage is treated as a release blocker, so it is tested rather than reasoned about: the same operation is exercised as two different tenants against a real database, and the second must come back empty — never a server error, and never a silent success.
- Tested at both layers, because they fail independently: the application filter and the database policy.
- Never against a mocked database — a mock cannot reproduce the behaviour the policy is there to provide.
- Including a control that proves the row really does exist, so an empty result is isolation rather than a typo in the fixture.
Put it into practice
Run a fleet with these guardrails on from day one.
Hard cost caps, one audited gateway in front of every tool call, and versioned rule files — the defaults, not an enterprise add-on.