<?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: vishalbharadwaj-alt</title>
    <description>The latest articles on DEV Community by vishalbharadwaj-alt (@vishalbharadwajalt).</description>
    <link>https://dev.to/vishalbharadwajalt</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%2F4191733%2F0231aa48-964e-4d83-9423-2496670cdfc9.png</url>
      <title>DEV Community: vishalbharadwaj-alt</title>
      <link>https://dev.to/vishalbharadwajalt</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vishalbharadwajalt"/>
    <language>en</language>
    <item>
      <title>SUNDER: using minimum cuts to heal the AI agent mesh</title>
      <dc:creator>vishalbharadwaj-alt</dc:creator>
      <pubDate>Sun, 18 Oct 2026 08:47:42 +0000</pubDate>
      <link>https://dev.to/vishalbharadwajalt/sunder-using-minimum-cuts-to-heal-the-ai-agent-mesh-1p51</link>
      <guid>https://dev.to/vishalbharadwajalt/sunder-using-minimum-cuts-to-heal-the-ai-agent-mesh-1p51</guid>
      <description>&lt;p&gt;&lt;em&gt;Graph Hacks: Context for AI Agents — Track 1: Agents That Act on Connected Data.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The graph is the new attack surface
&lt;/h2&gt;

&lt;p&gt;We started this project from a uncomfortable observation. In 2026, an enterprise&lt;br&gt;
doesn't run one AI agent — it runs dozens. A support agent, a sales agent, a&lt;br&gt;
research agent, an ops agent. Each one is wired to tools (ticket systems, email,&lt;br&gt;
browsers, shells, deploy CLIs), each tool holds credentials, and each credential&lt;br&gt;
grants access to resources. Increasingly that wiring lives in a graph: MCP&lt;br&gt;
servers, tool catalogs, IAM roles, agent-to-agent delegation.&lt;/p&gt;

&lt;p&gt;That's wonderful for capability and terrifying for security. An attacker doesn't&lt;br&gt;
need to steal a password anymore. They need to find a &lt;em&gt;path&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;untrusted-email ─FEEDS─▶ support-agent ─CAN_INVOKE─▶ ticket-tool
      ─USES─▶ jira-oauth ─GRANTS─▶ vault-role ─GRANTS─▶ prod-secrets-vault
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Six hops. No single compromised credential — just a chain of individually&lt;br&gt;
reasonable permissions. This is privilege escalation &lt;em&gt;as graph traversal&lt;/em&gt;, and it&lt;br&gt;
is the defining security problem of the agentic era.&lt;/p&gt;

&lt;p&gt;Most tools stop at &lt;em&gt;finding&lt;/em&gt; these paths. SUNDER's bet was: an agent that can&lt;br&gt;
read the graph should also &lt;strong&gt;act&lt;/strong&gt; on it — and act &lt;em&gt;optimally&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  The insight: don't hot-patch, min-cut
&lt;/h2&gt;

&lt;p&gt;The naive fix is to revoke every inbound edge to the crown jewel. That works, and&lt;br&gt;
it's also how you break production. The interesting question is: &lt;em&gt;what is the&lt;br&gt;
smallest set of permissions I can remove to disconnect the entire attacker&lt;br&gt;
surface?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That is the &lt;strong&gt;minimum s-t cut&lt;/strong&gt;. Wire a virtual super-source to every attacker&lt;br&gt;
entry point, a virtual super-sink to the crown jewel, and compute the min cut.&lt;br&gt;
By the &lt;strong&gt;max-flow / min-cut theorem&lt;/strong&gt;, the cut is provably minimal — and the&lt;br&gt;
max-flow value is a certificate that no smaller cut exists.&lt;/p&gt;

&lt;p&gt;Crucially, we gave every edge a &lt;strong&gt;cost&lt;/strong&gt; — the business impact of revoking it.&lt;br&gt;
Quarantining an untrusted data source is cheap (cost 1). Breaking an agent's&lt;br&gt;
ability to call a tool it needs is expensive (cost 5). Now the min cut minimises&lt;br&gt;
&lt;strong&gt;business impact&lt;/strong&gt;, not edge count. The agent isn't just finding &lt;em&gt;a&lt;/em&gt; fix; it's&lt;br&gt;
finding the &lt;em&gt;cheapest&lt;/em&gt; fix.&lt;/p&gt;

