<?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: Grantor</title>
    <description>The latest articles on DEV Community by Grantor (@grantor).</description>
    <link>https://dev.to/grantor</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%2F4088755%2F2922eac3-ea94-4429-89a6-8e22cf470d4f.png</url>
      <title>DEV Community: Grantor</title>
      <link>https://dev.to/grantor</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/grantor"/>
    <language>en</language>
    <item>
      <title>Give your AI sub-agent a budget, not your keys</title>
      <dc:creator>Grantor</dc:creator>
      <pubDate>Fri, 21 Aug 2026 19:06:18 +0000</pubDate>
      <link>https://dev.to/grantor/give-your-ai-sub-agent-a-budget-not-your-keys-2e7h</link>
      <guid>https://dev.to/grantor/give-your-ai-sub-agent-a-budget-not-your-keys-2e7h</guid>
      <description>&lt;p&gt;Spawn a sub-agent in CrewAI, LangGraph, AutoGen, or a Claude sub-agent&lt;br&gt;
setup and check what it actually holds: your credentials. The parent's&lt;br&gt;
keys, at full scope, forever. The throwaway agent you created to summarize&lt;br&gt;
three PDFs can call every tool your orchestrator can, and the only&lt;br&gt;
"revocation" is rotating keys everywhere at once.&lt;/p&gt;

&lt;p&gt;We accept this because handing a child &lt;em&gt;less&lt;/em&gt; than everything has been&lt;br&gt;
genuinely hard: OAuth scopes need an authorization server someone runs;&lt;br&gt;
role systems need an admin; API keys don't subdivide. So the ecosystem&lt;br&gt;
quietly standardized on "copy the parent's environment" and moved on.&lt;/p&gt;

&lt;p&gt;Here's a different shape, as an MCP server you run locally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx &lt;span class="nt"&gt;-y&lt;/span&gt; @grantor/mcp serve
&lt;span class="c"&gt;# or wire it into Claude Code:&lt;/span&gt;
claude mcp add grantor-mcp &lt;span class="nt"&gt;--&lt;/span&gt; npx &lt;span class="nt"&gt;-y&lt;/span&gt; @grantor/mcp serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That gives any MCP-speaking framework five tools. The whole model fits in&lt;br&gt;
one transcript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;grant    {tools: ["search","fetch"], max_uses: 20, ttl_secs: 3600}
         → {child_id: "…", sub: "…"}          # a bounded child identity

check    {child_id, tool: "search"}
         → {allow: true, remaining_uses: 19}   # gate EVERY action on this

check    {child_id, tool: "write"}
         → {allow: false, code: "CapabilityDenied"}   # not granted → denied

delegate {parent: child_id, tools: ["search"], max_uses: 5}
         → {child_id: "…"}                     # a narrower grand-child

revoke   {child_id}
         → revoked                             # authority withdrawn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The interesting properties are in what you &lt;em&gt;can't&lt;/em&gt; do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A child can never widen its slice.&lt;/strong&gt; Asking &lt;code&gt;delegate&lt;/code&gt; for a tool the
parent doesn't hold is refused before anything is signed. Asking for
more uses or a longer expiry silently clamps to the parent's bound.
This isn't a policy file the framework consults — the delegation chain
is cryptographically signed link by link, and verification re-checks the
narrowing math on every &lt;code&gt;check&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Budgets actually run out.&lt;/strong&gt; &lt;code&gt;max_uses: 20&lt;/code&gt; means the 21st &lt;code&gt;check&lt;/code&gt; is
denied with &lt;code&gt;UsesExhausted&lt;/code&gt;, not logged-and-allowed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Revocation is real.&lt;/strong&gt; In your own tenant, &lt;code&gt;revoke&lt;/code&gt; bumps a revocation
epoch on a public smart contract; every capability in that cohort fails
its next &lt;code&gt;check&lt;/code&gt; no matter which process holds it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the part that makes this different from every "policy engine" you've&lt;br&gt;
seen: &lt;strong&gt;there is no server.&lt;/strong&gt; No authorization service, no policy backend,&lt;br&gt;
no vendor API in the hot path. Authority anchors to a public registry&lt;br&gt;
contract on Base; verification is a local computation plus one &lt;code&gt;eth_call&lt;/code&gt;&lt;br&gt;
that any RPC provider can serve. The broker runs on your machine, next to&lt;br&gt;
the framework it guards, and holds the child keys so your agents never see&lt;br&gt;
key material at all.&lt;/p&gt;

&lt;p&gt;The zero-setup run above works because the package ships pointed at a&lt;br&gt;
live shared sandbox tenant on the production registry — real chain, real&lt;br&gt;
verification, publish-on-purpose demo key that controls nothing outside&lt;br&gt;
the sandbox. Honest limits: it's an unaudited developer preview, the&lt;br&gt;
sandbox broker self-issues its anti-replay challenge (it's holder and&lt;br&gt;
verifier in one process), and use-metering is local to the broker.&lt;/p&gt;

&lt;p&gt;Production is one contract call away (USDC on Base, no signup — your&lt;br&gt;
agent can even read the machine-readable onboarding manifest and do it&lt;br&gt;
itself). Docs: &lt;a href="https://chaingrantor.com/docs/guide/mcp-broker" rel="noopener noreferrer"&gt;https://chaingrantor.com/docs/guide/mcp-broker&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCP standardized what agents can&lt;br&gt;
call. A2A standardized how they talk. Nobody standardized what they're&lt;br&gt;
allowed to do — that's the layer this fills.&lt;/strong&gt;&lt;/p&gt;

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