Skip to main content

Secrets in the Playbook

No secret value lives in the Playbook. The frontmatter declares only the names, in required_secrets, and this list is an allowlist: only what is in it reaches that execution.

The path of a secret in production​

  1. The value stays in Kadu's vault, registered per environment in Settings → Secrets.
  2. At the start of the execution, Kadu delivers only the secrets listed in the task's required_secrets, as environment variables, and registers them for masking.
  3. The skill body reads $KOBANA_ACCESS_TOKEN, $FINTERA_TOKEN directly from the environment.
  4. Before sending any event, log, pending item or result to the console, the instrumentation replaces each secret's value with a mask.

Masking covers every variable in required_secrets, whatever its name, and catches the value as is, JSON-escaped (including JSON inside JSON) and, for a multi-line value, line by line. It ignores values shorter than 6 characters and does not recognize a transformed value (base64, URL-encoded).

Masking is the last line of defense; the first is not producing the leak. Never echo, log or include the value of a secret in the result, in events or in pending items.

Provisioning a new secret: order matters​

  1. Add the name to the task's required_secrets and merge.
  2. Check that the sync ran and listed the task under "Tasks updated". Before that, the old list remains in effect.
  3. Register the value in the environment, before the next run time if the task has schedules.

In the reverse order, the execution calls the external system with an empty variable and fails midway, not at the start.

Configuration is a secret too​

The allowlist is Kadu's only channel for environment variables. What is not a secret but needs to be able to change per organization also goes in it: a Linear project id, an ERP entity id (REPORT_LINEAR_PROJECT_ID, FINTERA_ENTITY_ID).

This catches whoever writes ${VAR:-default} in the body: a variable read with a default and outside the allowlist can never be overridden by Kadu. The skill works, the default always applies, and nobody notices until they need to change the value without a deploy. To check, cross the variables the body reads with required_secrets. Whatever is left must be exported by the body itself (working directory, for example), never configuration.

Adding an optional variable to the list is safe: with no value in the vault, it just does not arrive. The exception is the run endpoint, which rejects the call with 422 missing_secrets when a secret in the list has no value in the environment.

Inventory in kadu.yaml​

Each environment in kadu.yaml can list the keys it should have. This delivers nothing to any task: it lets the sync warn when an expected key has no value in that environment.

required_secrets (in the task)secrets (in the kadu.yaml environment)
What it isthe execution's allowlistthe environment's expected inventory
Effectthe variable reaches the executionwarning on the sync if a value is missing

In local development​

There is no vault: test values come from a .env outside git (for example sandbox/.env, from a sandbox/.env.example versioned with only the names). Outside Kadu the instrumentation runs in simulation mode, so no secret is sent anywhere. See Local development.