Not in the abstract. Every coding agent I run reads files into context — Cursor, Claude Code, Copilot. .env gets pulled in along with everything else. Once a key is in a prompt, it's in a network request, possibly a provider log, possibly a model trace I'll never see.
Add the older failure modes — bots scraping every new GitHub commit for sk-… patterns within minutes; CI runners that echo env blocks into build logs; teammates who paste production keys into Slack at 2 a.m. so you can debug an incident — and .env starts to feel like the leakiest place in the developer workflow.
So I designed Keyden — a CLI that replaces .env with an AES-256-GCM encrypted vault that lives on your machine and never writes plaintext to disk.
What .env actually costs you
- Secrets sit on disk in plaintext. Anything that can read your file system can read your keys — including the coding agent you just installed.
- git tracking is opt-out. .gitignore is one tooling override away from shipping the file. Public-repo scanners read it within minutes of push.
- Build systems and CI runners regularly print env to logs by accident.
- Sharing across a team means someone copies it into Slack, email, or 1Password and you lose track of who has what.
- Rotation is a manual hunt across every machine, every CI provider, and every staging environment.
Tools like dotenv-vault and SOPS exist to patch parts of this, but they all add a service, a cloud account, or a non-trivial setup story. For local development specifically, I wanted something simpler: encrypted at rest, opened with one password, with a workflow that mirrors what dotenv already gives you.
Keyden in four commands
1. install once npm install -g keyden
2. create your vault (you set the password) keyden init
3. add a secret keyden set GEMINI_API_KEY
4. run anything with secrets injected as env vars keyden run npm startThat's it. The vault file is a single AES-256-GCM-encrypted blob at ~/.keyden/vault.enc. There is no .env file in your project — so there is nothing to accidentally commit, and nothing for a coding agent to read. There is nothing to paste into Slack — your teammates run keyden init with their own password and pull values into a vault of their own.
If you'd rather use it from Node directly, the SDK is:
const keyden = require('keyden');
await keyden.open(process.env.KEYDEN_PASSWORD);
const key = await keyden.get('GEMINI_API_KEY');The crypto, briefly
I'm a developer, not a cryptographer, so the design choice was to use Node's built-in crypto module and nothing else. No third-party crypto packages. Nothing to supply-chain attack via a transitive dependency:
- AES-256-GCM authenticated encryption. Any tampering is detected on decrypt.
- scrypt KDF at N=²¹⁷. Roughly 500ms per brute-force attempt on commodity hardware.
- Atomic writes via temp-file rename. No half-written vault if a write is interrupted.
- chmod 600 at creation. `keyden doctor` re-validates the file's permissions.
- Symlink-traversal protection. Every write checks the full vault path for symbolic links.
The password itself is never written anywhere. It's only used to derive the key in memory. If you forget it, the vault is gone. (A recovery flow is on the roadmap, but it'll be opt-in.)
What Keyden parks. What it doesn't.
Be honest about the threat model or you mislead people. Keyden removes a specific class of risk — not all of them.
Parked
- Plaintext keys sitting on disk where any process can read them.
- Accidental git commits — there is no .env file in the project to commit.
- CI runners that echo the env block into a build log.
- Coding agents (Cursor, Claude Code, Copilot) pulling .env into prompts.
Still on you
- Malware running on your unlocked machine while the vault is open.
- A stolen laptop with the vault password remembered or cached.
- Phishing the vault password out of you.
- Supply-chain attack on the keyden npm package itself (which is why the crypto is Node built-ins only — smaller surface).
I'd rather be specific about scope than oversell. Keyden parks four specific worries — the leakiest, most automated, most embarrassment-prone ones. The rest stay on you, the way they always have.
.env vs Keyden, side by side
- Secrets at rest: plaintext on disk → AES-256-GCM encrypted.
- Accidental git commit: high risk → no .env file exists to commit.
- Coding agent reads .env: yes, into the prompt → no .env to read.
- CI/CD logs: env block visible → secrets read from vault, never logged
- Key rotation: hunt every .env file → `keyden rotate` (one command)
- Sharing across a team: Slack/Notion → shared team vaults (Teams plan)
- External dependencies: dotenv package required → zero, Node.js built-ins only
What Keyden is NOT
Keyden is for local development. It doesn't run on Vercel. It doesn't run on AWS Lambda. It doesn't run inside Docker images. It doesn't replace your platform's secrets manager — and it shouldn't. Use AWS Secrets Manager, GCP Secret Manager, Vercel environment variables, or whatever your hosting provides for production.
If you want a single tool that bridges local and prod, this isn't it. What it does fix is the leakiest part of the developer experience: the part where keys sit on your laptop in plaintext for months at a time, in front of every tool that can read a file.
Building it in public
Keyden is free, and the core vault stays free forever. Pro, Teams, and Enterprise tiers are on the way for sync, shared vaults, and team admin — those are paid. I'd rather charge for the multi-user pieces than carve up the single-developer experience.
The examples repo is open: github.com/divyabairavarasu/keyden-examples. Issues, PRs, and pointed criticism welcome — especially on the crypto.
Try it
npm install -g keyden && keyden initSite, docs, and quick start: https://keyden-guide.space
Quick-start guide: https://keyden-guide.space/docs/quick-start
Examples repo: https://github.com/divyabairavarasu/keyden-examples