Tenant isolation

How the boundary between organisations is enforced — and how it is proven.

Tenant isolation is the load-bearing security property. Everything else is defence in depth around it.

Three reinforcing mechanisms

Fail closed

The helper that resolves a tenant raises rather than returning a default. A blank tenant fails before any data is touched, so the worst case is an error, never an unscoped query.

Derived, never supplied

The tenant is always resolved server-side from the authenticated credential. It is never read from a request body, query string or header. There is no parameter a caller could set to claim a different tenant — the attack has no input to use.

Enforced by construction

Queries are built by canonical helpers that always emit the scope filter. Skipping the scope means not using the helper, which static analysis catches.

Per-store enforcement

StoreMechanism
Document databaseEvery read carries the tenant, plus the resource id for composite reads
Vector storeMandatory tenant payload filter, added before the query runs
GraphTenant clause on every match, with parameterised queries throughout
CacheTenant-prefixed keys
Object storePer-tenant bucket with a memory-scoped path prefix

404, not 403

A read that crosses a tenant boundary returns 404, not 403.

403 would confirm the resource exists. Over enough requests that is an enumeration oracle — an attacker learns your customer list one id at a time without ever reading a record. Returning 404 denies the existence signal along with the data.

Proof, not policy

The isolation rule is verified on every pull request: the test suite walks the abstract syntax tree of each endpoint and asserts that tenant scope is present, and an architecture linter enforces the layering rules in strict mode. A regression blocks the merge and the deployment pipeline.

This matters for a specific reason. "How do you know isolation is still intact after eighteen months of feature work?" is a question most vendors answer with a policy document. Here the answer is a failing build.

Logical against physical

Be precise about which you are getting:

DeploymentIsolation
SharedLogical — one set of engines, mandatory filters on every query
DedicatedPhysical — own engines in their own namespace, network-policed
Own infrastructurePhysical, and outside Chordian's estate entirely

Logical isolation is enforced and verified, but it is enforced in software. If your threat model requires that a vendor bug cannot expose your data, the honest answer is a dedicated or own-infrastructure memory — not a stronger adjective applied to the shared tier.

Was this page helpful?
Report an issue

On this page