One record per tenant. Almost everything hangs off it.
Data, settings, plan, limits, keys, region and bill are all scoped to it. So define the tenant before you draw a single box.
Isn’t the user the tenant?
Bad: Roles on the user
Priya, an admin at Bharat Traders, becomes an admin at Acme too.
Good: Roles on the membership
(user, tenant, role): one login, a different role in each tenant.
Which tenant is this request for? Ask the token.
The gateway verifies the signed token and reads its tenant claim. A tenant ID the client sends is stripped, never trusted.
Every request now takes its tenant from the token. Can data still leak?
The catch
Yes, through what it writes. Cache key invoice:1042 can exist in many tenants. Stamp the tenant ID on everything.
Fabrikam leaves. An attacker signs up as “fabrikam”.
Its leftover DNS record sends Fabrikam’s traffic to the newcomer. Anything keyed by the name resolves there too. Key by an opaque, immutable ID.
Solo users only. Model a tenant anyway?
Bad: Key every row by user
Family plans later mean re-keying every shared table, live.
Good: A tenant of one
One table and one join today; family plans become a feature.
The control plane owns the lifecycle
- Provision with idempotent, resumable steps
- Payment fails? Suspend; keep data, pause jobs
- Offboard: export window, then delete everywhere
- Free the subdomain only after a cooling-off
Remember
A tenant is the customer boundary, not a user. Take it from the signed token; stamp its immutable ID on everything.