Env Alias
Env Alias is an environment variable swiss-army-knife that lets you load complex collections of environment variables from a variety of sources only when you need them, reducing the risk of working with sensitive values.
It loads values from local files, http(s) URLs, shell exec output, Keepass databases, Ansible Vault files — in
JSON, YAML, Plaintext and INI formats — and exports them into your shell as a one-shot sourced
command. Values are fetched lazily, on demand, when you invoke the alias, so secrets are never loaded until you
actually use them.
Features
- Data sources: local files,
http(s)URLs,<getpass>,<stdin>, KeePass, Ansible Vault, and stdout fromexec. - Content formats: JSON, YAML, INI, and plaintext.
- Selectors: dot, slash, and bracket paths for JSON/YAML;
<section>.<option>for INI; line numbers for plaintext. - Ansible Vault Password File helper: generates the executable password-file arrangement Ansible expects.
env:NAMEreferences: reuse one whole value from the process environment or an earlier definition.- Internal-only values:
name: nullsuppresses normal export to the calling shell while retaining the value for later definitions in the same run. execsupport: run prerequisite or startup commands as part of a definition.- Terminal-only messages:
value_to: <stderr>writes to the terminal without polluting stdout. --debugoutput: written to STDERR; treat it as sensitive because it can contain secret material.- Multi-file invocation: define many lazy aliases with one command.
- Easy installation from PyPI.
Installation
Requires Python 3.10 or later.
pipx install env-alias
(Plain pip install env-alias works too.)
How it works
There are two phases:
- Alias definition phase — you add a line to
.bash_aliases/.bashrc. When a new shell starts,env-aliasprints one or more shellaliascommands, which your shell sources. The aliases are lightweight placeholders — they do not load any secrets yet. - Invocation phase — when you actually run an alias (e.g. type
env-awesome), it shells out toenv-alias --generator <file>, which resolves the values and printsexport "VAR"='value'lines that your shell sources. This is where the real (possibly slow, network/secret-fetching) work happens.
Because a child process can never modify your current shell, the command must be sourced. The standard wrapper is:
source <(env-alias ...)
# equivalent:
eval "$(env-alias ...)"
Usage — .bash_aliases
One alias, name inferred from the filename
source <(env-alias ~/projects/awesome/env-awesome-vars.yml)
This defines the alias env-awesome-vars (from the filename — note hyphens are fine), which when run loads the
environment defined in env-awesome-vars.yml.
One alias, explicit name
source <(env-alias awesome-envvars ~/projects/awesome/env-awesome-vars.yml)
Defines the alias awesome-envvars. An explicit alias name may be followed by only one definition file.
Many projects — one line, one alias per file
If you have ~20 project definition files, don't launch 20 env-alias processes at shell startup. Pass them all at
once — env-alias emits one alias per file, each lazily loading only its own file:
source <(env-alias \
~/.config/env-alias/env-proj-a.yml \
~/.config/env-alias/env-proj-b.yml \
~/.config/env-alias/env-proj-c.yml)
You can also pass a file pattern (glob):
source <(env-alias ~/.config/env-alias/env-*.yml)
One process at shell startup defines env-proj-a, env-proj-b and env-proj-c as independent lazily-loaded
aliases. This is the recommended pattern when you have many definitions.
Tab-completion
Name your aliases with a common prefix such as env- so they group together for shell tab-completion.
Example definition
env-alias:
MYPROJECT_KEEPASS_FILE:
name: null # internal only — not exported
exec: 'root="$(git rev-parse --show-toplevel)" && printf "%s/secrets/myproject-keepass.kdbx" "$root"'
MYPROJECT_KEEPASS_PASSPHRASE:
source: "<getpass>" # prompt the user (getpass) when run
override: false # don't re-prompt if already set
MYPROJECT_ANSIBLE_VAULT_PASSWORD:
name: null
source: "env:MYPROJECT_KEEPASS_FILE"
selector: "myproject-name/ansible-vault-entry-name:Password"
keepass_password: "env:MYPROJECT_KEEPASS_PASSPHRASE"
ANSIBLE_VAULT_PASSWORD_FILE:
ansible_vault_password: "env:MYPROJECT_ANSIBLE_VAULT_PASSWORD"
ansible_vault_password_file: true # render an Ansible Vault password file
AWS_SECRET_ACCESS_KEY:
source: "env:MYPROJECT_KEEPASS_FILE"
selector: "myproject-name/aws-entry-name:Password"
keepass_password: "env:MYPROJECT_KEEPASS_PASSPHRASE"
AWS_ACCESS_KEY_ID:
source: "env:MYPROJECT_KEEPASS_FILE"
selector: "myproject-name/aws-entry-name:Username"
keepass_password: "env:MYPROJECT_KEEPASS_PASSPHRASE"
MYPROJECT_KEEPASS_PASSPHRASE is prompted for via getpass but only if not already set (override: false), then
used to open the KeePass file so the AWS credentials and Ansible Vault password can be selected. The passphrase is
exported so it can be reused in the current shell; run unset MYPROJECT_KEEPASS_PASSPHRASE when finished.
Definition attributes
Each definition uses a small set of attributes to describe how its value is generated. See the documentation for full detail:
| Attribute | Purpose |
|---|---|
source |
Read a local file or HTTP(S) URL; <getpass>, <stdin>, and env:VAR are special sources |
parser |
Explicitly use yaml/yml, json, ini, or none; omitted content types are inferred |
selector |
Select a scalar from structured content, or a one-based line number from plaintext |
name |
Override the exported env-var name; null suppresses export to the calling shell |
value |
Set a direct value (or a whole-value env:VAR reference); bypasses parsing and selection |
exec |
Run a shell command; use its stdout as content |
override |
Whether to overwrite an existing env value (default true) |
keepass_password |
Password to open a Keepass .kdbx source |
ansible_vault_password |
Password for an Ansible Vault file |
ansible_vault_password_file |
Render an Ansible Vault password file |
value_to |
Also write a resolved value to <stderr>; combine with name: null for a terminal-only message |
Debugging
Add --debug to see verbose diagnostics on STDERR:
source <(env-alias --debug env-awesome-vars.yml)
Note: --debug output can contain secret material — treat it as sensitive.
Common issues & troubleshooting
- Aliases not defined? You must
source(oreval) the output — a bare command only prints it. Empty or malformed definitions root 'env-alias'— your file'senv-alias:key is empty/null. Add entries.keepassxc-cli/ansible-vaultnot found — install the respective binary and add it toPATH.- See Troubleshooting for more.
Security
The exec attribute runs arbitrary shell commands (shell=True). A malicious definition file can run any
command on your machine. Only use definition files you wrote or audited. See
the security documentation for the full threat model.
Project
- Docs — threatpatrols.github.io/env-alias
- PyPI — pypi.python.org/pypi/env-alias
- GitHub — github.com/threatpatrols/env-alias
This project was migrated from github.com/ndejong/env-alias to github.com/threatpatrols/env-alias in March 2025.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file env_alias-0.8.0.tar.gz.
File metadata
- Download URL: env_alias-0.8.0.tar.gz
- Upload date:
- Size: 212.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
586c8826d7ce482505e42afbb4cf9e847ca2c7c56759d546912dfe3418c52544
|
|
| MD5 |
e94574971d302430473a2c6e18237f23
|
|
| BLAKE2b-256 |
9fbdb036829efe67ec5c68caeb7e4bbbed269f96db9d91420f84c6b973cb567f
|
Provenance
The following attestation bundles were made for env_alias-0.8.0.tar.gz:
Publisher:
publish.yml on threatpatrols/env-alias
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
env_alias-0.8.0.tar.gz -
Subject digest:
586c8826d7ce482505e42afbb4cf9e847ca2c7c56759d546912dfe3418c52544 - Sigstore transparency entry: 2539431256
- Sigstore integration time:
-
Permalink:
threatpatrols/env-alias@71cea11622f4fe38184fab6245278e55898d0cde -
Branch / Tag:
refs/tags/v0.8.0 - Owner: https://github.com/threatpatrols
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@71cea11622f4fe38184fab6245278e55898d0cde -
Trigger Event:
push
-
Statement type:
File details
Details for the file env_alias-0.8.0-py3-none-any.whl.
File metadata
- Download URL: env_alias-0.8.0-py3-none-any.whl
- Upload date:
- Size: 23.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8024b516835daf5f9cc31759581e395717c56b69a339a42ff9bff0e857ade2f4
|
|
| MD5 |
88590bf54afed699a458ebcc9d17186d
|
|
| BLAKE2b-256 |
a53bcccaa955d66d6b3bef6d6e7cb196bc594bda0ef817e6e715b6d4860d4f1e
|
Provenance
The following attestation bundles were made for env_alias-0.8.0-py3-none-any.whl:
Publisher:
publish.yml on threatpatrols/env-alias
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
env_alias-0.8.0-py3-none-any.whl -
Subject digest:
8024b516835daf5f9cc31759581e395717c56b69a339a42ff9bff0e857ade2f4 - Sigstore transparency entry: 2539431268
- Sigstore integration time:
-
Permalink:
threatpatrols/env-alias@71cea11622f4fe38184fab6245278e55898d0cde -
Branch / Tag:
refs/tags/v0.8.0 - Owner: https://github.com/threatpatrols
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@71cea11622f4fe38184fab6245278e55898d0cde -
Trigger Event:
push
-
Statement type: