Secrets
Top-level secret blocks, node-level secret wiring, and the vendor keys the runtime resolves for you.
What it is. A named group of sensitive values your workflows need: API keys, tokens, credentials. The file declares the variable names; the values live in the project vault, never in the file.
Use it when a node calls a service that needs a key you hold, or several workflows share the same credentials and you want to declare them once.
Works with auth blocks (which read their credentials from a secret block), context.secrets in @ts code, and the per-node secrets: map below.
User-defined secrets flow through context.secrets. Vendor integrations (AI, Resend, Firecrawl, Parallel) resolve their API keys internally: you do not read those keys from context.secrets in @ts blocks.
secret
Group related environment variable names (not values) in a top-level block. Values are set with swirls secret set (stored in the project vault) or in the Portal.
| Field | Type | Required | Description |
|---|---|---|---|
label | string | No | Display label. |
description | string | No | Description. |
vars | identifier array | Yes | Secret key identifiers (e.g. API_KEY, CLIENT_ID). |
secret api_k {
label: "Third-party API"
vars: [API_KEY, API_SECRET]
}Node-level secrets:
On root { } or node name { }, list which vars from which blocks this node may access:
workflow example {
label: "Example"
root {
type: code
label: "Entry"
secrets: {
api_k: [API_KEY]
}
code: @ts {
const key = context.secrets.api_k.API_KEY
return { hasKey: Boolean(key) }
}
}
}Access pattern: context.secrets.<blockName>.<VAR>. See Context.
A node sees only the vars it declared. Secrets are delivered at run time, per node, so a workflow's blast radius is exactly what its file says it is.
Inferred vendor keys
These are resolved by the runtime for the corresponding node types; they are not exposed on context.secrets for user code:
| Node type | Inferred secret |
|---|---|
ai, agent | OPENROUTER_API_KEY (plus provider-specific keys) |
email | RESEND_API_KEY |
scrape | FIRECRAWL_API_KEY |
parallel | PARALLEL_API_KEY |
disk | ARCHIL_API_KEY |
Set them with swirls secret set KEY=... or in the Portal. Until a required key is set, executions for the nodes that need it are held.
Further reading
- Auth blocks: turn secret vars into HTTP authentication
- Context:
context.secretstyping