Environment variables keep configuration and secrets out of your code — define them once and read them at runtime. They come in two layers and two kinds.
Two layers: App base + per-entity override
Set a variable on an App and it's the shared base for everything in that app. A playground, workflow, stream, or agent can define a variable with the same key to override the app value just for itself; any key it doesn't redefine falls back to the app value. Each of those five surfaces has its own Environment variables editor.
Plain vs secure
A plain variable stores its value as-is and can be read wherever it's available (including a playground's browser code). A secure variable is encrypted at rest and is write-only: after you save it the UI shows it masked (••••••••) and re-reading never reveals it — to change a secret you submit a fresh value. Secure values are also scrubbed from run logs and artifacts.
Reading them in code
Server / runtime code — ctx.env
Playground server functions and stream binding functions receive a frozen ctx.env with both plain and secure values resolved:
exports.charge = async (ctx) => {
const key = ctx.env.STRIPE_SECRET_KEY; // secure value, decrypted at runtime
const base = ctx.env.API_BASE_URL; // plain value
const res = await ctx.http.post(base + '/charges', { amount: 500 }, {
headers: { Authorization: 'Bearer ' + key },
});
return res.data;
};
Playground browser code — flowfn.env
A playground's client-side JS can read plain variables via flowfn.env. Secure values are never sent to the browser, so they are absent here by design:
const base = flowfn.env.API_BASE_URL; // plain only — secure keys are not present
Workflow placeholders — {{ env.KEY }}
In workflows, reference a variable anywhere a placeholder is allowed (task inputs, templates, code tasks) with {{ env.KEY }} (the {{ $env.KEY }} form also works). It resolves from the run's merged env; an unknown key is left untouched and a warning is logged, so a missing secret never becomes a silent empty value.
Authorization: Bearer {{ env.API_TOKEN }}
Agents resolve env for their tool calls, but there is no author-facing ctx.env inside an agent, and secure values are never placed in the prompt sent to the model.
Naming & limits
- Keys match
^[A-Za-z_][A-Za-z0-9_]*$— a letter or underscore first, then letters, digits, or underscores. - Reserved keys:
NODE_ENV,PATH,HOME,PWD,USER,SHELL, and any key starting withFLOWFN_. - Up to 100 variables per owner; keys up to 128 characters; values up to 8 KB.