<?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: RedCapra</title>
    <description>The latest articles on DEV Community by RedCapra (@redcapra).</description>
    <link>https://dev.to/redcapra</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%2F4106778%2F5b2037ee-e511-4ce6-8447-13e4adc31572.png</url>
      <title>DEV Community: RedCapra</title>
      <link>https://dev.to/redcapra</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/redcapra"/>
    <language>en</language>
    <item>
      <title>We audited our AI coding agent's own config. It failed.</title>
      <dc:creator>RedCapra</dc:creator>
      <pubDate>Wed, 02 Sep 2026 22:07:36 +0000</pubDate>
      <link>https://dev.to/redcapra/we-audited-our-ai-coding-agents-own-config-it-failed-450a</link>
      <guid>https://dev.to/redcapra/we-audited-our-ai-coding-agents-own-config-it-failed-450a</guid>
      <description>&lt;p&gt;Your AI coding agent runs with your permissions. All of them.&lt;/p&gt;

&lt;p&gt;If it can read a file, it reads with your account. If it can run a shell command, that command can touch everything you can touch. Most of us set up these tools in five minutes, click "allow" a few times to make the prompts stop, and never look at the resulting config again.&lt;/p&gt;

&lt;p&gt;This week we audited our own.&lt;/p&gt;

&lt;h2&gt;
  
  
  The idea came from a 246,000-star repo
&lt;/h2&gt;

&lt;p&gt;We spent an evening reviewing &lt;a href="https://github.com/affaan-m/ecc" rel="noopener noreferrer"&gt;ECC&lt;/a&gt;, the viral agent-harness kit. Our verdict on installing it was no — for our setup, ~90 scripts executing on every tool call is more supply-chain surface than we'll accept, and its flagship learning system is a documented no-op on native Windows, which is what we run.&lt;/p&gt;

&lt;p&gt;But buried in it was one idea worth more than the whole repo: &lt;strong&gt;your agent tooling is part of your threat model.&lt;/strong&gt; The settings files, the hooks, the MCP server definitions, the permission allowlists — that's an attack surface, and almost nobody audits it.&lt;/p&gt;

&lt;p&gt;We ship a security scanner for a living. We had audited our web apps relentlessly. We had &lt;em&gt;never&lt;/em&gt; audited our own agent configs.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we found in our own house
&lt;/h2&gt;

&lt;p&gt;Five parallel audit passes over every harness config on our build machine. Findings, in descending order of embarrassment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;One repo's local settings contained &lt;code&gt;"Bash(*)"&lt;/code&gt;&lt;/strong&gt; — a blanket shell allow. Any prompt injection reaching a session in that project could run arbitrary commands with zero approval prompt. It had been sitting there since some long-forgotten session where someone (fine: we) allowed it to make a prompt go away.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Another repo's settings allowed unprompted &lt;code&gt;Read&lt;/code&gt; of the entire user profile&lt;/strong&gt; — SSH keys, token caches, browser profiles, password-manager stores. Plus a &lt;code&gt;python -c&lt;/code&gt; allow, which is arbitrary code execution wearing a lab coat.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OAuth token caches were readable &lt;em&gt;and writable&lt;/em&gt; by every local account&lt;/strong&gt; on the machine — inherited NTFS permissions nobody had ever looked at.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A global allow rule contradicted our own database doctrine&lt;/strong&gt; — granted once in some session, applying forever, in every project.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The one that made us laugh: when our agent tried to &lt;em&gt;fix&lt;/em&gt; the global permission file, the permission classifier &lt;strong&gt;blocked the agent from editing its own permissions&lt;/strong&gt;. Correct behavior. The guard guarded the guardian, and the fix went through a human paste instead.&lt;/p&gt;

&lt;p&gt;Everything above is closed now. Total time from "let's audit" to "all HIGHs fixed": about two hours. The &lt;code&gt;Bash(*)&lt;/code&gt; had been live for weeks.&lt;/p&gt;

&lt;h2&gt;
  
  
  We turned the checklist into a free tool
&lt;/h2&gt;

&lt;p&gt;The rule set from that audit is now a scanner you can run in your browser: &lt;strong&gt;&lt;a href="https://redcapra.com/agent-scan" rel="noopener noreferrer"&gt;redcapra.com/agent-scan&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Paste your &lt;code&gt;settings.json&lt;/code&gt;, &lt;code&gt;.mcp.json&lt;/code&gt;, or hooks config and it grades what it finds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;blanket and &lt;code&gt;sudo&lt;/code&gt; shell wildcards, arbitrary-exec allows (&lt;code&gt;python -c&lt;/code&gt;, &lt;code&gt;sh -c&lt;/code&gt;, &lt;code&gt;eval&lt;/code&gt;…), destructive-command allows&lt;/li&gt;
&lt;li&gt;profile-wide &lt;code&gt;Read&lt;/code&gt; grants and root-level &lt;code&gt;additionalDirectories&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;missing &lt;code&gt;.env&lt;/code&gt; read-deny nets&lt;/li&gt;
&lt;li&gt;unpinned auto-installing MCP servers (&lt;code&gt;npx -y something@latest&lt;/code&gt; executes whatever the registry serves next)&lt;/li&gt;
&lt;li&gt;credentials sitting inline in MCP/env config&lt;/li&gt;
&lt;li&gt;hook commands that interpolate tool input into shell strings, post to external hosts, or pipe downloads into &lt;code&gt;sh&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's a few hundred lines of plain JavaScript running entirely in the page. Nothing you paste is uploaded, logged, or stored — credential-shaped values are masked before they even appear in the findings text. No account, no email gate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three things to check tonight, no tool required
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Grep your settings files for &lt;code&gt;Bash(*)&lt;/code&gt;&lt;/strong&gt; — and for interpreter allows like &lt;code&gt;python -c&lt;/code&gt; or &lt;code&gt;sh -c&lt;/code&gt;, which are the same thing in disguise.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Look at every &lt;code&gt;npx -y&lt;/code&gt; in your MCP config.&lt;/strong&gt; Pin versions. &lt;code&gt;@latest&lt;/code&gt; means "whatever ships next runs on my machine automatically."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read your hooks like an attacker.&lt;/strong&gt; Anything interpolating &lt;code&gt;${...}&lt;/code&gt; tool input into a shell string is command injection waiting for a crafted filename. Anything posting to a non-localhost URL is an exfiltration channel — transcripts contain secrets more often than you think.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Your agent is probably fine. Its config might not be. Ours wasn't — and we do this for a living.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;RedCapra is a local-first security workbench: a real 47-check scan on your site, free, findings tracked in your browser. If the agent scanner is useful, &lt;a href="https://redcapra.com" rel="noopener noreferrer"&gt;the workbench&lt;/a&gt; is the same philosophy pointed at your web app.&lt;/em&gt;&lt;/p&gt;

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