<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Klavex</title>
    <description>The latest articles on DEV Community by Klavex (@klavex).</description>
    <link>https://dev.to/klavex</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3965514%2F30630741-b16c-473b-a996-07731b21a2c1.png</url>
      <title>DEV Community: Klavex</title>
      <link>https://dev.to/klavex</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/klavex"/>
    <language>en</language>
    <item>
      <title>Stop AI coding agents from reading your .env secrets</title>
      <dc:creator>Klavex</dc:creator>
      <pubDate>Thu, 11 Jun 2026 01:43:38 +0000</pubDate>
      <link>https://dev.to/klavex/stop-ai-coding-agents-from-reading-your-env-secrets-4ic9</link>
      <guid>https://dev.to/klavex/stop-ai-coding-agents-from-reading-your-env-secrets-4ic9</guid>
      <description>&lt;p&gt;I was working in Claude Code when it opened my &lt;code&gt;.env&lt;/code&gt; to "understand the configuration" — and then, helpfully, suggested I rotate the keys, since they were now exposed. The thing that exposed them was the agent reading them.&lt;/p&gt;

&lt;p&gt;That's the moment the problem clicked. So here's what's actually wrong with &lt;code&gt;.env&lt;/code&gt; in an agent-heavy workflow, and the approach I landed on.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem: your &lt;code&gt;.env&lt;/code&gt; is an agent buffet
&lt;/h2&gt;

&lt;p&gt;The same &lt;code&gt;.env&lt;/code&gt; file that lets your dev server boot also feeds every tool in your editor. Cursor, Claude Code, Copilot, and any MCP server you've wired up can &lt;code&gt;cat&lt;/code&gt; it whenever they want. There's no permission boundary — if it's on disk and your editor can read your project, the agent can read your keys.&lt;/p&gt;

&lt;p&gt;Two things make this worse than the old "don't commit your &lt;code&gt;.env&lt;/code&gt;" advice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;You can't scope an agent down.&lt;/strong&gt; It's all-or-nothing file access. The agent that needs to read &lt;code&gt;src/&lt;/code&gt; also gets &lt;code&gt;AWS_SECRET_ACCESS_KEY&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It leaks sideways.&lt;/strong&gt; The same file gets copy-pasted into Slack to onboard a teammate, screenshared, and synced into who-knows-what.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The root issue is simple: it's a plaintext file sitting on disk, and anything running in your editor can read a file on disk.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fix: don't keep a &lt;code&gt;.env&lt;/code&gt; at all
&lt;/h2&gt;

&lt;p&gt;The approach that actually removes the risk is to stop having the file. Instead of reading secrets from disk, inject them into the process at runtime — only for as long as the command runs.&lt;/p&gt;

&lt;p&gt;That's what I built &lt;a href="https://klavex.dev" rel="noopener noreferrer"&gt;Klavex&lt;/a&gt; to do. Setup is one command, and it imports your existing &lt;code&gt;.env&lt;/code&gt; so there's nothing to rewrite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;klavex

klavex init                 &lt;span class="c"&gt;# detects your repo, imports your existing .env, pins the project&lt;/span&gt;
klavex run &lt;span class="nt"&gt;--&lt;/span&gt; npm start     &lt;span class="c"&gt;# secrets injected into this process at runtime — nothing on disk&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After &lt;code&gt;klavex init&lt;/code&gt;, you delete the local &lt;code&gt;.env&lt;/code&gt;. From then on, &lt;code&gt;klavex run -- &amp;lt;your command&amp;gt;&lt;/code&gt; pulls the secrets from an encrypted vault straight into that one child process. They're never written to a file, so there's nothing for an agent to open.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scoping agents instead of trusting them
&lt;/h2&gt;

