The kadu.yaml
What belongs to the whole organization, rather than to a task, lives in an
optional kadu.yaml at the repository root: environments, webhooks and
the metadata of workspaces and activities. What belongs to a task
(schedule, endpoint, executor) stays in the task: block.
Rules that apply to all sections​
- Ownership. The sync creates and updates what is declared and only deletes what it created itself. What was created in the console and appears in the file is updated, never deleted.
- A missing section touches nothing. An empty list (
[]) removes only what the repository created. - The whole file is validated. Broken YAML, a field with the wrong type, an
unknown key (
colour:,bearer_token:), a webhook event outside the list or a repeated item make the sync apply nothing from the file, with a warning. An unknown top-level section is only a warning, and the rest applies.
All-or-nothing is on purpose: applying the good half would delete the item with the typo.
Environments​
environments:
- label: Produção
color: "#16a34a" # #rrggbb; missing = gray (#6b7280) on creation
branch: main # missing = main on creation
secrets: # only the KEYS — a value never goes into the repository
- KOBANA_ACCESS_TOKEN
- key: FINTERA_TOKEN
notes: token da entidade 34684
- label: Sandbox
color: "#f59e0b"
| Situation | What the sync does |
|---|---|
| Declared environment that does not exist | creates it, marked as the repository's |
| Declared environment that already exists (same name) | updates color and branch, if declared. The one created in the console is adopted for updating, never marked as the repository's |
Key in secrets with no value in the environment | warning: the sync never creates a secret |
Key in secrets with notes | overwrites the secret's note |
| Repository's environment that left the list | deletes it, unless it still has a secret or schedule (it stays, with a warning) |
| Console's environment that left the list | does not touch it |
The name is the key: renaming an environment in the file creates another one. The schedules that point to it must change in the frontmatter in the same commit. To rename an environment that already has secrets, rename it in the console and then in the file.
Webhooks​
webhooks:
- label: Falhas para o PagerDuty # the key: matched by name
url: https://events.exemplo.com/kadu
events: [execution.failed, organization.cost_limit_reached]
workspace: finance # scope plugin; null = whole organization; missing = do not touch
auth: header # basic | bearer | header; missing = bearer on creation
header_key: X-Api-Key # the non-secret part (for basic: basic_user)
enabled: true # missing = do not touch (on creation: active)
emails: [ops@exemplo.com] # notified when the webhook is deactivated by failures
metadata: { dono: sre }
Accepted events: execution.created, execution.queued, execution.started,
execution.completed, execution.failed, execution.cancelled,
todo.created, todo.resolved, organization.cost_limit_reached,
organization.entitlement_required and the <resource>.db.created|updated|deleted
events of task, activity, workspace, execution and memory.
A credential never goes into the file. bearer_token, the basic password
or the header value in the YAML are unknown keys and invalidate the whole file.
| Situation | What the sync does |
|---|---|
| Declared webhook that does not exist | creates it, marked as the repository's, without a credential and with a signing secret that nobody has seen, and warns |
| Existing webhook (same name, any origin) | updates url, events, emails (order does not matter), scope, basic_user/header_key and metadata |
auth different from the stored one | does not switch (it would delete the credential) and warns; switch in the console |
enabled: true on a webhook deactivated by failures | reactivates it and resets the failure counter, on every sync, while declared |
URL rejected (private IP, http), nonexistent workspace, two webhooks with the same name | skips that webhook, with a warning, without deleting it |
| Repository's webhook outside the list | deletes it |
| Console's webhook outside the list | does not touch it |
After creating it, two steps remain outside the repository: register the
credential in Settings → Webhooks and generate the signing secret with
POST /v1/webhooks/{id}/rotate-secret, configuring the new value in the
receiver. Until then, the delivery goes out unauthenticated and with a
signature that the receiver cannot verify.
Workspaces and activities​
workspaces:
- plugin: finance # the plugin = the workspace
metadata: { centro_de_custo: "42" }
activities:
- label: Baixa de Recebimentos # exact name within the workspace
metadata: { sla_horas: 4 }
Only the metadata, which appears in the v1 API and in the webhook payload,
replaced whole when declared. The file does not create a workspace or
activity (they come from the tasks), so a plugin or name that does not exist
becomes a warning.
Order of application​
Tasks → environments → schedules → workspace and activity metadata → webhooks → removal of the repository's environments. See Sync.