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.
(Plain pip install env-alias works too.)
How it works¶
- Alias definition phase — you add a line to
.bash_aliases/.bashrc. At shell startupenv-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:
How values are generated¶
Env Alias definition files are YAML format files that define how the value for each environment variable is generated.
- All Env Alias definition files MUST have an
env-aliastop-level root. - Environment variable names are defined by their key name, or their
nameattribute. - Each environment-variable definition uses attributes that define how their values are generated or obtained.
Most definitions use exactly one of source, exec, or value. For ordinary file, HTTP(S), and exec content, generation follows three steps:
- Acquire content from a local file, HTTP(S) URL, or command stdout.
- Parse content as JSON, YAML, INI, or plaintext.
- Select one value with a JSON/YAML path, an INI
<section>.<option>, or a plaintext line number.
Direct value, <stdin>, and <getpass> definitions return raw values. KeePass uses its selector as an entry/attribute lookup, while Ansible Vault and password-file support are special cases.
Definitions are evaluated top-to-bottom. An env:NAME reference first reads the process environment, then a value generated by an earlier definition, so put a value-producing definition before its consumer.
Quick start¶
# one alias, name inferred from the filename
source <(env-alias ~/projects/awesome/env-awesome-vars.yml)
# one alias, explicit name (only one file may follow an explicit name)
source <(env-alias awesome-envvars ~/projects/awesome/env-awesome-vars.yml)
# MANY projects in one line — one alias per file, each lazy-loaded
source <(env-alias \
~/.config/env-alias/env-proj-a.yml \
~/.config/env-alias/env-proj-b.yml \
~/.config/env-alias/env-proj-c.yml)
The multi-file form is recommended when you have many definitions: it collapses many env-alias process startups into one, while each emitted alias still lazily loads only its own file.
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.
By naming your aliases with an easy-to-remember prefix such as env-, they group together for shell tab-completion.
What's next¶
- Definition attributes — every attribute explained.
- Extended Examples — real-world setups, each tagged with the definition attributes they use.
- Troubleshooting — common issues and fixes.
- Security — threat model and best practices.
- Development — building and testing with the Makefile/uv toolchain.