tofupilot env
Last updated on October 21, 2026
The env command manages environment variables: the values a procedure reads through its config: and secrets: keys. An environment variable has one of two types:
| Type | Feeds | After saving |
|---|---|---|
| Secret (default) | A secrets: key, read as {secrets.KEY} | Never shown again: list and resolve show a digest. Use for passwords, API keys and tokens |
| Config | A config: key, read as {config.KEY} | Readable by members with access. Use for non-sensitive values |
It needs a user login (tofupilot login). A station's login is refused. Every subcommand accepts --json, whose entries carry kind: "config" or "secret" and note.
Levels
Every subcommand works on one level, chosen with flags:
| Flags | Level |
|---|---|
| none | The procedure the current directory is linked to |
--procedure <ID_OR_NAME> | That procedure |
--station <ID_OR_NAME> | That station: every procedure it runs |
--shared | Shared: every procedure of the organization |
--station and --shared cannot be combined. Procedures and stations are named by ID or by exact name.
Environments
ENVIRONMENTS is a comma-separated list of production, preview and development. A procedure or shared variable added without one targets all three. A station variable has no environment and counts as production.
One key can have several values at one level when their environments do not overlap. update and remove then need the environment of the value they change.
add
The add subcommand creates an environment variable. Without --value, the value is read from stdin, or asked for at a prompt (hidden for a Secret).
# Secret, the default type
tofupilot env add MES_TOKEN production --value "..." --yes
# Config, readable after saving
tofupilot env add LINE preview,development --no-sensitive --value "line-1"
tofupilot env add MES_URL production --type config --value https://mes.example.com
tofupilot env add DMM_RESOURCE --station line-1-bench-2 --no-sensitive --value "TCPIP0::10.0.0.7::INSTR"
tofupilot env add SETTLE_MS --shared --no-sensitive --value-type integer --value 200
# In a script: reads stdin, without its final line break
printf %s "$TOKEN" | tofupilot env add MES_TOKEN --station line-1-bench-2| Flag | Meaning |
|---|---|
--type <TYPE> | secret (default) or config |
--sensitive | Same as --type secret |
--no-sensitive | Same as --type config |
--value <VALUE> | The value. A Secret passed here lands in the shell history: prefer stdin or the prompt |
--note <TEXT> | Where to rotate the value, or who to contact. Shown where the value is set |
--value-type <TYPE> | string, number, integer or boolean. The value is checked against it |
--force | Overwrite an existing variable with the same key and level whose environments overlap the ones given; it then targets exactly those, and a Config given --type secret becomes a Secret. Both are confirmed first unless --yes. Without it, add stops and names --force |
-y, --yes | Skip confirmations |
--procedure, --station, --shared | The level |
A key is upper case letters, digits and _, not starting with a digit; TOFUPILOT_* is reserved. An empty value sets nothing.
Adding with --type secret and --force, or update --type secret, over an existing Config converts it to a Secret in place. A Secret cannot become a Config: Saved secrets are write-only, so this variable can't be changed to Config. Remove it and add it again.
list
The list subcommand (alias ls) lists the environment variables of one level: key, type, value (Config) or digest (Secret), environments, level and last update. Pass an environment to show only the values that target it.
tofupilot env list
tofupilot env ls production --station line-1-bench-2
tofupilot env ls --shared --type secret| Flag | Meaning |
|---|---|
[ENVIRONMENT] | production, preview or development |
--type <TYPE> | Only config or only secret |
--procedure, --station, --shared | The level |
A digest changes when its value changes. Digests are specific to a row, so two rows holding the same value show different digests.
update
The update subcommand sets a new value on an existing environment variable, and stops when there is none. It takes the same value flags as add.
tofupilot env update MES_TOKEN productionThe version increases, so each run records which value it used.
remove
The remove subcommand (alias rm) removes an environment variable. It asks for confirmation unless --yes is passed.
tofupilot env rm MES_URL preview --yespull
The pull subcommand writes the procedure's development values, Config and Secret, into .env.local, where a source run reads them.
tofupilot env pull
tofupilot env pull .env.bench --station line-1-bench-2| Option | Meaning |
|---|---|
[FILENAME] | The file to write, default .env.local |
--procedure <ID_OR_NAME> | Default: the directory's linked procedure |
--station <ID_OR_NAME> | Include that station's Config values |
-y, --yes | Overwrite an existing file |
A Secret is included only when it targets development. The file is written with mode 0600, and the command warns when .gitignore does not list it.
run
The run subcommand runs a command with the linked procedure's development values in its environment, without writing a file.
tofupilot env run -- python scripts/check_mes.pyresolve
The resolve subcommand shows, for each key a procedure would receive, the value that wins, its level and the lower levels it shadows. It resolves for an environment (default production), and includes a station's values with --station.
tofupilot env resolve production --station line-1-bench-2Secrets follow the precedence rules: a station Secret is left out of a non-production environment. Only keys with a value are listed; the YAML default: is applied when the run starts.
Permissions
| Role | Can |
|---|---|
| Viewer and above | list and resolve (Secrets as digests only) |
| Developer | Add, update and remove Config variables that do not target production |
| Admin, Owner | Also Secrets, station variables and anything that targets production |
Since the default type is Secret and the default environments include production, a Developer passes --no-sensitive and preview or development explicitly.
How is this guide?