Skip to content

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

  1. All tenant-scoped tables have tenant_id UUID column
  2. All queries set app.current_tenant in connection context
  3. RLS policies automatically filter data by tenant
  4. 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

  1. Separate databases per tenant: Rejected due to operational complexity
  2. Separate schemas per tenant: Rejected, too complex for MVP
  3. Soft filtering in app code: Rejected, security risk if developer forgets