Documentation

Everything you need to manage secrets with envsec.

Installation

envsec requires Node.js 18 or later. Install globally via npm:

bash
npm install -g envsec

Or run directly without installing:

bash
npx envsec

If you use mise as a version manager:

bash
mise use -g npm:envsec

Quick Start

Store your first secret. The -c flag sets the context — a label for grouping related secrets.

bash
# Store a secret
envsec -c myapp.dev add api.key -v "sk-abc123"

# Retrieve it
envsec -c myapp.dev get api.key

# List all secrets in the context
envsec -c myapp.dev list

# Run a command with secret interpolation
envsec -c myapp.dev run 'curl -H "Auth: {api.key}" https://api.example.com'

Requirements

macOS

No extra dependencies. Uses the built-in Keychain via the security CLI tool.

Linux

Requires libsecret-tools (provides the secret-tool command), which talks to GNOME Keyring, KDE Wallet, or any Secret Service API provider via D-Bus.

bash
# Debian / Ubuntu
sudo apt install libsecret-tools

# Fedora
sudo dnf install libsecret

# Arch
sudo pacman -S libsecret

Windows

No extra dependencies. Uses the built-in Windows Credential Manager via cmdkey and PowerShell.

envsec add

Store a secret in the OS credential store.

bash
# Inline value
envsec -c myapp.dev add api.key --value "sk-abc123"

# Interactive masked prompt (omit --value)
envsec -c myapp.dev add api.key

# With expiry duration
envsec -c myapp.dev add api.key -v "sk-abc123" --expires 30d

# Supported units: m (minutes), h (hours), d (days),
# w (weeks), mo (months), y (years)
# Combinable: 1y6mo, 2w3d, 1d12h
envsec -c myapp.dev add api.key -v "sk-abc123" -e 6mo

envsec get

Retrieve a single secret value.

bash
envsec -c myapp.dev get api.key

envsec list

List all secrets in a context, or list all contexts.

bash
# List secrets in a context
envsec -c myapp.dev list

# List all contexts (without -c)
envsec list

envsec delete

Remove a secret from the credential store.

bash
envsec -c myapp.dev delete api.key

# Skip confirmation prompt
envsec -c myapp.dev delete api.key --yes

# Alias
envsec -c myapp.dev del api.key

envsec run

Execute a command with secret interpolation. Placeholders like {key} are resolved and injected as environment variables — values never appear in ps output.

bash
# Run with secret interpolation
envsec -c myapp.dev run 'curl {api.url} -H "Authorization: Bearer {api.token}"'

# Save the command for later
envsec -c myapp.dev run --save --name deploy 'kubectl apply -f - <<< {k8s.manifest}'

envsec cmd

Manage saved commands.

bash
# List saved commands
envsec cmd list

# Run a saved command
envsec cmd run deploy

# Override context at execution time
envsec cmd run deploy --override-context myapp.prod

# Search saved commands
envsec cmd search psql

# Delete a saved command
envsec cmd delete deploy

envsec env

Export secrets as shell environment variable statements.

bash
# bash/zsh
eval $(envsec -c myapp.dev env)

# fish
envsec -c myapp.dev env --shell fish

# powershell
envsec -c myapp.dev env --shell powershell

# Unset exported variables
eval $(envsec -c myapp.dev env --unset)

Keys are converted to UPPER_SNAKE_CASE (e.g. api.token API_TOKEN).

envsec env-file

Export secrets to a .env file.

bash
# Default output: .env
envsec -c myapp.dev env-file

# Custom output path
envsec -c myapp.dev env-file --output .env.local

envsec load

Import secrets from a .env file into a context.

bash
# Import from .env
envsec -c myapp.dev load

# Custom input file
envsec -c myapp.dev load --input .env.local

# Overwrite existing secrets
envsec -c myapp.dev load --force

envsec audit

Check for expired or expiring secrets.

bash
# Default window: 30 days
envsec -c myapp.dev audit

# Custom window
envsec -c myapp.dev audit --within 7d

# Only already-expired
envsec -c myapp.dev audit --within 0d

# Audit all contexts
envsec audit

# JSON output
envsec -c myapp.dev audit --json

envsec share

Encrypt secrets with GPG for team sharing.

bash
# Encrypt for a team member
envsec -c myapp.dev share --encrypt-to [email]

# Save to file
envsec -c myapp.dev share --encrypt-to [email] -o secrets.enc

# JSON format inside encrypted payload
envsec -c myapp.dev --json share --encrypt-to [email] -o secrets.enc

The recipient decrypts with gpg --decrypt secrets.enc and pipes the result into envsec load.

Contexts

A context is a free-form label for grouping secrets — e.g. myapp.dev, stripe-api.prod, work.staging. Most commands require a context specified with --context (or -c).

Keys must contain at least one dot separator (e.g. service.account) which maps to the credential store's service/account structure.

Custom Database Path

By default, metadata is stored at ~/.envsec/store.sqlite. Override with --db or the ENVSEC_DB environment variable.

bash
# Project-local database
envsec --db ./local-store.sqlite -c myapp.dev list

# Via environment variable
export ENVSEC_DB=/shared/team/envsec.sqlite
envsec -c myapp.dev list

Shell Completions

Tab completion for bash, zsh, fish, and sh.

bash
# Bash (add to ~/.bashrc)
eval "$(envsec --completions bash)"

# Zsh (add to ~/.zshrc)
eval "$(envsec --completions zsh)"

# Fish (add to ~/.config/fish/config.fish)
envsec --completions fish | source

Security Model

envsec delegates encryption to your OS native credential store. It never invents its own crypto. Secret values go straight from your terminal into the OS credential store — they are never written to config files, logs, or intermediate storage.

The list and search commands display key names only — values are never printed. The run command injects secrets as environment variables of the child process rather than interpolating them into the command string, keeping values out of ps output and shell history.

The metadata directory (~/.envsec/) is created with 0700 permissions and the SQLite database with 0600, limiting access to the owning user.

Known Limitations

  • The SQLite database stores key names, context names, and timestamps — never secret values, but enough to reveal what secrets exist.
  • The env-file command writes secret values to a .env file on disk. Treat the output file accordingly.
  • The run command passes templates through /bin/sh. Only run templates you wrote or trust.
  • Any process running as your OS user can read all secrets across all contexts.
  • On Linux, envsec depends on an active D-Bus session and a keyring daemon.