ADR-001: Multi-Tenancy Implementation¶
Status¶
Accepted
Context¶
The SaaS platform needs to serve multiple tenants (companies/couriers) from a single deployment. Each tenant must have isolated data and cannot see other tenants' information.
Decision¶
Row-Level Security (RLS) with a tenant_id column in all tenant-scoped tables.
-- Enable RLS on all tenant tables
ENABLE ROW LEVEL SECURITY;
FORCE ROW LEVEL SECURITY;
-- Policy to enforce tenant isolation
CREATE POLICY tenant_isolation ON shipments
USING (tenant_id = current_setting('app.current_tenant')::uuid);
Implementation¶
- All tenant-scoped tables have
tenant_idUUID column - All queries set
app.current_tenantin connection context - RLS policies automatically filter data by tenant
- No manual tenant filtering needed in application code
Consequences¶
Positive¶
- Strong data isolation guaranteed by database
- No risk of tenant A seeing tenant B's data
- Simplified application code (no manual filtering)
Negative¶
- Added complexity in connection management
- Must set tenant context on every database connection
- Slight performance overhead per query
Alternatives Considered¶
- Separate databases per tenant: Rejected due to operational complexity
- Separate schemas per tenant: Rejected, too complex for MVP
- Soft filtering in app code: Rejected, security risk if developer forgets