Skip to main content

Tenant overrides

File: config/agents/tenants/*.yaml · Schema: schemas/tenant.schema.json

One customer's differences, deep-merged over the shared definitions: thresholds, connectors, auto-approval.

Fields​

FieldTypeDescription
connectorsmapconnectors.<id> is deep-merged over that connector. Default: {}.
overridesmap of name → WorkflowOverrideoverrides.<workflow>.nodes.<node> is deep-merged over that node. Default: {}.
tenantstringRequired. The tenant's slug; must match tenants.slug.
workflowsTenantWorkflowsWhich workflows the tenant may run. Default: {"enabled":[]}.

Unknown fields are refused at boot.

Types​

Types referred to by the fields above, from the same schema.

TenantWorkflows​

FieldTypeDescription
enabledlist of stringWorkflows this tenant may run. Empty means every enabled workflow. Default: [].

Unknown fields are refused at boot.

WorkflowOverride​

FieldTypeDescription
nodesmapPatches by node id, deep-merged over that node. A patch naming a node the workflow does not have stops boot. Default: {}.

Unknown fields are refused at boot.

In this repository​

config/agents/tenants/acme.yaml

# Per-tenant overrides, merged over the base definitions for tenant `acme` only.
tenant: acme
workflows:
enabled: [invoice_v1]
overrides:
invoice_v1:
nodes:
approval:
with:
auto_approve: { enabled: true }
# A tenant can also swap a connector's adapter. A webhook needs a URL and a signing secret,
# and boot fails without them, so this stays commented out until acme has both:
# connectors:
# accounting:
# kind: webhook
# options: { url: "https://erp.acme.example/hooks" }
# credentials: { hmac_secret: <a get_env reference to ACME_ACCOUNTING_HMAC_SECRET> }
connectors: {}

Editor support​

The schemas are generated from the Rust definition structs (task schema_export), and a test fails when they drift. Point a YAML language server at the schema to get completion and validation while editing:

# yaml-language-server: $schema=../../../schemas/tenant.schema.json