DenialOS
Docs / Tenant and client isolation
IMPLEMENTED — RUNTIME-TESTED; PRODUCTION ROLE CUTOVER PENDING
⏱️ 3 min read · 448 words

Tenant and client isolation

DenialOS applies isolation at two independent layers, so a mistake in one is not the only thing standing between two customers.

Application layer

Customer-bound reads and writes are scoped by organization and client in application code:

The design goal is:

organization A + client A
          ≠
organization B + client B

and likewise:

connection A
cannot substitute for
connection B

Database layer

Tenant tables also carry row-level security policies keyed on the record's organization:

The boundary fails closed

The application refuses to serve from a database connection that can bypass these policies. The API boot path, the worker boot path, and the serverless entrypoint each check the connected database role; the serverless entrypoint answers 503 environment_not_ready rather than serving requests with isolation disabled. A preflight command (npm run verify:runtime-role) performs the same check before a deployment is promoted.

What is verified

The isolation suite runs against a real PostgreSQL instance as a role that row-level security can actually constrain — not a superuser, and not a role with BYPASSRLS:

Boundary

Row-level security is defense in depth on top of scoped authorization code, not a replacement for it. The database policies enforce the organization boundary; isolation between separate clients inside one organization is enforced by application authorization. This documentation does not claim customer-specific validation for any particular deployment, and production enablement requires the deployment to run under a role that cannot bypass the policies — the runtime gate refuses traffic until that is true.