Environment and Configuration
Declaring env vars, substitution, precedence, and secrets.
A config declares every environment variable it depends on under env:, then references them in settings as ${NAME} and in expressions as env.NAME. Referencing an undeclared variable is an error at load time.
Declaring variables
Each declaration has a name and, optionally, a default and a required flag:
env:
- name: HTTP_HOST
default: 0.0.0.0
- name: HTTP_PORT
default: "8080"
- name: FLOW_WORKERS
default: "8"
- name: API_KEY
required: true # must be supplied externally; a default would not satisfy itdefault is used when nothing external supplies the variable; an explicit empty default (default: "") is valid and distinct from no default at all. required: true fails the load when the variable is not supplied by the OS environment or a .env file. A default does not satisfy required.
${NAME} substitution
Any value in the config accepts ${NAME} references to declared variables: settings at any depth, and the flow's own fields too:
connectors:
- name: api
type: http
settings:
host: ${HTTP_HOST}
port: ${HTTP_PORT} # an exact ${VAR} keeps its type -> int 8080
basePath: /api/v1
flows:
- name: orders
workers: ${FLOW_WORKERS} # the same, on a typed flow fieldA value that is exactly one ${NAME} takes the variable's natural type ("8080" becomes the integer 8080, "true" a boolean), so env vars can fill numeric and boolean fields such as workers. A ${NAME} embedded in a longer string is replaced textually. The env: and resources: sections are read to build the environment before substitution runs, so they must be written literally. Two mistakes fail at load time: referencing a name not declared under env:, and referencing a declared name that resolved to no value and has no default.
Changed in 0.5.0. Substitution used to reach only settings values. A ${NAME} anywhere else was left as literal text; now it is resolved, and a reference to a name not declared under env: fails the load. If a value legitimately contains ${...}, declare the variable or rewrite the value.
env.NAME in expressions
The same resolved values are available to every CEL expression through the env variable:
- type: set-payload
settings:
value: '{"greeting": env.GREETING, "at": string(now)}'Use ${NAME} for static configuration and env.NAME when a value participates in per-message logic. See Expressions.
Resolution precedence
Each declared variable resolves from the first source that supplies it:
- The OS environment, which always wins.
HTTP_PORT=9090 octo run --config orders.yamloverrides everything. .envfiles:./.env, overlaid by the file named in$OCTO_ENV_FILE(when set), overlaid by any declaredresources.envfiles in listed order.- The declared
default.
# override at startup without editing the config
HTTP_PORT=9090 octo run --config orders.yaml
# or put the same line in ./.env (hot-reloads with --watch)
echo 'HTTP_PORT=9090' > .env.env files use the usual convention: KEY=VALUE lines, # comments, an optional export prefix, and single- or double-quoted values. A missing .env file is never an error.
On the platform
On the Octo platform, secrets and env resources are managed per integration and supplied to the runtime with the same precedence, so the declarations in your config stay the single source of truth. See Resources and Secrets.