multi-tenant-starter template
tenants.yaml with acme-prod (US residency, enterprise quotas) + beta-tenant (EU residency, trial quotas). Demonstrates per-tenant bus strategy, per-tenant extensions.allow/deny, scoped Vault secrets, and a smoke-test block in the README that walks the user through declaragent tenants list / show + declaragent audit verify.
Scaffold
declaragent init --template multi-tenant-starter --multi-tenant \
--tenant-id acme-prod
Canonical starter: templates/multi-tenant-starter/.
Configure
- Provision Vault paths
secret/data/acme-prod/*andsecret/data/beta-tenant/*. - Set
VAULT_ADDR+ a short-lived token in.env. - Each tenant's
agent.yamlreferences secrets via${secret:tenant:...}— the resolver scopes to the current tenant context at runtime.
Smoke-test
declaragent daemon &
declaragent tenants list
declaragent tenants show acme-prod
declaragent tenants diff # shows pending config changes
declaragent audit verify --tenant acme-prod --json
declaragent secrets list --provider vault --json
Cross-tenant boundary-violation test:
declaragent audit query --tenant beta-tenant --kind tenant_boundary_denied
Should emit zero rows on a healthy deployment.
Key points
- Per-tenant bus strategy. Each tenant has its own in-memory bus; no message can cross the boundary without a
tenant_boundary_deniedaudit record. - Scoped extensions. The
acme-prodtenant hasextensions.allow: [slack, kafka];beta-tenanthasextensions.deny: [whatsapp]. - Audit.
declaragent audit verifywalks the Merkle-chained audit log per tenant — a tamper drops a signed-row check failure.
[placeholder — landing 2026-Q2] Cross-tenant quota enforcement demo
(beta-tenant bursting into EQUOTA while acme-prod stays green).