Skip to content

ADR-029: Multi-Tenancy by Default

Decision

Every system assumes multi-tenancy from day one. The naming ladder <env>.<agency>.<org-unit>.<app> is the canonical prefix for all resources, tenant isolation is enforced in the data engine rather than application code, and tenant identity derives only from verified credentials.

Key rules

  • Naming ladder is <env>.<agency>.<org-unit>.<app> — environment leads. It applies to Kafka topics, Redis keys, k8s namespaces, Postgres schemas, Docker images, deployments, and every other named resource.
  • Collapsing a level in the ladder requires documented justification. Undocumented single-tenant naming is a defect.
  • Shared data stores use database-per-tenant, schema-per-tenant, or forced Row-Level Security (RLS) — never a bare WHERE tenant_id = ? query as the only guard.
  • Tenant identity comes from a verified JWT/OIDC claim or mTLS — never from a URL path, query parameter, or unsigned header.
  • APIs keep the tenant out of the resource path: /v1/billing/invoices, not /v1/tenant-123/billing/invoices.
  • Every PR that introduces a data store, topic, or API must state its isolation story in one sentence.

Why

Assuming multi-tenancy from the start makes the naming ladder, isolation boundary, and identity source structural rather than retrofitted, so single-tenant assumptions cannot leak into shared infrastructure. Enforcing isolation in the data engine (RLS or schema/database separation) keeps a single missed WHERE clause from becoming a cross-tenant data breach, and deriving tenant identity from verified claims prevents path- or header-based spoofing.

Applies when

You are designing, naming, or provisioning any data store, topic, queue, cache, cluster resource, image, deployment, or API endpoint that handles tenant data.

  • ADR-025 — auth JWT standard; the verified tenant_id claim is the source of tenant identity.
  • ADR-024 — engineering standards.
  • ADR-028 — platform foundations.
  • ADR-027 — default tech stack.