How do I use secrets and env vars in steps?
1min read
TL;DR: Store every credential in Secrets, then reference it with ${VAR} in connector headers and HTTP steps, or read it from the environment in Code steps. Secrets are encrypted per workspace and resolved at run time, so keys never live in playbook bodies, source control, or run output.
Who this is for
Developers handling API keys, tokens, and other credentials inside playbooks.
Where do secrets live?
Secrets are stored in Ballet's per-tenant encrypted store. You add them once and reference them by name wherever a credential is needed — they are never written into the playbook definition.
How do I reference a secret?
- Connector headers and HTTP steps — use
${VAR}interpolation:
Authorization: Bearer ${EXAMPLE_API_KEY}
- Code steps — read from the environment:
const key = process.env.EXAMPLE_API_KEY;
The placeholders are resolved at connect/run time from the workspace secret store.
How is this different from an API token?
| Secret | API token | |
|---|---|---|
| Purpose | Credentials a playbook uses to call out to other systems | A credential others use to call into Ballet |
| Where used | Steps, connector headers | Authorization: Bearer on Ballet API/MCP requests |
| Managed in | Secrets | Settings → API tokens |
See authentication for API tokens.
Best practices
- One secret per credential; give it a clear, specific name.
- Never paste keys directly into a step, prompt, or commit.
- Rotate by updating the secret value — references keep working.
- Return only non-sensitive data from steps so secrets don't leak into run output.
