envchain-xtra

Maintained envchain fork for safer macOS Keychain secret release and local AI-agent security stacks.

View the Project on GitHub nvk/envchain-xtra

             _
            | |
 ________  _| |_ _ __ __ _
|______\ \/ / __| '__/ _` |
        >  <| |_| | | (_| |
       /_/\_\\__|_|  \__,_|

envchain-xtra

Maintained envchain fork for safer macOS Keychain secret release and local AI-agent security stacks.

envchain-xtra installs the familiar envchain executable: secrets stay in the OS vault, and are released only to the command you explicitly launch. This fork keeps the original interface useful while tightening the defaults that matter when coding agents, wrappers, and sandbox layers are part of the workflow.

brew tap nvk/tap
brew install nvk/tap/envchain-xtra

envchain --set aws AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY
envchain aws env | grep AWS_

Why This Fork Exists

The original sorah/envchain made the important design choice: do not put secrets in shell startup files. Store them in the OS secret store and release them only when needed.

This fork is no longer just an experiment. As of 2026-05-01, the original upstream master branch was last updated on 2024-04-24. This fork now carries the active macOS maintenance, Homebrew distribution, security defaults, and agent-stack integration used by this environment.

The premise is direct:

This fork exists to keep the secret-release layer strong while leaving launch verification and sandbox policy to the layers above and below it.

What You Get

Maintenance Policy

This fork preserves upstream compatibility where that does not weaken the security model. It will intentionally diverge when safer defaults or modern macOS behavior require it.

Current fork responsibilities:

Notable fork changes:

Upstream Sync Policy

This fork still tracks the original project as upstream, but does not wait on upstream for releases that affect local security posture.

Upstream patches are welcome when they fit the fork’s goals. If upstream becomes active again, this repository remains the maintained downstream distribution for the envchain-xtra security stack rather than a temporary branch.

What It Does

Secrets for common computing environments, such as AWS_SECRET_ACCESS_KEY, are commonly provided through environment variables.

A common practice is to place them in shell initialization files such as .bashrc and .zshrc.

Putting these secrets on disk in this way is a grave risk.

envchain stores credential values in a secure vault and exports them to environment variables only when you invoke it explicitly.

Currently, envchain supports macOS Keychain and D-Bus Secret Service (gnome-keyring) as storage backends.

Don’t give any credentials implicitly!

Security Model in This Fork

The intended security model in this fork is not just “store secrets in Keychain and run envchain.”

The preferred stack is:

shell name -> bondage -> [envchain] -> [nono] -> exact pinned tool

In that model:

That split is cleaner because secret release, launch verification, and sandbox policy stay in separate layers instead of being mixed into shell glue.

It also deliberately leans on the OS where the OS is stronger than userland glue:

Compatibility Layer: contrib/shell-guards.zsh

contrib/shell-guards.zsh is still provided for wrapper-based workflows that have not moved to bondage yet.

It remains useful as a transitional or lightweight compatibility layer because it can:

Example:

source /path/to/contrib/shell-guards.zsh

my_tool() {
  _verify_binary my_tool || return 1
  envchain my-namespace nono run -- command my_tool "$@"
}

The helper file also provides:

If you also want a human-approval gate, _require_touchid can be used with an external touchid-check helper when ENVCHAIN_TOUCHID=1.

For new setups, bondage should be the preferred launcher path. The shell guard script is best treated as compatibility glue for setups that still need shell-based wrappers.

Experimental Branches

The touch-id branch is kept separate from master while biometric prompting and secret-storage behavior are evaluated:

The stable path is still envchain for secret release, bondage for launch verification, and nono for sandboxing.

Requirements (macOS)

Requirements (Linux)

Linux support is inherited from upstream. It should not be treated as the primary tested path for this fork unless a maintainer is actively exercising it.

Installation

Homebrew Tap (macOS)

brew tap nvk/tap
brew install nvk/tap/envchain-xtra

This installs the envchain executable from this fork.

Choose this fork when you want the maintained macOS path, safer terminal defaults, Homebrew packaging, and integration with the local AI-agent security stack. Choose upstream only if you specifically need the original behavior and are prepared to own any missing maintenance locally.

If you also want the launcher/policy layer described above:

brew install nvk/tap/agent-bondage

It intentionally conflicts with the upstream Homebrew envchain formula because both install the same binary name.

If upstream envchain is already installed:

brew uninstall envchain
brew install nvk/tap/envchain-xtra

If envchain-xtra is already installed but not linked yet:

brew link --overwrite envchain-xtra

From Source

This path is mainly for development work on the fork itself:

$ make

$ sudo make install
(or)
$ cp ./envchain ~/bin/

Usage

Saving variables

Environment variables are set within a specified namespace. You can set variables in a single command:

envchain --set NAMESPACE ENV [ENV ..]

You will be prompted to enter the values for each variable. Input is hidden by default. After saving, envchain prints a redacted preview: the first four characters, or the prefix up to an early dash, followed by ... and the last three characters. Short values are shown only as ....

For example, we can set two variables, AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, within a namespace called aws:

$ envchain --set aws AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY
aws.AWS_ACCESS_KEY_ID (hidden):
aws.AWS_ACCESS_KEY_ID saved: my-a...key
aws.AWS_SECRET_ACCESS_KEY (hidden):
aws.AWS_SECRET_ACCESS_KEY saved: ...

Here we define a single new variable within a different namespace:

$ envchain --set hubot HUBOT_HIPCHAT_PASSWORD
hubot.HUBOT_HIPCHAT_PASSWORD (hidden):
hubot.HUBOT_HIPCHAT_PASSWORD saved: ...

These will all appear as application passwords with envchain-NAMESPACE in the data store (Keychain in macOS, gnome-keyring in common Linux distros).

Execute commands with defined variables

$ env | grep AWS_ || echo "No AWS_ env vars"
No AWS_ env vars
$ envchain aws env | grep AWS_
AWS_ACCESS_KEY_ID=my-access-key
AWS_SECRET_ACCESS_KEY=secret
$ envchain aws s3cmd blah blah blah
⋮
$ envchain hubot env | grep AWS_ || echo "No AWS_ env vars for hubot"
No AWS_ env vars for hubot
$ envchain hubot env | grep HUBOT_
HUBOT_HIPCHAT_PASSWORD: xxxx

You may specify multiple namespaces at once by separating them with commas:

$ envchain aws,hubot env | grep 'AWS_\|HUBOT_'
AWS_ACCESS_KEY_ID=my-access-key
AWS_SECRET_ACCESS_KEY=secret
HUBOT_HIPCHAT_PASSWORD: xxxx

More options

--list

List namespaces that have been created

$ envchain --list
aws
hubot

--noecho

Do not echo user input. This is the default.

$ envchain --set --noecho foo BAR
foo.BAR (hidden):
foo.BAR saved: ...

--echo

Echo user input while typing. Use this only when you explicitly want plaintext visible in terminal scrollback or logs.

$ envchain --set --echo foo BAR
foo.BAR: visible-while-typing
foo.BAR saved: visi...ing

--require-passphrase

Always ask for keychain passphrase

$ envchain --set --require-passphrase name

--no-require-passphrase

Do not ask for keychain passphrase

$ envchain --set --no-require-passphrase name

Project Lineage

envchain-xtra is based on envchain by Shota Fukumori and contributors. The original project made the important design choice: keep secrets out of shell startup files and release them only for explicit commands.

Original authors:

Fork maintenance and additional changes:

License

MIT License

Releasing

See RELEASING.md.