AES-256-GCM encrypted vaults locked in the OS keychain —
out of your shell history, off your filesystem as plaintext, and out of reach of AI coding agents.
.env files were never meant to be a security boundary.They're plaintext. Any process running on your machine can read your filesystem. Every export KEY=value you type gets saved to shell history. Accidentally commit it once, paste it into a chat message once, and it's out.
You added .env to .gitignore. That stops Git. It doesn't change the fact that the file is sitting there, unencrypted, next to your source code — readable by any tool, script, or AI assistant with filesystem access.
envsecret replaces .env files with per-project encrypted vaults. The master key lives in the OS keychain — not on disk. Secrets are never written as plaintext anywhere.
When you run your app with envs run, secrets are injected directly into that process's environment. Your shell is never modified. Your project folder stays clean — no plaintext credentials for anything to find.
Before
# plaintext file sitting next to your source code
source .env && node server.jsAfter
# encrypted vault, shell untouched, nothing exposed on disk
envs run -- node server.jsSecrets can leak through three places. envsecret closes all of them.
The vault is AES-256-GCM encrypted. Anyone — or any tool — browsing your project finds vault.enc, a binary blob indistinguishable from random noise without the master key. The master key is in the OS keychain, not on the filesystem.
envs run uses syscall.Exec to replace itself with your process. Secrets are injected directly into the child's environment. The parent shell is never modified — printenv before and after sees nothing new.
There is no export KEY=value command to type. The secret never appears in a command. ~/.bash_history and ~/.zsh_history have nothing to give.
Generates a 256-bit master key, stores it in macOS Keychain or Linux libsecret, creates an encrypted vault at ~/.envsecret/<project>/vault.enc
envs initEach write re-encrypts the vault with a fresh random salt and IV.
envs set DATABASE_URL "postgres://user:pass@host/db"
envs set STRIPE_SECRET "sk_live_..."envsecret replaces itself with your process. Secrets live only in that process's environment, for the lifetime of that process. Nothing persists in the shell.
envs run -- node server.jsThe vault is encrypted binary on disk. The shell environment is never modified. There is no plaintext file in your project for any agent, script, or MCP tool to stumble upon.
Each project gets its own vault and its own master key. Secrets for api-service are completely separate from frontend — different file, different keychain entry, different derived keys.
Authenticated encryption with scrypt key derivation. Fresh salt and IV on every write. Any tampering is detected on load.
macOS Keychain and Linux libsecret. The master key is never written to disk, a config file, or an environment variable.
Process replacement via syscall.Exec. No export. No parent process holding secrets. Nothing in history.
No application code changes. Replace node -r dotenv/config server.js with envs run -- node server.js.
Migrate an existing project in one command, then delete the plaintext file.
envs import .envenvsecret eliminates ambient exposure — plaintext files, shell environment, shell history. It does not protect a compromised runtime.
| Threat | Protected |
|---|---|
.env files readable on disk | ✓Yes |
Secrets in shell history | ✓Yes |
printenv / env in sibling processes | ✓Yes |
Secrets leaking between projects | ✓Yes — isolated vaults and keys |
Accidental .env commit to git | ✓Yes |
AI agent or script finding plaintext credentials on disk | ✓Yes |
Agent calling os.Getenv inside your running app | No |
Root-level /proc inspection or ptrace | No |
Compromised OS keychain | No |
envs init # create vault, store key in keychain
envs set KEY "value" # encrypt and store a secret
envs get KEY # print a single value to stdout
envs list # list key names (values never shown)
envs run -- <command> # run a command with secrets in its env
envs run --clean -- <command> # run with only vault vars + PATH
envs import .env # bulk import from a .env file
envs rename OLD NEW # rename a key
envs copy SRC DST # copy a key to a new name
envs delete KEY # remove a key
envs destroy # permanently delete a project vault
envs projects # list all initialized projects
envs status # vault diagnostics, no secrets exposedcurl -fsSL https://raw.githubusercontent.com/julianofirme/envsecret/main/install.sh | bashgit clone https://github.com/julianofirme/envsecret.git
cd envsecret
go build -o envs .
sudo mv envs /usr/local/bin/Linux prerequisite: libsecret (libsecret-1-dev on Debian/Ubuntu, libsecret-devel on Fedora).