DEV Community

Cover image for Your Terminal Remembers Every Secret You've Ever Typed
David Nussio
David Nussio

Posted on

Your Terminal Remembers Every Secret You've Ever Typed

TL;DR: I built envsec, a free, open-source CLI that stores your development secrets in macOS Keychain, GNOME Keyring, or Windows Credential Manager. Run commands with secrets without ever exposing them in your shell history or ps output. Generate .env files on the fly when you need them, delete them when you're done. No provider, no account, no subscription. The v1.0 beta is out now. npm install -g envsec@beta and you're done.


The secrets hiding in your terminal

Open your shell history right now. Go ahead, history | grep -i key or history | grep -i password. Scared yet?

Every time you run curl with an API key, psql with a connection string, or docker run with credentials, those secrets land in your shell history file. They show up in ps output. They live in plaintext on disk until you manually scrub them — which you never do.

And it gets worse. If you're like most developers, you also have .env files scattered across every project directory on your machine — including projects you haven't touched in months. Each one is a plaintext file with API keys, database passwords, and tokens just sitting there on your filesystem. Any process running as your user can read them. Any supply chain attack that scans your project directories can harvest them. One malicious npm postinstall script, one compromised VS Code extension, and every secret across every project you've ever worked on is exfiltrated in milliseconds.

This isn't theoretical. In September 2025, the Shai-Hulud worm did exactly this: it compromised over 500 npm packages and used TruffleHog to recursively scan victims' home directories — .env files, git history, config files, all of it. When I read about it, my first thought wasn't "am I running one of those packages?" It was: "how many abandoned .env files do I have sitting in my projects right now?" I checked. The answer was uncomfortable.
Security researchers have found over a million secrets from exposed environment files across tens of thousands of websites. Stolen credentials were the attack vector in roughly one in five breaches reported in recent industry analyses.

The enterprise world solved this with tools like HashiCorp Vault, Doppler, and Infisical. But those solutions require cloud accounts, infrastructure, and dedicated DevOps staff. If you're a solo developer or on a small team, you don't need a SaaS platform with SSO and RBAC to keep your Stripe test key out of your shell history.

What if your OS could be the vault?

Your operating system already has a battle-tested, encrypted credential store:

  • macOS has the Keychain
  • Linux has GNOME Keyring / KDE Wallet (Secret Service API)
  • Windows has Credential Manager

These are the same systems that protect your Wi-Fi passwords, SSH keys, and browser credentials. They use hardware-backed encryption where available. They've been audited by millions of users for decades.

So I built envsec to put them to work for your development secrets.

How envsec works

envsec is a Node.js CLI. No daemon, no server, no cloud account. You install it, and it talks directly to your OS credential store.

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

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

# Run a command with secrets injected as env vars
envsec -c myapp.dev run 'curl -H "Auth: {api.key}" https://api.example.com'
Enter fullscreen mode Exit fullscreen mode

The -c flag sets a context — a label for grouping related secrets. Think myapp.dev, stripe-api.prod, work.staging. You organize secrets however makes sense for your workflow.

Secret values go straight into the OS credential store. They never touch a config file, a log, or intermediate storage. envsec only keeps metadata (key names, timestamps) in a local SQLite database — never the values themselves.

What you can do with it

.env files become ephemeral, not permanent

envsec doesn't try to eliminate .env files — too many tools depend on them. Instead, it changes the relationship. Your secrets live permanently in the OS vault. The .env file becomes a temporary artifact you generate when you start working and throw away when you're done:

# Start of your work session: generate .env from the vault
envsec -c myapp.dev env-file --output .env.local

# ... do your work ...

# End of session: delete it. The secrets are safe in the vault.
rm .env.local
Enter fullscreen mode Exit fullscreen mode

Why does this matter? Think about supply chain attacks. A malicious npm package, a compromised postinstall script, a rogue VS Code extension — all they need to do is scan $HOME or your project directories for .env files. If you have 10 projects, that's 10 plaintext files with credentials sitting there 24/7, waiting to be harvested.

With envsec, the .env exists only while you're actively working. The attack surface window shrinks from "always" to "only during active development." And the secrets themselves? Locked behind OS-level encryption that no fs.readFileSync can touch.

Coming soon: I'm working on automating this pattern — envsec will hook into your shell or project tooling to export secrets when you cd into a project and clean them up when you leave. Zero manual steps.

# You can also import existing .env files into the vault
envsec -c myapp.dev load --input .env.local

# Then delete the original — you won't need it anymore
rm .env.local
Enter fullscreen mode Exit fullscreen mode

Your terminal is leaking secrets — envsec stops that

This is the part I care about the most, and the core reason I built envsec.

Think about what happens every time you run a command with a secret in it:

# This is what most of us do — and it's terrible
curl -H "Authorization: Bearer sk-live-abc123xyz" https://api.stripe.com/v1/charges
psql "postgres://admin:P@ssw0rd!@db.example.com:5432/prod"
Enter fullscreen mode Exit fullscreen mode

That API key is now in your shell history forever. It's visible in ps output to every process on your machine. It's probably synced to your dotfiles repo. If you use a shared server, your coworkers can see it.

