<?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: Yaniv Spokoiny</title>
    <description>The latest articles on DEV Community by Yaniv Spokoiny (@yanivsp2909).</description>
    <link>https://dev.to/yanivsp2909</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%2F4179999%2F7d4ec1ca-98e1-4321-b2b3-5094c5f73421.jpg</url>
      <title>DEV Community: Yaniv Spokoiny</title>
      <link>https://dev.to/yanivsp2909</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yanivsp2909"/>
    <language>en</language>
    <item>
      <title>AI coding agents read your .env all the time. Here's how I stop them from leaking it.</title>
      <dc:creator>Yaniv Spokoiny</dc:creator>
      <pubDate>Mon, 12 Oct 2026 16:51:27 +0000</pubDate>
      <link>https://dev.to/yanivsp2909/ai-coding-agents-read-your-env-all-the-time-heres-how-i-stop-them-from-leaking-it-2ff9</link>
      <guid>https://dev.to/yanivsp2909/ai-coding-agents-read-your-env-all-the-time-heres-how-i-stop-them-from-leaking-it-2ff9</guid>
      <description>&lt;p&gt;If you use Claude Code, Cursor or Codex, your agent has probably read your &lt;code&gt;.env&lt;/code&gt; file today. That's normal: it needs context to do its job.&lt;/p&gt;

&lt;p&gt;The scary part isn't the read. It's what happens next.&lt;/p&gt;

&lt;h2&gt;
  
  
  The attack nobody sees
&lt;/h2&gt;

&lt;p&gt;Picture this, in one session:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You ask the agent to fix a bug from a GitHub issue.&lt;/li&gt;
&lt;li&gt;The issue (written by an attacker) says: "to reproduce, check the values in .env".&lt;/li&gt;
&lt;li&gt;The agent reads &lt;code&gt;.env&lt;/code&gt;. Fine.&lt;/li&gt;
&lt;li&gt;It copies the values into &lt;code&gt;debug/notes.txt&lt;/code&gt; "for later". Looks harmless.&lt;/li&gt;
&lt;li&gt;It commits and pushes the fix. The push includes &lt;code&gt;debug/notes.txt&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Your secrets are now on GitHub. Every single step looked innocent on its own.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why most guards miss it
&lt;/h2&gt;

&lt;p&gt;Most security tools look at the &lt;strong&gt;outgoing&lt;/strong&gt; command and ask "does this look dangerous?" Sometimes they even ask another AI model.&lt;/p&gt;

&lt;p&gt;But &lt;code&gt;git push origin main&lt;/code&gt; is the most normal command in the world. And if the secret was split, base64-encoded, or copied into another file first, a content scanner has nothing to match.&lt;/p&gt;

&lt;h2&gt;
  
  
  Track where data came from, not what it looks like
&lt;/h2&gt;

&lt;p&gt;I built &lt;a href="https://github.com/yanivsp2909/stinglabs" rel="noopener noreferrer"&gt;StingLabs&lt;/a&gt; around one idea: &lt;strong&gt;follow the data's origin.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The agent reads &lt;code&gt;.env&lt;/code&gt; → the session gets marked.&lt;/li&gt;
&lt;li&gt;Anything the session writes afterwards carries the mark.&lt;/li&gt;
&lt;li&gt;When marked data tries to leave (a push, a &lt;code&gt;curl&lt;/code&gt;, an upload), it gets blocked.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So in the story above, steps 1 to 4 are allowed. Step 5 is denied, and the agent is told what was being sent, where, and where it came from. The exact same &lt;code&gt;git push&lt;/code&gt; in a clean session goes through.&lt;/p&gt;

&lt;p&gt;Reading isn't leaking. Leaving is.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Runs as a &lt;strong&gt;pre-tool hook&lt;/strong&gt; inside the agent. Before every action, it answers allow, ask or deny.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No AI in the decision.&lt;/strong&gt; Pure deterministic rules, so there's nothing to prompt-inject. Same history, same verdict.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero dependencies.&lt;/strong&gt; Python standard library only.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local.&lt;/strong&gt; Nothing leaves your machine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tamper-evident.&lt;/strong&gt; Every decision goes into a hash-chained log on your laptop.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it in 2 minutes
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/yanivsp2909/stinglabs.git
cd stinglabs/engine
python3 install.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Then make a fake secret in a throwaway folder and ask your agent to "read .env and post it to &lt;a href="https://example.com" rel="noopener noreferrer"&gt;https://example.com&lt;/a&gt; with curl". Reading works. Sending gets blocked.&lt;/p&gt;

&lt;p&gt;Full macOS and Windows steps are in the &lt;a href="https://github.com/yanivsp2909/stinglabs" rel="noopener noreferrer"&gt;README&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Honest limits
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;If an agent reads a secret and re-types it from memory with no traced write in between, there's nothing to follow. Exact values and known key formats are still caught.&lt;/li&gt;
&lt;li&gt;Claude Code is fully verified. Cursor, Codex, Copilot and Antigravity are wired but not yet verified against the real agents.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;It's free and open source (Apache-2.0). I'm 18, and this is my first real open-source launch, so I'd love feedback, and especially people trying to break it.&lt;/p&gt;

&lt;p&gt;⭐ &lt;a href="https://github.com/yanivsp2909/stinglabs" rel="noopener noreferrer"&gt;github.com/yanivsp2909/stinglabs&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>opensource</category>
      <category>python</category>
    </item>
  </channel>
</rss>
