<?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: Shorya Sethia</title>
    <description>The latest articles on DEV Community by Shorya Sethia (@shoryasethia).</description>
    <link>https://dev.to/shoryasethia</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%2F4024551%2F95a7240a-293e-40da-b604-1ecbbeb382aa.jpg</url>
      <title>DEV Community: Shorya Sethia</title>
      <link>https://dev.to/shoryasethia</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shoryasethia"/>
    <language>en</language>
    <item>
      <title>Most products still assume a human is clicking.</title>
      <dc:creator>Shorya Sethia</dc:creator>
      <pubDate>Sat, 11 Jul 2026 23:45:52 +0000</pubDate>
      <link>https://dev.to/shoryasethia/most-products-still-assume-a-human-is-clicking-2854</link>
      <guid>https://dev.to/shoryasethia/most-products-still-assume-a-human-is-clicking-2854</guid>
      <description>&lt;p&gt;Buttons. Forms. Wizards. Session auth. Implicit guardrails baked into the UI.&lt;/p&gt;

&lt;p&gt;That works until an AI agent needs to do real work in the same product.&lt;/p&gt;

&lt;p&gt;Then teams usually do one of two things to allow AI agents:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hand the agent an API key&lt;/li&gt;
&lt;li&gt;Wrap the product in a chatbot and hope the model behaves&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Neither solves the hard part.&lt;br&gt;
The hard part is not access. It is execution.&lt;/p&gt;

&lt;p&gt;Can this caller read that record?&lt;br&gt;
Can it update this field?&lt;br&gt;
Does this action need a person to approve it first?&lt;br&gt;
If something goes wrong, can you reconstruct what happened?&lt;/p&gt;

&lt;p&gt;An API key answers none of that.&lt;br&gt;
It only answers: "can this thing reach my backend?"&lt;/p&gt;

&lt;p&gt;That is why we keep saying agents need gates, not keys.&lt;/p&gt;

&lt;p&gt;A gate is a declared rule:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what actions exist&lt;/li&gt;
&lt;li&gt;who can invoke them&lt;/li&gt;
&lt;li&gt;when consent is required&lt;/li&gt;
&lt;li&gt;what gets logged&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://ductai.vercel.app/?utm_source=dev-to&amp;amp;utm_medium=social&amp;amp;utm_caimpaign=blog-accountable-agent" rel="noopener noreferrer"&gt;Duct&lt;/a&gt; was dogfooded this on **Whistler **with two callers on the same policy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a human using the embedded Shell&lt;/li&gt;
&lt;li&gt;a third-party agent calling the same actions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcwxjn5e6ml40m9uodi74.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcwxjn5e6ml40m9uodi74.png" alt="Whistler x Duct" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Same manifest. Same permission checks. Same approval on side effects. Same audit trail.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No master API key for either.&lt;/p&gt;

&lt;p&gt;If you are adding agents to a product that was built for humans, the question is not "do we expose an API?"&lt;/p&gt;

&lt;p&gt;It is: "do we have a &lt;strong&gt;governed execution layer&lt;/strong&gt; for every caller?"&lt;/p&gt;

&lt;p&gt;I wrote up how we built that layer, with demos: &lt;a href="https://ductai.vercel.app/blog/accountable-agent?utm_source=dev-to-post``&amp;amp;utm_medium=social&amp;amp;utm_campaign=blog-accountable-agent" rel="noopener noreferrer"&gt;blog/accountable-agents&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
      <category>agents</category>
    </item>
    <item>
      <title>AI agents can now click "delete" in your product. Who's checking?</title>
      <dc:creator>Shorya Sethia</dc:creator>
      <pubDate>Fri, 10 Jul 2026 22:14:09 +0000</pubDate>
      <link>https://dev.to/shoryasethia/ai-agents-can-now-click-delete-in-your-product-whos-checking-l30</link>
      <guid>https://dev.to/shoryasethia/ai-agents-can-now-click-delete-in-your-product-whos-checking-l30</guid>
      <description>&lt;p&gt;If a human logs into your product, you already have auth, roles, and audit logs. If an AI agent calls the same endpoints, what do you have?&lt;/p&gt;