The usual workaround? Prefix with a space (and hope your shell is configured to ignore it), or pipe from a file, or use some ad-hoc export dance that you forget the syntax of every time.

envsec solves this cleanly. The run command resolves {key} placeholders and injects values as environment variables of the child process — the actual secret values never appear in ps output, never land in shell history, and never touch the command string:

# The secret never appears in your terminal or history
envsec -c myapp.prod run 'psql {db.connection_string}'

# Same for API calls
envsec -c stripe.live run 'curl -H "Authorization: Bearer {api.key}" https://api.stripe.com/v1/charges'
Enter fullscreen mode Exit fullscreen mode

What your shell history sees: envsec -c stripe.live run 'curl -H "Authorization: Bearer {api.key}" ...'
What it doesn't see: your actual API key. Ever.

Save the command, forget the secret

But here's where it gets really practical. How many times do you run the same command with the same secrets? Database connections, API calls, deploy scripts — it's always the same commands. envsec lets you save the command template once and replay it forever, without ever exposing the underlying secrets:

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

# Run it again — secrets are resolved fresh from the vault every time
envsec cmd run deploy

# Same command, different environment — just swap the context
envsec cmd run deploy --override-context myapp.prod

# List all your saved commands
envsec cmd list

# Search through them
envsec cmd search psql
Enter fullscreen mode Exit fullscreen mode

This is the workflow I always wanted: the command lives in envsec, the secret lives in the OS vault, and your terminal history stays clean. No provider, no cloud account, no subscription. Just a free, open-source devtool that respects both your security and your workflow.

Export as shell variables

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

# fish
envsec -c myapp.dev env --shell fish
Enter fullscreen mode Exit fullscreen mode

Audit expiring credentials

# Set expiry when adding secrets
envsec -c myapp.dev add api.key -v "sk-abc123" --expires 30d

# Audit what's expiring soon
envsec -c myapp.dev audit --within 7d
Enter fullscreen mode Exit fullscreen mode

Share secrets securely with GPG

envsec -c myapp.dev share --encrypt-to colleague@company.com -o secrets.enc
Enter fullscreen mode Exit fullscreen mode

No more pasting API keys in Slack DMs.

How it compares

envsec .env files Doppler/Infisical HashiCorp Vault
Setup time 30 seconds 0 10-30 minutes Hours/days
Infrastructure None None Cloud/self-hosted Self-hosted cluster
Provider/account None needed None needed Required Required
Encryption OS-native None Custom/AES Custom
Shell history safe Yes — secrets never in history No CLI injection yes CLI injection yes
Command memory Built-in (save & replay) No No No
Supply chain exposure Secrets not on filesystem Always on disk Not on disk Not on disk
Cost Free, forever Free Free tier + paid Free + operational cost
Best for Solo devs, small teams Quick prototypes Growing teams Enterprise

envsec isn't trying to replace Vault or Doppler. If you need centralized team management with RBAC and audit logs at scale, those tools are excellent. envsec fills a different gap: a free, provider-free devtool for developers who want secure secrets in their terminal without infrastructure or accounts.

Why I built this

Three things kept bugging me.

First, my terminal was a liability. Every curl, every psql, every deploy script with a credential in it — all captured in shell history, all visible in process listings. I wanted to run commands with secrets without leaving traces.

Second, my .env files were a sitting target. Every project directory had one. Always there, always in plaintext, always available for any process — legitimate or malicious — to read. I didn't want to stop using .env files entirely (too many tools depend on them), but I wanted them to be temporary — generated when I need them, deleted when I'm done, with the real secrets locked in the OS vault.

Third, the false dichotomy. The developer community acts like there are only two options: plaintext files, or sign up for a cloud service. But I didn't want a provider. I didn't want to create an account. I didn't want my secrets leaving my machine. I just wanted a proper devtool — free, local, provider-free — that treats secrets like secrets.

Your OS already has the answer. It just needed a decent CLI in front of it. That's envsec: a devtool that gives you secure secret management in the terminal, with command memory so you never have to type (or expose) a secret again. No vendor, no lock-in, no monthly bill. Just your Keychain and your rules.

The beta is live

envsec v1.0 beta is available now:

brew install davidnussio/homebrew-tap/envsec

npm install -g envsec@beta

npx envsec@beta
Enter fullscreen mode Exit fullscreen mode

It works on macOS, Linux, and Windows. Node.js 18+ required. On Linux you'll need libsecret-tools installed (most desktop distros have it).

What's in the beta:

  • Full CRUD for secrets organized by context
  • Glob pattern search across contexts and secrets
  • .env import/export for backward compatibility
  • Command interpolation and saved commands
  • Secret expiry and audit
  • GPG-based team sharing
  • Shell completions for bash, zsh, fish, and PowerShell

Try it, break it, tell me about it

This is a beta, which means I want your feedback. If something feels wrong, if a workflow is missing, if it blows up on your specific Linux distro — I want to hear about it.

Star the repo if you think your terminal history shouldn't be a liability. Open an issue if envsec doesn't work for you yet. And if you find it useful, share it with a developer friend who's still typing API keys directly into curl.


envsec is MIT-licensed and will always be free and open source.


Tags: #opensource #security #devtools #node #cli #dotenv #secrets

Top comments (0)