Environment variables
${VAR} resolution, what's interpolated, what isn't.
Cannectors substitutes ${VAR_NAME} references in the YAML with the
corresponding environment variable at startup. This is the only
way to pass secrets into a pipeline — credentials never live in the
YAML, and the resolved values are never logged.
Syntax
authentication:
type: bearer
credentials:
token: ${SOURCE_BEARER_TOKEN}The expression is ${NAME}. Curly braces are required. The variable
name must match [A-Z_][A-Z0-9_]* (uppercase letters, digits,
underscores; can't start with a digit).
When substitution happens
Substitution runs once, at pipeline startup, before the runtime is built and before the first input fetch. The resolved configuration is held in memory for the lifetime of the process.
Implication: if you rotate a secret, you have to restart the process for Cannectors to pick up the new value. There's no hot-reload.
Where it works
Substitution happens on string values in the YAML, regardless of which module they belong to. The most common slots:
| Slot | Example |
|---|---|
| Bearer / Basic / OAuth2 credentials | token: ${SRC_TOKEN} |
| API key | key: ${API_KEY} |
| Database connection strings | connectionStringRef: ${WAREHOUSE_DATABASE_URL} |
| Webhook HMAC secrets | secret: ${WEBHOOK_HMAC_SECRET} |
You can use ${VAR} anywhere a string is expected, including in
endpoints if you really want to:
endpoint: ${SOURCE_BASE_URL}/api/ordersWhat isn't substituted
- Numbers, booleans, arrays: only strings get substituted. Don't
write
maxAttempts: ${MAX_ATTEMPTS}— keep numeric tuning inside the YAML. - Templates: the
{{record.x}}syntax is not env-var substitution. Those are record placeholders, resolved per record at runtime — see Records. - Defaults: if
${VAR}is missing or empty, Cannectors fails fast at startup with a clear error. There's no implicit "default if unset" mechanism.
Loading vars
Cannectors reads os.Environ() — nothing else. Use whatever pattern
your shell/runtime already uses to populate env:
# direct
export SOURCE_BEARER_TOKEN=…
cannectors run pipeline.yaml
# inline (one-shot)
SOURCE_BEARER_TOKEN=… cannectors run pipeline.yaml
# via .env file (your shell, not Cannectors)
set -a; source .env; set +a
cannectors run pipeline.yamlFor systemd, set Environment= or EnvironmentFile= in the unit. For
Kubernetes, use envFrom: secretRef or env: valueFrom: secretKeyRef.
Cannectors does not read .env files itself. Use your shell or a
loader like direnv, dotenv-cli, or your container platform's
secret injection.
What gets logged
The runtime logs the structure of the pipeline (module types,
counts, schedule expression) but never the values resolved from env
vars. If you see ${VAR} in logs, it's because substitution failed —
the value was never resolved.
cannectors validate --verbose also redacts resolved credentials —
you'll see credentials: {token: "[redacted]"} instead of the literal
token.