&lt;p&gt;The part I care about most: when you &lt;em&gt;do&lt;/em&gt; want an agent or a CI job to have keys, you don't hand it the whole vault. You mint it a &lt;strong&gt;read-only token scoped to specific environments&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;KLAVEX_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;scoped-token&amp;gt; klavex run &lt;span class="nt"&gt;-e&lt;/span&gt; &amp;lt;env-id&amp;gt; &lt;span class="nt"&gt;--&lt;/span&gt; ./run-tests.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Grant a token Dev, and Production is simply unreachable — the API refuses to decrypt anything outside the token's allowlist. The token can read its scoped secrets but can't create, change, or delete anything. So an agent gets exactly the keys you chose, and prod stays invisible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not Doppler or Infisical?
&lt;/h2&gt;

&lt;p&gt;Fair question — they're genuinely good tools, and they also do runtime injection. The honest difference is &lt;strong&gt;scope and pricing&lt;/strong&gt;, not security:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They're full &lt;strong&gt;platforms&lt;/strong&gt;: dozens of integrations, dynamic secrets, rotation, PKI, SSH, audit tiers. A lot to stand up and configure.&lt;/li&gt;
&lt;li&gt;They're priced &lt;strong&gt;per seat&lt;/strong&gt;, which climbs fast for a small team.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If what you want is narrow — "get my secrets off disk and scope what my agents can read" — that's a whole platform to adopt for one job. Klavex's bet is the opposite: it does that one thing, you're set up in one command, AI agents are free and unlimited, and team pricing is flat (it never scales per seat). The day you need dynamic secrets or PKI, Doppler and Infisical are exactly where you should go.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this does &lt;em&gt;not&lt;/em&gt; do
&lt;/h2&gt;

&lt;p&gt;To be precise about the threat model, because it matters: &lt;strong&gt;this is not a sandbox.&lt;/strong&gt; Anything running as your user can still read the process environment at runtime — including, in principle, a sufficiently determined tool. What Klavex removes is the plaintext file that sits on disk forever, readable at any time, by anything. That's the realistic, high-frequency exposure, and it's the one worth closing.&lt;/p&gt;




&lt;p&gt;It's live, free for solo use: &lt;a href="https://klavex.dev" rel="noopener noreferrer"&gt;klavex.dev&lt;/a&gt;. If you work with coding agents daily, I'd genuinely like to know whether this matches a problem you've hit — or whether I'm the only one who kept watching Claude read my keys.&lt;/p&gt;

</description>
      <category>security</category>
      <category>ai</category>
      <category>devops</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to stop your coding agent from reading your .env secrets</title>
      <dc:creator>Klavex</dc:creator>
      <pubDate>Wed, 03 Jun 2026 01:46:49 +0000</pubDate>
      <link>https://dev.to/klavex/how-to-stop-your-coding-agent-from-reading-your-env-secrets-5g6o</link>
      <guid>https://dev.to/klavex/how-to-stop-your-coding-agent-from-reading-your-env-secrets-5g6o</guid>
      <description>&lt;p&gt;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:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;.&lt;span class="n"&gt;env&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It doesn't matter that &lt;code&gt;.env&lt;/code&gt; is in your &lt;code&gt;.gitignore&lt;/code&gt;. &lt;code&gt;.gitignore&lt;/code&gt; keeps it out of git — it does nothing about a &lt;code&gt;read_file('.env')&lt;/code&gt; tool call dropping &lt;code&gt;STRIPE_SECRET_KEY=sk_live_...&lt;/code&gt; straight 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.&lt;/p&gt;

&lt;p&gt;I stared at that for a while and realized the fix isn't "scope the agent down." The fix is: &lt;strong&gt;don't have a plaintext secrets file at all.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The idea: inject secrets at runtime, never write them to disk
&lt;/h2&gt;

&lt;p&gt;Instead of a &lt;code&gt;.env&lt;/code&gt;, you wrap your command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;klavex init             &lt;span class="c"&gt;# pick your project + environment once&lt;/span&gt;
klavex run &lt;span class="nt"&gt;--&lt;/span&gt; npm start &lt;span class="c"&gt;# that's it — no flags after this&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The CLI pulls that environment's variables from an encrypted vault and injects them into the &lt;strong&gt;child process only&lt;/strong&gt;. Your shell never sees them. Nothing is written to disk. So when the agent goes looking:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; .env
&lt;span class="nb"&gt;cat&lt;/span&gt;: .env: No such file or directory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's nothing to read, because the keys only ever existed inside the &lt;code&gt;npm start&lt;/code&gt; process. That's the whole pitch in one screenshot.&lt;/p&gt;

