<?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: Broskidev</title>
    <description>The latest articles on DEV Community by Broskidev (@broskigx).</description>
    <link>https://dev.to/broskigx</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%2F4096551%2F46a39800-ab3c-423f-a6d5-a90d463ea955.png</url>
      <title>DEV Community: Broskidev</title>
      <link>https://dev.to/broskigx</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/broskigx"/>
    <language>en</language>
    <item>
      <title>I built an autonomous multi-agent AI pentester — and why it's not another GPT wrapper</title>
      <dc:creator>Broskidev</dc:creator>
      <pubDate>Thu, 27 Aug 2026 02:52:12 +0000</pubDate>
      <link>https://dev.to/broskigx/i-built-an-autonomous-multi-agent-ai-pentester-and-why-its-not-another-gpt-wrapper-1l09</link>
      <guid>https://dev.to/broskigx/i-built-an-autonomous-multi-agent-ai-pentester-and-why-its-not-another-gpt-wrapper-1l09</guid>
      <description>&lt;p&gt;Most "AI pentester" projects are a single LLM in a while-loop with a shell. You&lt;br&gt;
give it a target, it runs commands until it decides it found something. That's&lt;br&gt;
how you get &lt;strong&gt;confident nonsense&lt;/strong&gt; — a model that writes a beautiful vulnerability&lt;br&gt;
report for a bug that doesn't exist.&lt;/p&gt;

&lt;p&gt;I wanted the opposite: an engine where a finding has to be &lt;em&gt;earned&lt;/em&gt;. So I built&lt;br&gt;
&lt;a href="https://github.com/Broskigx/Oihk-pentesting" rel="noopener noreferrer"&gt;OIHK&lt;/a&gt; — an autonomous, multi-agent&lt;br&gt;
AI penetration-testing engine. It's open source (MIT) and runs locally.&lt;/p&gt;

&lt;h2&gt;
  
  
  Not one model in a loop — a team of agents
&lt;/h2&gt;

&lt;p&gt;OIHK is a &lt;strong&gt;multi-agent engine&lt;/strong&gt;. A root planner delegates to specialist agents —&lt;br&gt;
recon, discovery, validation, reporting — that all share two things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a &lt;strong&gt;versioned scan plan&lt;/strong&gt; (optimistic concurrency, revision history, resume), and&lt;/li&gt;
&lt;li&gt;an &lt;strong&gt;evidence ledger&lt;/strong&gt; (immutable execution records).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Agents don't coordinate by vibes in a chat log. They claim explicit plan steps,&lt;br&gt;
attach real evidence, and update state through a revisioned store. The root can't&lt;br&gt;
close a run while critical work is still open.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rule I care about most: no evidence, no finding
&lt;/h2&gt;

&lt;p&gt;Here's the design decision the whole thing is built around:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An LLM writing a convincing PoC string is &lt;strong&gt;not&lt;/strong&gt; a finding.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A finding requires a &lt;strong&gt;real, successful, governed tool execution&lt;/strong&gt; &lt;em&gt;and&lt;/em&gt; a&lt;br&gt;
&lt;strong&gt;separate validation record&lt;/strong&gt;. Only a validation agent can turn evidence into a&lt;br&gt;
finding. If there's no execution record and no independent validation, it never&lt;br&gt;
becomes a finding — no matter how confident the model sounds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Safety enforced in code, not prompts
&lt;/h2&gt;

&lt;p&gt;Offensive tools + autonomous agents is a scary combo if "be careful" is just a&lt;br&gt;
line in a prompt. In OIHK the guardrails are actual code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PASSIVE mode is a policy layer&lt;/strong&gt;, not an instruction. Active tools are rejected
even if the agent tries to route them through the generic shell.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scope is exact.&lt;/strong&gt; Declaring &lt;code&gt;example.com&lt;/code&gt; doesn't authorize its subdomains or
resolved IPs. Declared hosts are resolved once and DNS-pinned for the whole run.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Egress fails closed.&lt;/strong&gt; The declared scope is compiled into a netfilter
allowlist inside the sandbox's own per-run network namespace. On platforms that
can't guarantee it, startup &lt;strong&gt;aborts&lt;/strong&gt; instead of pretending to be isolated.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hardened sandbox:&lt;/strong&gt; read-only rootfs, dropped capabilities, no-new-privileges,
non-root, no sudo surface.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Swap the model, keep the engine
&lt;/h2&gt;

&lt;p&gt;OIHK is provider-agnostic. Any OpenAI-compatible endpoint works (LM Studio by&lt;br&gt;
default), with per-role model routing and no hardcoded provider. You can run a&lt;br&gt;
strong reasoning model as the planner and a fast one for the specialists.&lt;/p&gt;

&lt;h2&gt;
  
  
  It's also its own benchmark
&lt;/h2&gt;

&lt;p&gt;This is my favorite part. OIHK doubles as an &lt;strong&gt;evaluation environment&lt;/strong&gt;: it runs&lt;br&gt;
the &lt;em&gt;real&lt;/em&gt; engine against 16 local, deliberately vulnerable scenarios and scores&lt;br&gt;
the model &lt;strong&gt;programmatically&lt;/strong&gt; — never by asking a model to grade itself.&lt;/p&gt;

&lt;p&gt;There's a deterministic offline &lt;code&gt;mock&lt;/code&gt; solver for CI and demos:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

bash
uv run oihk eval run-all --model mock
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

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