mine env
Manage per-project environment profiles encrypted at rest, stored outside your repository. Values are masked by default in CLI output; reveal is always explicit.
Passphrase
Section titled “Passphrase”All mine env operations require a passphrase. mine resolves it in this order:
MINE_ENV_PASSPHRASEenv var — highest priority, always winsMINE_VAULT_PASSPHRASEenv var — fallback vault passphrase- OS keychain — stored via
mine vault unlock, retrieved transparently - Interactive prompt — secure input (no echo) when running in a terminal
The passphrase is never stored on disk in plaintext. By default it is only held in memory during each operation, but if you run mine vault unlock it may also be persisted securely in the OS keychain (encrypted/protected by the OS). In non-interactive mode without a passphrase source, commands fail with a clear error.
Set env vars permanently in your shell profile for CI/automation, or run mine vault unlock once for interactive use.
Show Active Profile
Section titled “Show Active Profile”mine envShows the current project’s active profile with values masked. Equivalent to mine env show.
Show a Profile
Section titled “Show a Profile”mine env showmine env show stagingmine env show staging --revealShows variables for the active profile (default) or a named profile. Values are masked unless --reveal is passed.
| Flag | Default | Description |
|---|---|---|
--reveal | false | Print raw values instead of masked values |
Set a Variable
Section titled “Set a Variable”mine env set API_URL=https://api.example.commine env set API_TOKEN # prompts securely — no shell historyprintf '%s\n' "$TOKEN" | mine env set API_TOKEN # read value from stdinSets a variable in the active profile. Pass KEY=VALUE inline or pass only KEY to read the value securely from TTY input (hidden) or from stdin. Using the prompt or stdin keeps secrets out of shell history.
If the key already exists, the value is overwritten.
Unset a Variable
Section titled “Unset a Variable”mine env unset API_TOKENRemoves a variable from the active profile permanently.
Compare Profiles
Section titled “Compare Profiles”mine env diff local stagingShows keys that differ between two profiles: added, removed, and changed. Values are never shown in diff output.
Switch Active Profile
Section titled “Switch Active Profile”mine env switch stagingChanges the active profile for the current project. The target profile must already exist.
Export for Shell
Section titled “Export for Shell”mine env exportmine env export --shell fishEmits shell export statements for the active profile. Use this with eval to load vars into your session, or pipe to a script.
| Flag | Default | Description |
|---|---|---|
--shell | posix | Export syntax: posix (bash/zsh) or fish |
Use the menv shell helper from mine shell init as a shortcut:
eval "$(mine shell init)"menvGenerate a Template
Section titled “Generate a Template”mine env template > .env.exampleEmits .env.example-style output with keys only and empty values. Useful for documenting required variables in your repository without exposing any secrets.
Inject into a Subprocess
Section titled “Inject into a Subprocess”mine env inject -- go test ./...mine env inject -- env | grep API_Runs a command with the active profile variables injected into the subprocess environment. Profile variables override any matching inherited environment variables. Your shell session is not affected.
Edit a Profile in $EDITOR
Section titled “Edit a Profile in $EDITOR”mine env editmine env edit stagingOpens the active profile (or a named profile) in $EDITOR for bulk editing. The profile is decrypted to a secure temp file, opened in your editor, then re-encrypted and saved on clean exit.
The temp file format is one KEY=VALUE line per variable, sorted alphabetically. Blank lines and lines starting with # are ignored on re-read.
Behaviour:
- If
$EDITORis not set, the command fails with an actionable error suggesting how to set it and themine env setfallback. - If the editor exits non-zero, all edits are discarded and the original profile is unchanged.
- If any key in the edited file is invalid (doesn’t match
[A-Za-z_][A-Za-z0-9_]*), the command fails and the original profile is unchanged. - If a named profile does not exist, the command errors rather than silently creating an empty profile.
- The temp file is removed (with best-effort zero-fill) on all exit paths — success, editor error, or parse error.
Shell Integration
Section titled “Shell Integration”Install the menv helper by adding eval "$(mine shell init)" to your shell config:
# ~/.zshrc or ~/.bashrceval "$(mine shell init)"Then use menv to load your active profile at any time:
mine env switch stagingmenvecho "$API_URL"On fish, menv automatically uses fish-compatible export syntax. In all shells, menv returns a non-zero exit code if export fails.
Security Notes
Section titled “Security Notes”- Profile files are encrypted at rest using age with passphrase-based scrypt key derivation.
- Plaintext values are never written to disk at any point.
- Profile files are written atomically (temp file → rename) to prevent corruption.
- Profile file permissions are
0600(owner read/write only). - If you forget your passphrase, the profile cannot be recovered.
- Wrong passphrase returns a non-zero exit code with an explicit error — there is no silent fallback.
- A tampered or corrupted profile returns a non-zero exit code — there is no auto-repair.
Error Handling
Section titled “Error Handling”| Situation | Behavior |
|---|---|
| Wrong passphrase | Non-zero exit, explicit error with hint |
| Corrupted profile | Non-zero exit, explicit error with hint |
Missing profile on switch | Non-zero exit, profile name in error |
Missing named profile on edit | Non-zero exit, profile name in error |
| No passphrase in non-interactive mode | Non-zero exit, instructive error |
| Invalid key name | Non-zero exit before any disk writes |
$EDITOR not set on edit | Non-zero exit, suggests export EDITOR=vim and mine env set fallback |
Editor exits non-zero on edit | Non-zero exit, original profile unchanged |
| Invalid key in edited file | Non-zero exit listing bad keys, original profile unchanged |
Storage Location
Section titled “Storage Location”Profiles are stored at $XDG_DATA_HOME/mine/envs/ (default ~/.local/share/mine/envs/).
Each project gets a subdirectory named by sha256(project_path). Profile files inside are named <profile>.age. The active profile per project is tracked in the mine SQLite database.
Override the data directory with the XDG_DATA_HOME environment variable.