All docs
Docs · Deploy & operate
Tenants
Multi-tenant by default
A single team can ignore tenancy entirely; the moment you host a second team, a client, or a product, the walls are already there.
Multi-tenant documentation applies for those running their own self-hosted chassis.
End users who use a hosted Thanks, Computer cloud service benefit from multi-tenancy, but do not need to do anything to configure it.
How an event gets its tenant — and keeps it
Routing resolves the tenant before
any rule fires — by hostname, mail recipient, or listener — and stamps @tenant on the envelope. Then it’s pinned: immutable for the
life of the request. Rules and ops can’t overwrite it (the envelope
guard rejects the write), and usage accounting reads the pin, not the
envelope — a misbehaving rule can’t bill its work to someone else.
Events that match nothing land in the system tenant (_sys), where
boot rules may assign them to a real tenant exactly once. Tenant slugs
starting with _ are reserved for the chassis.
People: memberships, not global roles
An actor’s capabilities are per tenant — admin of acme, read-only
in beta, nothing anywhere else. The admin API enforces this at the
path: under /v1/tenants/acme/…, a signed caller’s capabilities are
re-resolved from their acme membership (no membership, no access),
and a browser session minted for one tenant won’t replay against
another. Invitations are tenant-scoped and can’t grant capabilities
the inviter doesn’t hold. Operators with super_admin see across
tenants — that’s the one global role.
Setting one up
txco auth tenant create acme # the tenant
txco auth invite --tenant acme --label "alice" # token for a teammate
txco auth tenant hostnames add acme.example.com --stack acme/web
txco auth tenant secrets set STRIPE_API_KEY --tenant acme
txco apply --tenant acme # deploy stacks into it --tenant defaults to default (or your profile’s default), so
single-tenant workflows never type it. txco auth tenants lists what
you can see; txco auth memberships lists where you belong.
Operating tenants
Suspension is a clean kill switch: txco admin tenant suspend acme --deny-status 402 --deny-reason payment_required makes the chassis
answer that tenant’s traffic with your chosen denial — while still
attributing the attempts to the tenant for the record. resume lifts
it. Deleting is a soft revoke: routing and cron stop, history and audit
rows remain.
Outbound-mail rate limits are tracked per node (a runaway-loop valve, not fleet-wide accounting), and hostname-ownership verification is permissive by default — set --require-hostname-verification in production so unverified bindings don’t route.
What lives inside a tenant
Everything, keyed at the database row:
| Resource | The boundary |
|---|---|
| Stacks & rules | A stack name is unique per tenant; tenant A’s rules never fire for tenant B’s events |
| Hostnames & domains | Hostname bindings, delegated DNS zones, and DKIM keys are tenant rows — one tenant’s claim 409s another’s |
| Secrets | Scoped (tenant, stack, name); materialization can’t cross the line |
| Traces | Tenant-attributed; the admin API only serves them under /v1/tenants/{slug}/… |
| Cron | Each tenant with a _cron stack gets its own tick envelope |
| Usage & fuel | Every request’s spend is attributed to its tenant — the quota/billing dimension |
| Outbound mail | Per-tenant rate limits, and the from-domain must be that tenant’s verified hostname |
| People | Actors hold per-tenant memberships with per-tenant capabilities |