ADR-0001: Multi-Tenant Isolation
Status: Accepted
Date: 2025-12-29
Context
- Platform serves multiple tenants (organizations) - currently SAMA, future: VFS Global, Allied Shielding
- Every database table with user data must include tenant_id for isolation
- Risk of cross-tenant data leakage if queries omit tenant filter
Decision
-
Tenant resolution via
resolveTenantSecure()atserver/routes.ts:107-159 -
Security rules at lines 90-98:
- Session tenant is primary source
- Query param override requires
SUPER_ADMIN_MODE=trueANDSUPER_ADMINrole - No silent fallbacks - missing tenant = 400/403
-
requireTenant()helper atserver/routes.ts:161enforces tenant presence -
Every query must include tenant_id filter (verified in vector store:
server/lib/vectorStore.ts:75) -
Default tenant "sama" seeded at
server/storage.ts:423-431
Alternatives Considered
- Row-level security in PostgreSQL - Rejected: complexity, harder to debug
- Separate databases per tenant - Rejected: operational overhead, cost
Consequences
- All new tables must include
tenantIdcolumn with index - All queries must filter by
tenantId - Cross-tenant access blocked at API layer with 403