<?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: One Man Fleet</title>
    <description>The latest articles on DEV Community by One Man Fleet (@1manfleet).</description>
    <link>https://dev.to/1manfleet</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3980259%2F3a904d9b-0d6e-421e-8980-4acbc1b91683.png</url>
      <title>DEV Community: One Man Fleet</title>
      <link>https://dev.to/1manfleet</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/1manfleet"/>
    <language>en</language>
    <item>
      <title>Passport – issue revocable, Secure Enclave-signed permissions to AI agents</title>
      <dc:creator>One Man Fleet</dc:creator>
      <pubDate>Fri, 12 Jun 2026 13:24:41 +0000</pubDate>
      <link>https://dev.to/1manfleet/passport-issue-revocable-secure-enclave-signed-permissions-to-ai-agents-16lk</link>
      <guid>https://dev.to/1manfleet/passport-issue-revocable-secure-enclave-signed-permissions-to-ai-agents-16lk</guid>
      <description>&lt;p&gt;I built Passport, a free iOS/macOS app that lets a human issue signed, scoped, time-bounded credentials to AI agents — and revoke them instantly.&lt;/p&gt;

&lt;p&gt;The problem: when an agent acts on your behalf (books, buys, emails), the receiving service can't tell whether a human authorized that specific agent to do that specific thing. Today it's raw API keys (no scoping, no audit trail, no kill switch) or nothing.&lt;/p&gt;

&lt;p&gt;A Passport credential is a standard ES256 JWT that asserts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;which agent this is (human-readable name)&lt;/li&gt;
&lt;li&gt;what it may do (scopes like &lt;code&gt;browse&lt;/code&gt;, &lt;code&gt;purchase:general&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;when the grant expires&lt;/li&gt;
&lt;li&gt;the issuing public key, embedded in the header&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The private key is generated in the device's Secure Enclave and never leaves it; every issuance requires Face ID, so each credential maps to an explicit human decision.&lt;/p&gt;

&lt;p&gt;Verification is deliberately boring: any JWT library can verify the token offline against the embedded key. There's also a hosted endpoint (Cloudflare Worker) that does signature + expiry + scope + revocation in one POST:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST https://passport-verify.passport-app.workers.dev/verify
{"token": "&amp;lt;jwt&amp;gt;", "scope": "purchase:general"}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Revocation went live today: revoke a credential in the app and the next verify returns 401 with "Token has been revoked by its owner" (KV-backed list, also queryable at &lt;code&gt;GET /revoked?jti=&lt;/code&gt;). I tested the full loop on a real credential in production. If you verify offline instead, you can poll the revocation endpoint or simply rely on short expiry times.&lt;/p&gt;

&lt;p&gt;The format choice is intentional — I wanted something existing HTTP middleware could accept with one &lt;code&gt;if&lt;/code&gt; statement, not a new protocol. Visa TAP and Google AP2 are converging on the same three-leg shape (human grants → agent presents → merchant verifies) for payments; this is that pattern as a small open building block.&lt;/p&gt;

&lt;p&gt;App is free on the App Store (iOS + macOS, native). Docs with drop-in Node/Python/cURL snippets: &lt;a href="https://passport-landing.pages.dev" rel="noopener noreferrer"&gt;https://passport-landing.pages.dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Curious how others handling agent auth are thinking about scoped, revocable delegation vs. just passing API keys around.&lt;/p&gt;

&lt;p&gt;Thank you! Feel free to ask questions!&lt;/p&gt;

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