Multi-Tenancy
Tenant isolation strategy and implementation
Multi-Tenancy
Goal
Build a multi-tenant system where each company's data is completely isolated from others, while allowing users to belong to multiple tenants.
Isolation Strategy
- Shared database with row-level isolation (not database-per-tenant)
- tenantId column on every tenant-specific table
- Every query filters by tenantId - no exceptions
- Zero cross-tenant data access - enforced at repository level
Three-Level Hierarchy
| Level | Who | Access |
|---|---|---|
| Platform Admin | System operators | All tenants (super admin) |
| Tenant Admin | Company admins | Own tenant only |
| Tenant User | Employees | Own tenant, based on role permissions |
User-Tenant Relationship
- Users exist globally (single account across platform)
- Users connect to tenants via
UserTenantjoin table - Users can belong to multiple tenants (e.g., consultant working for multiple companies)
- Users switch between tenants via tenant selector
Security Rules
- Every table (except Tenant) has
tenantIdcolumnNote: User.tenantId is optional because Auth.js PrismaAdapter creates the user record before the
createUserevent fires to assign tenant context. See Phase 01 for details. - Every repository method takes
tenantIdas first parameter - Every query includes
WHERE tenantId = ? - AuthGuard verifies user has access to requested tenant
- Session includes current
tenantIdandsystemRolecontext (enriched via Auth.js session callback) - Audit logging tracks all tenant-scoped operations
Key Implementation Points
- Tenant context extracted from JWT in AuthGuard
- Repository methods enforce tenant filtering
- Platform admins can impersonate tenants for support
- Tenant deletion cascades all related data
Implementation details to be defined during development