&lt;p&gt;And here's the payoff, straight from the demo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Minimum-cost cut: 3 edges, cost 3
  • revoke public-webpage  —[FEEDS]→ research-agent
  • revoke deploy-role     —[GRANTS]→ prod-secrets-vault
  • revoke jira-oauth      —[GRANTS]→ vault-role
(For comparison, the fewest-edge cut also uses 3 edges but costs 6.)
Verified: 0 attack paths remain. The crown jewel is sealed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both cuts sever the threat. SUNDER picked the one that rips out the fewest&lt;br&gt;
working integrations — because it optimised for cost, not just size.&lt;/p&gt;
&lt;h2&gt;
  
  
  Building it on FalkorDB
&lt;/h2&gt;

&lt;p&gt;The whole thing is a graph problem, so the agent lives on a graph. We modelled&lt;br&gt;
the enterprise as six node labels (&lt;code&gt;Agent&lt;/code&gt;, &lt;code&gt;Tool&lt;/code&gt;, &lt;code&gt;Credential&lt;/code&gt;, &lt;code&gt;Resource&lt;/code&gt;,&lt;br&gt;
&lt;code&gt;DataSource&lt;/code&gt;, &lt;code&gt;Human&lt;/code&gt;) and capability relationships (&lt;code&gt;FEEDS&lt;/code&gt;, &lt;code&gt;CAN_INVOKE&lt;/code&gt;,&lt;br&gt;
&lt;code&gt;USES&lt;/code&gt;, &lt;code&gt;GRANTS&lt;/code&gt;, &lt;code&gt;HAS_ACCESS&lt;/code&gt;, &lt;code&gt;DELEGATES&lt;/code&gt;, &lt;code&gt;CALLS&lt;/code&gt;, &lt;code&gt;HAS_CREDENTIAL&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;FalkorDB does the heavy lifting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;openCypher variable-length paths&lt;/strong&gt; enumerate the multi-hop attack chains
(&lt;code&gt;MATCH p = (s)-[*1..8]-&amp;gt;(t) WHERE all(x IN relationships(p) WHERE type(x) IN […])&lt;/code&gt;),&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;algo.pageRank&lt;/code&gt;&lt;/strong&gt; shows where privilege concentrates,&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;algo.betweenness&lt;/code&gt;&lt;/strong&gt; finds the brokers that many attack paths cross,&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;algo.labelPropagation&lt;/code&gt;&lt;/strong&gt; clusters tightly-coupled permissions so remediation
respects real boundaries.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One nice detail: we run &lt;strong&gt;embedded&lt;/strong&gt;. &lt;code&gt;falkordblite&lt;/code&gt; spins up a FalkorDB server&lt;br&gt;
in-process, so there is no Docker, no cloud, no network — the demo just runs.&lt;br&gt;
And because the embedded build doesn't register &lt;code&gt;algo.maxFlow&lt;/code&gt;, SUNDER ships a&lt;br&gt;
dependency-free &lt;strong&gt;Dinic max-flow&lt;/strong&gt; and feature-detects the built-in so it can&lt;br&gt;
corroborate the answer on a full deployment. Belt and braces.&lt;/p&gt;
&lt;h2&gt;
  
  
  One agent, three interfaces, eleven tools
&lt;/h2&gt;

&lt;p&gt;We exposed the same eleven tools three ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Python functions&lt;/strong&gt; — the direct API,&lt;/li&gt;
&lt;li&gt;an &lt;strong&gt;MCP server&lt;/strong&gt; — so &lt;em&gt;any&lt;/em&gt; MCP client can reason over the mesh,&lt;/li&gt;
&lt;li&gt;a &lt;strong&gt;FastAPI + SSE&lt;/strong&gt; endpoint that streams the agent's reasoning to a web UI.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The agent itself has two planners: a &lt;code&gt;LoopPlanner&lt;/code&gt; that runs observe -&amp;gt; decide -&amp;gt; act&lt;br&gt;
(the model sees each real tool result before choosing the next tool, inside guardrails:&lt;br&gt;
the cut always comes from &lt;code&gt;compute_min_cut&lt;/code&gt;, &lt;code&gt;apply_cut&lt;/code&gt; needs a prior &lt;code&gt;simulate_cut&lt;/code&gt;, and&lt;br&gt;
the run always ends verified), and a &lt;code&gt;ScriptedPlanner&lt;/code&gt; that is deterministic and offline-safe. The reasoning lives in the open:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[1] describe_mesh         38 nodes, 42 edges across 6 labels
[2] find_entry_points     5 attacker-controlled entry points
[3] all_attack_paths      11 multi-hop attack paths, shortest is 3 hops
[5] find_choke_points     support-agent, research-agent, jira-oauth, …
[7] compute_min_cut       minimum-cost cut: 3 edges, cost 3
[8] simulate_cut          11 -&amp;gt; 0 attack paths
[9] apply_cut             revoked 3 permission edges
[10] verify               VERIFIED: 0 attack paths remain
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the guardrails a security agent needs: it &lt;strong&gt;simulates before it acts&lt;/strong&gt;&lt;br&gt;
(&lt;code&gt;simulate_cut&lt;/code&gt;) and &lt;strong&gt;proves the result&lt;/strong&gt; (&lt;code&gt;verify&lt;/code&gt;). A remediation agent that&lt;br&gt;
can't demonstrate its fix didn't work isn't trustworthy; a remediation agent that&lt;br&gt;
&lt;em&gt;cuts the graph&lt;/em&gt; without a proof is a liability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this is the right shape for "Agents That Act on Connected Data"
&lt;/h2&gt;

&lt;p&gt;The track asks for an agent that doesn't just read a graph but &lt;em&gt;does something&lt;/em&gt;&lt;br&gt;
with it. SUNDER reads (paths, centrality, communities), reasons (min-cost cut),&lt;br&gt;
and writes (revokes edges, then re-queries to confirm). The graph is not a&lt;br&gt;
retrieval scratchpad — it is the &lt;strong&gt;world the agent changes&lt;/strong&gt;, and every change is&lt;br&gt;
justified by a graph computation.&lt;/p&gt;

&lt;p&gt;It's also, quietly, the most useful security tool I've built: a way to answer&lt;br&gt;
"given this tangled agent mesh, what is the &lt;em&gt;minimum&lt;/em&gt; thing I must break to make&lt;br&gt;
it safe?" — with a proof attached.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;conda create &lt;span class="nt"&gt;-n&lt;/span&gt; sunder &lt;span class="nv"&gt;python&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3.12 &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; conda activate sunder
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
python &lt;span class="nt"&gt;-m&lt;/span&gt; sunder seed &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; python &lt;span class="nt"&gt;-m&lt;/span&gt; sunder demo     &lt;span class="c"&gt;# offline, no Docker&lt;/span&gt;
python &lt;span class="nt"&gt;-m&lt;/span&gt; sunder serve                             &lt;span class="c"&gt;# web UI with live animation&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Attack simulation&lt;/strong&gt; with an &lt;em&gt;evolving adversary&lt;/em&gt; that re-routes after each
cut, turning remediation into a game-theoretic loop.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blast-radius budgeting&lt;/strong&gt;: constrain the cut to a budget and return the best
achievable coverage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;More ingesters.&lt;/strong&gt; MCP client configs are done (&lt;code&gt;sunder harden&lt;/code&gt;: patched
configs plus a proof from re-ingesting them); IAM exports and live MCP server
introspection are next, so the graph reflects production, not a demo fixture.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The agent mesh is going to keep growing. The least we can do is give it a&lt;br&gt;
graph-native immune system — one that heals by the minimum cut.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Built with FalkorDB (embedded), an MCP tool surface, and a dependency-free&lt;br&gt;
max-flow/min-cut engine.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>cybersecurity</category>
      <category>security</category>
    </item>
  </channel>
</rss>
