Credentials & variables
Workflow configs never contain secrets. They contain references, and the values live in the Nucleus vault — encrypted at rest (AES-256-GCM), masked in the UI, and resolved only when a run starts. The payoff: exported workflows are safe to share, artifacts are safe to copy, and rotating a key is a one-place edit that the whole fleet picks up on its next run.
This page is the model; the hands-on walkthroughs (with screenshots of every step, including the full OAuth2 Connect flow) live in the Credentials guide and Variables guide.
References
| Syntax | Resolves to | Example |
|---|---|---|
${credential.<id-or-name>.<field>} | A field of a stored credential | ${credential.telegram-bot.botToken} |
${variable.<id-or-name>} | An org-wide variable (Admin → Variables) | ${variable.alerts-channel} |
References resolve once, at run start — before any {{ }} expression runs — in both the
editor’s test runs and deployed apps. Credentials can be referenced by id or by name.
Credential templates & the picker
Credentials are typed by templates (Telegram bot, Slack bot, SMTP, Postgres, S3, OAuth2
providers, generic bearer/API key, and more). Connection nodes start with a credential picker:
pick a stored credential and the node’s connection fields fill with the right
${credential.<id>.*} placeholders; pick None to enter values manually; create a new
credential inline with + New.
Each credential row shows where it’s used — the workflows that reference it, with a marker when one is live on a host — and deleting one is guarded by that usage: the product names the workflows that would break.
Two more behaviors worth knowing:
- Secrets never round-trip. Editing a credential shows its secret fields blank/redacted — the stored values are not sent to the browser. Leave a secret untouched and the stored value is kept; type to replace.
- References accept id or name.
${credential.telegram-bot.botToken}and${credential.cred_56da21f413.botToken}resolve identically — rename-safe by id, readable by name.
OAuth2
OAuth2 credentials are first-class: presets for Google, Microsoft, Notion and HubSpot, plus a generic provider (your own auth/token URLs). The flow:
- Create the credential with your OAuth client id + secret.
- Click Connect — the Nucleus builds the consent URL (PKCE, signed single-use state) and the
provider redirects back to
/api/oauth/callback. - Tokens are stored as managed, masked fields. Status shows connected / expiring / error.
Refresh is automatic at resolve time: whenever a credential is resolved for a run and the access token is near expiry, the Nucleus refreshes it synchronously (with a per-credential lock) and serves the fresh token. Long-lived deployed apps re-resolve every run start, which bounds token staleness to one run.
Setting up a Google OAuth client — redirect URIs, API enablement, test users and the 7-day testing caveat — is covered step-by-step in the Google Sheets guide.
How deployed workflows get secrets
Deployed workflows contain no secret values — only the references. At deploy time the
Nucleus mints a resolve token scoped to that deployment. At the start of every run the host
calls home (POST /api/runtime/resolve) with that token, receives exactly the values the
workflow references under a short TTL lease (60 seconds), substitutes them in memory, and never
writes them to disk.
Consequences worth knowing:
- Rotating a credential in the vault takes effect on each deployment’s next run — no redeploy.
- A copied workflow document is useless without its deployment’s resolve token and network reach to your Nucleus.
- Worker process environments are scrubbed; secrets do not leak into child env or logs.
- The lease is scoped: a deployment can resolve only the references its own workflow declares — a compromised host cannot enumerate the vault.
Variables
Org-wide variables (Admin → Variables) hold non-secret config — URLs, channel names, thresholds —
referenced as ${variable.name} anywhere a credential reference works. Same resolution timing,
same “used by” tracking. Variables are typed (string, prompt, number, boolean, JSON,
tenants): a prompt variable gives long-form AI prompt text a proper authoring surface, and a
tenants variable holds the registry the Rate Limit node
enforces — see the Variables guide.