<?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: Alex</title>
    <description>The latest articles on DEV Community by Alex (@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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3965514%2F30630741-b16c-473b-a996-07731b21a2c1.png</url>
      <title>DEV Community: Alex</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>How to stop your coding agent from reading your .env secrets</title>
      <dc:creator>Alex</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>