&lt;p&gt;It also quietly fixes the boring team problems: no more "ping six people on Slack for the right keys," no more stale &lt;code&gt;.env&lt;/code&gt; after someone rotates a credential — rotate it once, every machine picks it up on the next &lt;code&gt;klavex run&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;klavex      &lt;span class="c"&gt;# Python 3.10+, macOS/Linux/WSL&lt;/span&gt;
klavex login            &lt;span class="c"&gt;# opens the browser once, token goes in your OS keychain&lt;/span&gt;
klavex init 
klavex run &lt;span class="nt"&gt;--&lt;/span&gt; npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That'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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Letting an agent have &lt;em&gt;some&lt;/em&gt; secrets — on purpose
&lt;/h2&gt;

&lt;p&gt;"No &lt;code&gt;.env&lt;/code&gt;" 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:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# In the dashboard: New agent → name it → tick the environments it may read → copy the token (shown once).&lt;/span&gt;
&lt;span class="c"&gt;# On the agent / CI machine — no browser, no interactive login:&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;KLAVEX_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;kx_agent_xxxxxxxx
klavex run &lt;span class="nt"&gt;-e&lt;/span&gt; env_dev_abc123 &lt;span class="nt"&gt;--&lt;/span&gt; npm &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That token is &lt;strong&gt;read-only&lt;/strong&gt; (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 &lt;code&gt;dev&lt;/code&gt;, and a request for &lt;code&gt;prod&lt;/code&gt; comes back &lt;code&gt;403&lt;/code&gt;. Every fetch lands in an audit log, and revoking the token kills it everywhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this does &lt;em&gt;not&lt;/em&gt; do (because someone will ask)
&lt;/h2&gt;

&lt;p&gt;Let me be honest about the boundary, since this is a security tool and overclaiming is how you lose a dev audience:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Klavex is not a sandbox.&lt;/strong&gt; Anything that can execute arbitrary commands &lt;em&gt;as you&lt;/em&gt; can still reach the secrets at runtime — it can read &lt;code&gt;/proc/&amp;lt;pid&amp;gt;/environ&lt;/code&gt;, or just wrap &lt;code&gt;klavex run&lt;/code&gt; itself. What this removes is the &lt;em&gt;persistent, plaintext-on-disk&lt;/em&gt; footprint: the &lt;code&gt;.env&lt;/code&gt; that lives in your repo for the project's whole life and gets caught by a casual file read, an accidental &lt;code&gt;git add -f&lt;/code&gt;, 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.&lt;/p&gt;

&lt;p&gt;Other 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 &lt;code&gt;{team, project}&lt;/code&gt; so a stolen token can't cross-decrypt another tenant's data) — nothing I'm claiming is novel crypto.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it / tell me I'm wrong
&lt;/h2&gt;

&lt;p&gt;It's early (v0.1.x). Solo is free forever.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;klavex
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Docs:    &lt;a href="https://klavex.dev/docs.html" rel="noopener noreferrer"&gt;https://klavex.dev/docs.html&lt;/a&gt;&lt;br&gt;
App:     &lt;a href="https://app.klavex.dev" rel="noopener noreferrer"&gt;https://app.klavex.dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'd genuinely like feedback on two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Is &lt;code&gt;klavex run&lt;/code&gt; in front of every command worth it, or is that friction too high?&lt;/li&gt;
&lt;li&gt;Is "your agent can read your .env" a real problem you've felt — or am I solving something nobody cares about?&lt;/li&gt;
&lt;li&gt;Should i also provide a typescript CLI?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Rip it apart in the comments.&lt;/p&gt;

</description>
      <category>security</category>
      <category>ai</category>
      <category>cli</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
