Tenant Isolation
VaultAP is a multi-tenant system, meaning multiple organizations share the same infrastructure. Tenant isolation ensures that one organization's data is never visible to, or accessible by, another organization — under any circumstances.
VaultAP enforces isolation at three independent layers. Even if one layer were to fail, the remaining two would prevent data leakage.
Layer 1: Application-Level Filtering
Every database query in VaultAP includes an org_id filter. This is not optional or developer-dependent — it is enforced by a middleware layer that automatically injects the authenticated user's organization ID into every query before it reaches the database.
The org_id filter is applied at the ORM level. There is no code path that can query data without an organization scope. This is verified through automated tests that reject any unscoped query.
Key properties:
- Every table that stores customer data includes an
org_idcolumn. - The middleware extracts
org_idfrom the authenticated session — it cannot be overridden by request parameters. - API endpoints that accept an organization identifier validate it against the session before proceeding.
Layer 2: Row-Level Security
As a second layer of defense, VaultAP uses row-level security (RLS) policies in the database itself. Even if the application layer were compromised or bypassed, the database would reject queries that attempt to access rows belonging to a different organization.
RLS policies are configured so that:
- Each database session is tagged with the current
org_id. - SELECT, INSERT, UPDATE, and DELETE operations are restricted to rows matching the session's
org_id. - Direct database access (e.g., for debugging or maintenance) is performed through strictly controlled, audited connections that are also bound by RLS.
RLS policies cannot be disabled by application code. They are enforced by the database engine regardless of how the connection is established.
Layer 3: Per-Tenant Encryption Keys
Each organization's data is encrypted with a unique encryption key. Even if raw database storage were somehow accessed, data from one organization cannot be decrypted using another organization's key.
- Keys are generated when an organization is created and stored in a dedicated key management service.
- The encryption service resolves the correct key based on the
org_idof the request. - Key rotation is performed per-tenant, so rotating one organization's key does not affect others.
Data Never Crosses Boundaries
These three layers work together to guarantee that data never crosses tenant boundaries:
| Scenario | Protection |
|---|---|
Application bug omits org_id filter | RLS blocks the query at the database level |
Attacker manipulates API request with a different org_id | Middleware overrides with the session's org_id; RLS provides backup |
| Raw database storage is accessed | Per-tenant encryption keys prevent decryption of other tenants' data |
| Database administrator queries production | RLS policies apply to all sessions, including admin connections |
Tenant isolation is continuously verified by automated integration tests that attempt cross-tenant data access and assert failure. These tests run as part of every deployment.