Cadence
Guides

Give a worker a secret it needs

Store a secret as a credential, scope it to a space or a single pool, and have a worker version read it as an environment variable.

A worker often needs a secret to do its job — an API token, a key for a service it calls. This guide stores that secret once, as a credential, and points a worker version at it so the secret reaches the worker as an environment variable without ever being written into the version itself. You will create the credential, choose how widely it applies, wire a worker version to read it, and then rotate or revoke it later.

If the vocabulary is new, read Credentials and worker versions first.

Before you start

Every step here needs admin on the space. See Authentication. You also need, already in place:

  • A pool that runs a worker version, staffed as in Staff a stage with a pool. The credential reaches the worker through that version.
  • The secret value itself — the token or key you are going to store.

One thing is true of every step: a secret's value is set only in the browser. The Model Context Protocol endpoint can list a credential's metadata and revoke a space-scope credential, but it never carries the value in or out, and neither does the HTTP API. So the value is typed into the web interface and nowhere else.

1. Store the secret as a credential

In the web interface, add a credential and enter the secret as its value. You give it three things:

  • A name — uppercase letters, digits, and underscores, starting with a letter, such as GH_TOKEN. A worker version will name this exact string to read it.
  • A provider kind and its config, which is where the secret goes. The simplest kind stores a value you type; others hold the pieces a service needs. Credentials lists the kinds.

The value you type is stored encrypted and is never shown again — not by any read, and not back in the form if the save is rejected. That is worth knowing before you rotate one: rotating means typing the new value in again, because Cadence cannot show you the old one.

2. Choose how widely it applies

Where you add the credential decides which leases resolve it:

  • Space scope — added in the Credentials section of the space's settings, it is available to every pool in the space.
  • Pool scope — added on a pool's own edit page, it applies to that one pool.

A pool-scope credential overrides a space-scope credential of the same name for that pool's leases. So you can set a shared value at space scope and give one pool its own value under the same name, and that pool's workers get the pool's value while every other pool gets the shared one.

The exact browser locations for each scope are in Credentials.

3. Have a worker version read it

A worker version declares its environment variables. Each declaration has a name, a source, and a value. To read a credential, set source to credential and set value to the credential's name:

// worker_versions_update_draft
{ "id": 91, "env_declarations": [ { "name": "GH_TOKEN", "source": "credential", "value": "GH_TOKEN" } ] }

Two things to know before you run this:

  • The environment variable's name and the credential's name are separate. The name is what the worker's process sees; the value is the credential to resolve. They are often the same string, as above, but they need not be.
  • A worker version accepts env declarations only while it is a draft. Publishing a version freezes its fields, so declare the variable on the draft and then publish. If the version is already published, create a new draft (fork it) and declare it there. See worker versions.

If you name a credential that has no live value in the space, the change is refused: a credential source is rejected unless a live credential of that name can be resolved. Store the credential (step 1) before you point a version at it.

4. Confirm the worker reads it

When a lease runs the published version, Cadence resolves the credential and hands the worker the environment variable under the declared name — the worker reads it the way it reads any environment variable, and never sees which credential answered. If you have set both a space-scope and a pool-scope credential of that name, a lease from the pool with its own value gets the pool's; a lease from any other pool gets the space's.

The resolution happens when the lease starts. If no live credential of that name can be resolved at that point, the lease cannot start — so a missing or revoked credential stops the worker rather than running it without the secret.

Rotate the secret

To rotate a credential, add it again under the same name with the new value. The old value is retired and the new one takes its place, so the next lease resolves the new value. Because the stored value is never shown, rotating means typing the new value in — Cadence cannot pre-fill it.

Revoke the secret

Revoking retires a credential. For a space-scope credential, revoke it over the Model Context Protocol endpoint with credentials_revoke, or delete it in the browser. A pool-scope credential is revoked in the browser. See Credentials.

If a Heroku inbound webhook in the space resolves releases with this credential, Cadence asks before revoking it. Over MCP, credentials_revoke returns confirmation_required with the dependent webhooks and revokes nothing until you call it again with confirm: true. In the browser, a Revoke <NAME>? dialog lists them, and Revoke anyway goes ahead. See Credentials § When Heroku webhooks depend on the credential.

Once retired, that name no longer resolves. A worker version that still reads it will not find a value, so its next lease cannot start until a live credential of that name exists again — revoking is a deliberate act with that consequence, not something Cadence works around on its own.

On this page