← All decisions

Tenant config: repo bootstraps, DB authoritative at runtime

accepted

0004 — Tenant config: repo bootstraps, DB authoritative at runtime

Context

Each tenant has settings: org name, domains, theme name, enabled modules, integration credentials, content type seed, branding assets. Two failure modes to avoid:

Decision

A two-layer config model:

  1. tenants/<slug>/tenant.config.ts — bootstrap source of truth. Validated via Zod schema in packages/tenant-config. Used to create the org row at onboarding time. Lives in git (or a private per-tenant repo).
  2. organizations row in the DB — runtime source of truth. Mutable from the admin UI. Drives the live system once the tenant exists.

A nightly job compares the two and surfaces drift. Drift isn’t an error — admins are supposed to change runtime values from the UI. Drift is informational: “this tenant’s runtime diverges from its bootstrap config; if you re-bootstrap from tenant.config.ts, here’s what would change.”

Consequences

Easier:

Harder:

Alternatives considered