&lt;p&gt;For most products, the honest answer is: an API key and hope.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The gap nobody built for&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;We spent a decade building permission systems for humans clicking buttons. RBAC, SSO, audit trails, all of it assumes a person is on the other end, moving at human speed, making one action at a time.&lt;/p&gt;

&lt;p&gt;Agents break every one of those assumptions. They call your API in bursts, chain actions together, and increasingly use the same session across many requests without a human watching each one. Most teams patch this with an if/else check buried in a route handler. That works until you need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;version what an agent is allowed to do without redeploying&lt;/li&gt;
&lt;li&gt;pause a destructive action for human approval mid-flow&lt;/li&gt;
&lt;li&gt;revoke access to one agent without touching everyone else&lt;/li&gt;
&lt;li&gt;prove after the fact exactly what happened and why it was allowed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An if/else can't do any of that. It's not a permissions system, it's a guess that happens to compile.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What I built instead&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://ductai.vercel.app/?utm_source=dev-to-post&amp;amp;utm_medium=social" rel="noopener noreferrer"&gt;Duct&lt;/a&gt; is a manifest-driven action enforcement layer that sits between your product and whoever is calling it, human or agent or another product. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7lv1lbwz0k98oj3qjmpb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7lv1lbwz0k98oj3qjmpb.png" alt="Duct" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Three primitives:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;duct.config.ts&lt;/strong&gt; — a manifest that declares every action your product exposes, what it does, and what it requires to run. This is the single source of truth, not scattered checks across your codebase.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shell&lt;/strong&gt; — the surface a human uses. Same actions, same manifest, but rendered for a person.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Invoke API&lt;/strong&gt; — the surface an agent uses. Same actions, same manifest, enforced the same way.&lt;/p&gt;

&lt;p&gt;The part that took the longest to get right is the token model. There are two tokens, not one:&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;delegation token&lt;/strong&gt; that says "this agent is allowed to act on this account, generally, for this long." Longer-lived, coarse-grained.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;per-action approval token&lt;/strong&gt; that says "this specific side-effecting action is approved, right now." Short TTL, single use, required only for actions the manifest marks as sensitive.&lt;/p&gt;

&lt;p&gt;Splitting these apart is what makes revocation and human-in-the-loop approval actually work. You can kill an agent's delegation token instantly without touching in-flight actions that already got their per-action approval. And you can force a human checkpoint on a refund or a delete without slowing down the 95% of actions that don't need one.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The hard part wasn't the happy path&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Anyone can build this for the easy case: one human, one agent, one session. The interesting failures show up at the edges. An agent with browser or computer-use tools can technically forward an approval URL, but the proof of approval (a session-bound cookie) only gets issued at the moment a human actually loads that page. An API-only caller can't fake that, even if it has the URL. That distinction, between an agent forwarding a link and a human actually completing an approval, is most of the design work.&lt;/p&gt;

&lt;p&gt;There's also a case I couldn't solve: a fully anonymous, agent-only product with no human and no KYC anywhere in the chain. For that, all you get are deterministic policy caps. No amount of clever token design gets you accountability if there was never an identity to begin with. Worth knowing where the line is instead of pretending otherwise.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where this leaves us&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Duct isn't a diagram. It's a working enforcement layer, built specifically because none of the existing auth or agent tooling answers "who approved that" for actions, not just credentials.&lt;/p&gt;

&lt;p&gt;If you're building a product where agents call in and you don't yet have a real answer to that question, I'd genuinely like to hear how you're handling it, or if you want to try Duct on what you're building.&lt;/p&gt;

&lt;p&gt;Highly recommend to checkout &lt;a href="http://ductai.vercel.app/?utm_source=dev-to-post&amp;amp;utm_medium=social" rel="noopener noreferrer"&gt;Duct&lt;/a&gt;.&lt;/p&gt;

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