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.
Sealed units: the deliberate exception
Everything above describes the normal rule — secrets live in the vault, travel as a short-lived lease, and are never written to a host’s disk.
A sealed unit deliberately breaks it. Credentials are resolved at package time and written into the workflow documents inside the artifact, because an air-gapped box cannot ask anyone for a password. The artifact is then as sensitive as the vault entries it carries: keep it off shared storage, and rebuild rather than edit it when a secret rotates.
It is opt-in per unit, never the default, and the artifact declares which mode it was built in. On the running box, values that came from credentials are masked in the definition view, and the credentials panel lists names only. Both of those views need the host access token, so an unauthenticated visitor gets neither the definition nor the credential names — the artifact file itself is the thing to protect, not the dashboard. That holds only in token mode: a unit built for open access drops that gate along with every other one.