{"slug": "how-to-stop-your-coding-agent-from-reading-your-env-secrets", "title": "How to stop your coding agent from reading your .env secrets", "summary": "A developer created Klavex, a CLI tool that eliminates plaintext `.env` files by storing secrets in an encrypted vault and injecting them only into child processes. The tool prevents coding agents like Cursor and Claude Code from reading sensitive credentials during file scans, as secrets never exist on disk. Klavex also supports read-only tokens for CI runners and agents, with per-environment scoping and audit logging.", "body_md": "Open Cursor, Claude Code, or any MCP-enabled agent in your project and ask it to \"fix the failing test.\" To do that, it reads files. Lots of them. And nothing stops it from reading this one:\n\n```\n.env\n```\n\nIt doesn't matter that `.env`\n\nis in your `.gitignore`\n\n. `.gitignore`\n\nkeeps it out of git — it does nothing about a `read_file('.env')`\n\ntool call dropping `STRIPE_SECRET_KEY=sk_live_...`\n\nstraight into a model's context window. The same file that boots your dev server is sitting in plaintext, on disk, readable by every agent you've invited into your editor.\n\nI stared at that for a while and realized the fix isn't \"scope the agent down.\" The fix is: **don't have a plaintext secrets file at all.**\n\nInstead of a `.env`\n\n, you wrap your command:\n\n```\nklavex init             # pick your project + environment once\nklavex run -- npm start # that's it — no flags after this\n```\n\nThe CLI pulls that environment's variables from an encrypted vault and injects them into the **child process only**. Your shell never sees them. Nothing is written to disk. So when the agent goes looking:\n\n``` bash\n$ cat .env\ncat: .env: No such file or directory\n```\n\nThere's nothing to read, because the keys only ever existed inside the `npm start`\n\nprocess. That's the whole pitch in one screenshot.\n\nIt also quietly fixes the boring team problems: no more \"ping six people on Slack for the right keys,\" no more stale `.env`\n\nafter someone rotates a credential — rotate it once, every machine picks it up on the next `klavex run`\n\n.\n\n```\npip install klavex      # Python 3.10+, macOS/Linux/WSL\nklavex login            # opens the browser once, token goes in your OS keychain\nklavex init \nklavex run -- npm start\n```\n\nThat's the entire surface area. I deliberately kept it small — most secrets tools turn into a platform you have to administer. This is three commands.\n\n\"No `.env`\n\n\" handles accidental leakage. But sometimes you genuinely want an agent or a CI runner to use real secrets. For that you mint it its own token, scoped to exactly the environments you pick:\n\n```\n# In the dashboard: New agent → name it → tick the environments it may read → copy the token (shown once).\n# On the agent / CI machine — no browser, no interactive login:\nexport KLAVEX_TOKEN=kx_agent_xxxxxxxx\nklavex run -e env_dev_abc123 -- npm test\n```\n\nThat token is **read-only** (it can read its scoped secrets, but can't create, change, or delete anything) and the backend refuses to decrypt any environment it wasn't granted. Grant it `dev`\n\n, and a request for `prod`\n\ncomes back `403`\n\n. Every fetch lands in an audit log, and revoking the token kills it everywhere.\n\nLet me be honest about the boundary, since this is a security tool and overclaiming is how you lose a dev audience:\n\n**Klavex is not a sandbox.** Anything that can execute arbitrary commands *as you* can still reach the secrets at runtime — it can read `/proc/<pid>/environ`\n\n, or just wrap `klavex run`\n\nitself. What this removes is the *persistent, plaintext-on-disk* footprint: the `.env`\n\nthat lives in your repo for the project's whole life and gets caught by a casual file read, an accidental `git add -f`\n\n, a broad \"scan the repo\" agent pass, a backup, or a screen-share. It shrinks the exposure window from \"always, on disk\" to \"only inside the one process you launched.\" That's a real, meaningful reduction — not airtight magic.\n\nOther honest notes: the CLI isn't open source yet, and the encryption is standard envelope encryption (a per-secret data key wrapped by a KMS master key, with an encryption context bound to `{team, project}`\n\nso a stolen token can't cross-decrypt another tenant's data) — nothing I'm claiming is novel crypto.\n\nIt's early (v0.1.x). Solo is free forever.\n\n```\npip install klavex\n```\n\nDocs: [https://klavex.dev/docs.html](https://klavex.dev/docs.html)\n\nApp: [https://app.klavex.dev](https://app.klavex.dev)\n\nI'd genuinely like feedback on two things:\n\n`klavex run`\n\nin front of every command worth it, or is that friction too high?Rip it apart in the comments.", "url": "https://wpnews.pro/news/how-to-stop-your-coding-agent-from-reading-your-env-secrets", "canonical_source": "https://dev.to/klavex/how-to-stop-your-coding-agent-from-reading-your-env-secrets-5g6o", "published_at": "2026-06-03 01:46:49+00:00", "updated_at": "2026-06-03 02:12:06.333959+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "ai-products", "ai-safety", "ai-infrastructure"], "entities": ["Cursor", "Claude Code", "MCP", "Stripe", "Klavex"], "alternates": {"html": "https://wpnews.pro/news/how-to-stop-your-coding-agent-from-reading-your-env-secrets", "markdown": "https://wpnews.pro/news/how-to-stop-your-coding-agent-from-reading-your-env-secrets.md", "text": "https://wpnews.pro/news/how-to-stop-your-coding-agent-from-reading-your-env-secrets.txt", "jsonld": "https://wpnews.pro/news/how-to-stop-your-coding-agent-from-reading-your-env-secrets.jsonld"}}