Filter environment variables
Author: Christian Heimes
Created: 2026-04-23
Status: Open
Issue: #1083
What
A configurable filter for environment variables inherited by external
commands. Fromager strips sensitive variables from os.environ before
they reach build scripts, hooks, or other subprocesses.
Why
Fromager runs arbitrary third-party code during builds – PEP 517 hooks, setup scripts, patching commands, git operations. Every subprocess today inherits the full parent environment, including credentials, CI tokens, and registry passwords that have no business inside a build.
This is a supply-chain risk. A compromised or careless build script can read and exfiltrate any variable it inherits. The risk is higher in CI environments where runners routinely carry cloud credentials, API tokens, and service account keys.
Controlling which variables pass through also improves reproducibility. Stray environment can silently alter build behavior (compiler flags, proxy settings, locale overrides). Filtering makes builds more deterministic.
sudo solves the same problem with env_keep and env_delete in
sudoers. This proposal follows that proven model.
References:
Goals
Filter sensitive environment variables from subprocesses
No configuration means no filtering – existing setups are unaffected
How
Configuration
A new external_commands section in settings.yaml with two optional
lists: keep_env (allowlist) and delete_env (blocklist). Both
default to empty.
external_commands:
keep_env:
- "SOME_VARIABLE"
- "OTHER_*"
delete_env:
- "CREDENTIALS"
- "CI_TOKEN"
Pattern matching
Entries without * are exact matches. Entries ending with * are
prefix matches: AWS_* matches AWS_REGION, AWS_SECRET_ACCESS_KEY,
etc. A * in any other position is a validation error. A bare * is
only valid in delete_env (catch-all); in keep_env it is a
validation error.
Evaluation order
keep_env is evaluated before delete_env. All checks are case-insensitive
and short-circuit. If a variable matches the hard-coded always-keep set or
an entry in keep_env, then the variable is kept.
For each variable in os.environ:
If it is in a hard-coded always-keep set – keep, regardless of configuration. The always-keep set contains variables required for basic subprocess operation and proxy settings:
HOME,HOSTNAME,LANG,LANGUAGE,LC_*,LOGNAME,NO_COLOR,PATH,SHELL,USER,http_proxy,https_proxy,no_proxy.If any
keep_enventry matches – keep.If any
delete_enventry matches – delete.Otherwise – keep (default passthrough).
delete_env: ['*'] can be used to prevent passthrough. It filters all
variables that neither match the always-keep set nor keep_env entries.
Variables injected by fromager itself (extra_environ,
build_environment, package-level env) are never filtered. They are
applied after the filter runs.
API changes
external_commands.run() currently has no access to WorkContext or
settings. Making the filter configuration available there will require
API changes to the function signature or module state. The specifics of
that change are out of scope for this proposal and will be handled by a
separate proposal for the external_commands API.
Examples
Strip everything except what builds need:
external_commands:
keep_env:
- "CARGO_*"
delete_env:
- "*"
Remove a few known secrets, pass everything else:
external_commands:
delete_env:
- "CI_TOKEN"
- "REGISTRY_PASSWORD"
- "AWS_*"