Cadence
Reference

Credentials

Store, rotate, and revoke the secrets a worker version reads, at space and pool scope.

A credential holds a secret — a token or key — that a worker version reads through an environment variable declared with a credential source. Credentials exist at space scope and pool scope; a pool-scope credential overrides a space-scope one of the same name for that pool's leases.

Every credential operation on this page needs admin on the space. See Authentication. Replace https://cadence.example.com with your instance's address.

A credential has a name (uppercase letters, digits, and underscores, starting with a letter), a provider kind, and a config that holds the secret. The config is stored encrypted and is never returned by any read, and never echoed back into a form on error — nothing you type is shown again.

List and revoke over MCP

  • credentials_list returns the credentials in a space as metadata only — each row's name, provider_kind, label, whether it is retired, and its timestamps. It never returns the config. The list includes both space-scope and pool-scope credentials.
  • credentials_revoke retires a live credential by name. It acts on space-scope credentials; a pool-scope credential is revoked from the web interface. It takes space_key, name, and an optional confirm.

Retiring a credential leaves the name unresolved, so a worker version that reads it will no longer find a value.

When Heroku webhooks depend on the credential

A Heroku inbound webhook resolves a credential to judge each succeeded release (see Inbound § Which credential a release is resolved with). A live Heroku webhook depends on a credential's name when:

  • it is bound to that name, or
  • it is not bound, and it has received deliveries for an app whose HEROKU_TOKEN_<APP> is that name. A delivery received before your instance offered webhook binding has no webhook recorded, so it counts against every unbound Heroku webhook in its space, so such a webhook can be listed even if it never received a delivery for that app.

A webhook is not counted when a live credential of the same name at the other level — space or instance — would still serve it after the revoke.

If any webhook depends on the name and you do not pass confirm: true, credentials_revoke revokes nothing and returns the webhooks instead:

// credentials_revoke
{ "space_key": "OPS", "name": "HEROKU_TOKEN_SUNRISE_WEB" }
{
  "confirmation_required": true,
  "dependent_webhooks": [
    {
      "id": 42,
      "space": "OPS",
      "source": "heroku",
      "label": "Production releases",
      "credential_name": null,
      "revoked": false,
      "revoked_at": null,
      "created_at": "2026-10-01T10:04:00Z",
      "app_names": ["sunrise-web"]
    }
  ]
}

Each entry is the webhook as inbound_webhooks_list returns it, plus app_names: the apps whose deliveries made it depend on the name. app_names is empty for a webhook that is bound to the name. To revoke anyway, call again with confirm: true. A revoke goes ahead as before when no webhook depends on the name. A name with no live space-scope credential is still refused with no live credential named "<NAME>".

This is a warning, not a block. Once you revoke the name, every succeeded release those webhooks resolve with that name is refused until a live credential of that name exists again. Restoring the credential does not reach releases already refused: an admin must re-run each one — see Inbound § Re-run a refused delivery.

Set and rotate in the web interface

Putting a config into the registry is done in the web interface only — a secret never crosses an API or MCP boundary.

  • Space scope: /spaces/:space_id/credentials/new to add or rotate, and the Credentials section of space settings to review. Deleting revokes. When Heroku webhooks depend on the credential, deleting first opens a Revoke <NAME>? dialog, described below.
  • Pool scope: /spaces/:space_id/pools/:pool_id/credentials/new to add or rotate, reviewed inline on the pool's edit page.

Setting a credential on a name that already has a live value rotates it: the old value is retired and the new one inserted. Because the config is never shown, rotating means typing the new value in again.

The Revoke <NAME>? dialog lists each webhook that depends on the credential, by its label (or "Unlabelled webhook") and its source, marked "bound to <NAME>" or "by app name: <apps>". Revoke anyway revokes the credential. Cancel revokes nothing. Which webhooks count is described in When Heroku webhooks depend on the credential.

Instance-scope credentials are a separate surface reachable only by whoever administers the Cadence instance, not by a space admin. An instance-scope credential can serve a Heroku webhook in any space that has no live space-scope credential of the same name (see Inbound § Which credential a release is resolved with), so deleting one on the instance Settings → Credentials page asks the same confirmation, and also shows each webhook's space.

On this page