<?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: Arun KT</title>
    <description>The latest articles on DEV Community by Arun KT (@arun_kt_bb670b3a571f5efd8).</description>
    <link>https://dev.to/arun_kt_bb670b3a571f5efd8</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%2F3835802%2Fd11b76b7-f221-4cc5-bfdf-7378a6cd99d4.png</url>
      <title>DEV Community: Arun KT</title>
      <link>https://dev.to/arun_kt_bb670b3a571f5efd8</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/arun_kt_bb670b3a571f5efd8"/>
    <language>en</language>
    <item>
      <title>AI agents choose blindly. I built an open trust layer to fix that.</title>
      <dc:creator>Arun KT</dc:creator>
      <pubDate>Sat, 13 Jun 2026 16:08:48 +0000</pubDate>
      <link>https://dev.to/arun_kt_bb670b3a571f5efd8/ai-agents-choose-blindly-i-built-an-open-trust-layer-to-fix-that-6b0</link>
      <guid>https://dev.to/arun_kt_bb670b3a571f5efd8/ai-agents-choose-blindly-i-built-an-open-trust-layer-to-fix-that-6b0</guid>
      <description>&lt;p&gt;Your AI agent makes choices you never see — which API to call, which dataset to pull, which &lt;em&gt;other&lt;/em&gt; agent to hand a subtask to. Right now it makes them blind.&lt;/p&gt;

&lt;p&gt;It can't tell a reliable provider from a scam. It can't carry a track record from one task to the next. And it has no way to know whether a recommendation sitting in its context window is organic or something a vendor paid to put there. Humans handle trust with reputation, reviews, brand, gut feel. An agent can do none of that — it's perfectly, silently steerable by whatever text reaches it.&lt;/p&gt;

&lt;p&gt;That gap gets worse every month as agents start &lt;em&gt;transacting&lt;/em&gt; with each other — MCP, A2A, agent payments. So I built &lt;strong&gt;ERABI&lt;/strong&gt;: an open, cryptographically auditable reputation and discovery layer for AI agents. It's live, Apache-2.0, and an agent can join in one command.&lt;/p&gt;

&lt;h2&gt;
  
  
  The loop
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;register   → an Ed25519 identity the agent owns (no account, no signup)
discover   → find providers ranked by reputation, never by payment
intent     → fire a "moment of choice"; get organic + clearly-labeled
             sponsored candidates, each with a signed disclosure
report_outcome / confirm_outcome
           → both sides sign; the outcome lands on a hash-chained ledger
my_reputation / my_earnings
           → a public, recomputable track record
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two invariants do the heavy lifting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Organic rankings can't be bought.&lt;/strong&gt; Reputation comes &lt;em&gt;only&lt;/em&gt; from dual-signed outcomes — both parties cryptographically confirm what happened. No single-sided reviews, no pay-to-rank.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Every paid placement is labeled and inspectable.&lt;/strong&gt; Sponsored results carry a signed &lt;code&gt;DisclosureRecord&lt;/code&gt; you can fetch and verify in your browser. Paid influence over agents is coming either way; this version is signed, capped, and auditable instead of hidden in a system prompt.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it in 60 seconds
&lt;/h2&gt;

&lt;p&gt;It's an MCP server, zero-config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"erabi"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"erabi-mcp"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Call &lt;code&gt;register&lt;/code&gt;, and you get back a permalink to your agent's live public page — reputation, earnings, and every dual-signed event on the ledger. Or just watch the network move: &lt;strong&gt;&lt;a href="https://erabi-explorer.vercel.app" rel="noopener noreferrer"&gt;https://erabi-explorer.vercel.app&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Under the hood
&lt;/h2&gt;

&lt;p&gt;TypeScript monorepo. Ed25519-signed envelopes over RFC 8785 canonical JSON (so signatures are reproducible across languages). A GSP auction where reputation acts as the quality score. A dual-signed, hash-chained outcome ledger with holdback windows and an anomaly engine. MCP server + TypeScript/Python SDKs. ~180 tests. Every reputation score is recomputable from public evidence — the explorer lets you verify a disclosure's signature in-browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest part — read this before you assume
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No real money moves.&lt;/strong&gt; The economy is &lt;em&gt;ledger-only&lt;/em&gt; today: every auction and signature is a real protocol event, but the dollar amounts are units of account, not currency. Ledger balances will never convert to money. Payment rails (x402/AP2) are pluggable and come later; when they do, pre-rail reputation is marked as a separate era. The rules are declared before anyone can game them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It's early.&lt;/strong&gt; I'm one person; the network is freshly launched. What's real today is the &lt;em&gt;mechanism&lt;/em&gt; — identity, signed disclosures, dual-signed settlement, recomputable reputation — running live and verifiable.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why I think this matters
&lt;/h2&gt;

&lt;p&gt;Whatever the agent ecosystem becomes, agents will need to answer "can I trust this counterparty?" &lt;em&gt;programmatically, at machine speed, without a human in the loop.&lt;/em&gt; That's a trust primitive that doesn't exist yet, and it can't be borrowed from the human web. ERABI is my attempt at it, in the open, where every claim is falsifiable from public data.&lt;/p&gt;

&lt;p&gt;It's Apache-2.0. Tear it apart:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repo: &lt;a href="https://github.com/HMAKT99/Erabi" rel="noopener noreferrer"&gt;https://github.com/HMAKT99/Erabi&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Live network: &lt;a href="https://erabi-explorer.vercel.app" rel="noopener noreferrer"&gt;https://erabi-explorer.vercel.app&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>typescript</category>
      <category>mcp</category>
    </item>
    <item>
      <title>Apple wants $199 for a Touch ID keyboard. I shipped a free one in Swift!</title>
      <dc:creator>Arun KT</dc:creator>
      <pubDate>Mon, 27 Apr 2026 17:21:06 +0000</pubDate>
      <link>https://dev.to/arun_kt_bb670b3a571f5efd8/apple-wants-199-for-a-touch-id-keyboard-i-shipped-a-free-one-in-swift-16ni</link>
      <guid>https://dev.to/arun_kt_bb670b3a571f5efd8/apple-wants-199-for-a-touch-id-keyboard-i-shipped-a-free-one-in-swift-16ni</guid>
      <description>&lt;p&gt;I have a Mac mini.&lt;/p&gt;

&lt;p&gt;Apple's official path to fingerprint authentication on a Mac mini is buying their $199 Magic Keyboard with Touch ID. The new MacBook Neo charges $100 extra for the variant with the sensor. Mac Studio and Mac Pro never ship with one at all.&lt;/p&gt;

&lt;p&gt;The fingerprint sensor I actually use 50 times a day already lives in the phone in my pocket.&lt;/p&gt;

&lt;p&gt;So I spent two weekends building &lt;strong&gt;TouchBridge&lt;/strong&gt; — an open-source macOS daemon and PAM module that lets any phone, watch, or browser act as Touch ID for any Mac.&lt;/p&gt;

&lt;p&gt;This post is the technical write-up. Repo: &lt;a href="https://github.com/HMAKT99/UnTouchID" rel="noopener noreferrer"&gt;github.com/HMAKT99/UnTouchID&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it actually does
&lt;/h2&gt;

&lt;p&gt;After a one-line install, this just works:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; ~/.cache
TouchBridge: check your phone…
&lt;span class="o"&gt;[&lt;/span&gt;phone vibrates, you press the sensor, the prompt clears]
&lt;span class="nv"&gt;$ &lt;/span&gt;_
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;sudo&lt;/code&gt; got authenticated by the Secure Enclave on my iPhone over local Bluetooth. No password. No cloud round-trip. No Apple ID. The same flow works for the screensaver unlock and (soon) the App Store / System Settings prompts that go through &lt;code&gt;Authorization Services&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If my phone is dead, out of range, or refuses biometric, the PAM stack falls through to the normal password prompt. You're never locked out.&lt;/p&gt;

&lt;h2&gt;
  
  
  The architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flowchart LR
    A[sudo / loginwindow] --&amp;gt; B[/etc/pam.d]
    B --&amp;gt; C[pam_touchbridge.so]
    C -- Unix socket --&amp;gt; D[touchbridged]
    D &amp;lt;-- BLE: ECDH + AES-256-GCM --&amp;gt; E[TouchBridge app]
    E --&amp;gt; F[Secure Enclave / StrongBox]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;pam_touchbridge.so&lt;/code&gt; — a tiny PAM module written in C. Drop a single line into &lt;code&gt;/etc/pam.d/sudo&lt;/code&gt; and &lt;code&gt;sudo&lt;/code&gt; now consults it before falling through to the password module.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;touchbridged&lt;/code&gt; — a Swift launchd daemon that owns the BLE connection, the paired-device list, and the audit log. PAM talks to it over a Unix socket.&lt;/li&gt;
&lt;li&gt;Companion apps — Swift on iOS / Apple Watch, Kotlin on Android / Wear OS, and a JavaScript fallback for any browser that supports WebAuthn. Each one holds a non-extractable ECDSA P-256 keypair in secure hardware.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The handshake, end to end
&lt;/h2&gt;

&lt;p&gt;When you type &lt;code&gt;sudo&lt;/code&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;PAM invokes &lt;code&gt;pam_sm_authenticate&lt;/code&gt; in &lt;code&gt;pam_touchbridge.so&lt;/code&gt;. The module connects to the daemon's Unix socket and asks: anyone paired and online?&lt;/li&gt;
&lt;li&gt;The daemon picks the highest-priority paired device (your iPhone first, watch as fallback) and generates a fresh 32-byte cryptographic nonce.&lt;/li&gt;
&lt;li&gt;It encrypts the nonce under a session key derived via ECDH-on-pair (rotated periodically) with AES-256-GCM, then sends it to the device over BLE.&lt;/li&gt;
&lt;li&gt;The companion app shows a system biometric prompt — Face ID, Touch ID, fingerprint sensor, whatever the device has.&lt;/li&gt;
&lt;li&gt;On approval, the device signs the nonce with its non-extractable ECDSA P-256 key in the Secure Enclave or StrongBox / TEE Keystore. The private key never leaves secure hardware.&lt;/li&gt;
&lt;li&gt;The signed nonce comes back over the same encrypted BLE channel. The daemon verifies the signature against the public key it cached during pairing.&lt;/li&gt;
&lt;li&gt;If verification passes, the daemon writes a one-line entry to &lt;code&gt;~/.touchbridge/audit.log&lt;/code&gt; and returns &lt;code&gt;PAM_SUCCESS&lt;/code&gt;. PAM lets &lt;code&gt;sudo&lt;/code&gt; proceed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;End-to-end latency on a recent iPhone over BLE: 80–250 ms. Faster than typing my password.&lt;/p&gt;

&lt;h2&gt;
  
  
  What &lt;code&gt;pam_touchbridge.so&lt;/code&gt; actually looks like
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;PAM_EXTERN&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;pam_sm_authenticate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pam_handle_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pamh&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                   &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pam_get_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pamh&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;PAM_SUCCESS&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;PAM_AUTH_ERR&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;sock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tb_connect_daemon&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sock&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;PAM_AUTHINFO_UNAVAIL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;// PAM falls through&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tb_send_request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;getpid&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;tb_surface&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;PAM_AUTHINFO_UNAVAIL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;pam_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pamh&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"TouchBridge: check your phone…"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;tb_response_t&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;rc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tb_recv_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="cm"&gt;/*timeout_ms=*/&lt;/span&gt;&lt;span class="mi"&gt;30000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rc&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;PAM_AUTHINFO_UNAVAIL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;TB_OK&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;PAM_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;TB_DENY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;PAM_AUTH_ERR&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;PAM_AUTHINFO_UNAVAIL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Returning &lt;code&gt;PAM_AUTHINFO_UNAVAIL&lt;/code&gt; instead of &lt;code&gt;PAM_AUTH_ERR&lt;/code&gt; when the daemon isn't reachable tells PAM to keep walking the stack — so if the daemon's down, the password prompt still works. This is what makes it safe to install.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Swift signing path
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;nonce&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;throws&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Data&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;access&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;SecAccessControlCreateWithFlags&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;kSecAttrAccessibleWhenUnlockedThisDeviceOnly&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;privateKeyUsage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;biometryCurrentSet&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="kc"&gt;nil&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="kt"&gt;SecureEnclave&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;P256&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Signing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;PrivateKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nv"&gt;accessControl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;access&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;sig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;for&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;nonce&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;sig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;derRepresentation&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;biometryCurrentSet&lt;/code&gt; hardware-enforces biometric at signing time. If the enrolled fingerprint or face changes, the key invalidates — so a stolen phone can't be re-enrolled to keep using TouchBridge.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it can't do — being honest
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;FileVault unlock&lt;/strong&gt; happens before any user-space daemon is alive. No PAM hook there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The macOS login screen&lt;/strong&gt; — same reason: &lt;code&gt;loginwindow&lt;/code&gt; boots before &lt;code&gt;launchd&lt;/code&gt; user agents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Apple Pay&lt;/strong&gt; runs on a dedicated hardware path that only Apple's signed components can touch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keychain biometric items&lt;/strong&gt; — the crypto wall is enforced in the kernel and binds to the local Secure Enclave.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1Password biometric unlock&lt;/strong&gt; — SIP sandboxes prevent any third-party module from injecting into 1Password's prompt path. (Bitwarden works because its CLI uses the OS PAM stack.)&lt;/p&gt;

&lt;p&gt;If you see a tool that claims any of those, be skeptical and read its source.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it in 60 seconds (no phone needed)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew tap HMAKT99/touchbridge
brew &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--cask&lt;/span&gt; touchbridge

&lt;span class="c"&gt;# in one terminal&lt;/span&gt;
touchbridged serve &lt;span class="nt"&gt;--simulator&lt;/span&gt;

&lt;span class="c"&gt;# in another&lt;/span&gt;
&lt;span class="nb"&gt;sudo echo&lt;/span&gt; &lt;span class="s2"&gt;"this just prompted touchbridge instead of my password"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The cask is signed with a Developer ID and notarized; the formula pins SHA256.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd love help with
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Linux PAM port.&lt;/strong&gt; The protocol is portable; &lt;code&gt;pam_touchbridge.so&lt;/code&gt; builds on Linux, but the daemon needs a BlueZ adapter. Friendly first contribution if you've poked at BlueZ.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MDM / fleet pairing.&lt;/strong&gt; Provisioning the paired-device key over MDM for shared lab Macs. Open RFC.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hardware test reports.&lt;/strong&gt; Comment with &lt;code&gt;Mac model + paired device + result&lt;/code&gt; so the README's compatibility table grows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I'm posting here
&lt;/h2&gt;

&lt;p&gt;DEV.to has the largest concentration of people who actually understand the difference between PAM, PolicyKit, and &lt;code&gt;Authorization Services&lt;/code&gt;. The threat model is in &lt;code&gt;SECURITY.md&lt;/code&gt; and I'd love to have it picked apart.&lt;/p&gt;

&lt;p&gt;If TouchBridge saves you the price of a Magic Keyboard, a star on the repo is the cheapest way to say thanks.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href="https://github.com/HMAKT99/UnTouchID" rel="noopener noreferrer"&gt;github.com/HMAKT99/UnTouchID&lt;/a&gt;&lt;br&gt;
License: MIT&lt;br&gt;
Built because I refused to pay $199 for a sensor my phone already has.&lt;/p&gt;

</description>
      <category>swift</category>
      <category>opensource</category>
      <category>security</category>
    </item>
    <item>
      <title>Every era creates its file format. AI doesn't have one yet.</title>
      <dc:creator>Arun KT</dc:creator>
      <pubDate>Fri, 20 Mar 2026 16:35:40 +0000</pubDate>
      <link>https://dev.to/arun_kt_bb670b3a571f5efd8/every-era-creates-its-file-format-ai-doesnt-have-one-yet-5cde</link>
      <guid>https://dev.to/arun_kt_bb670b3a571f5efd8/every-era-creates-its-file-format-ai-doesnt-have-one-yet-5cde</guid>
      <description>&lt;p&gt;Print gave us PDF. Photography gave us JPEG. Music gave us MP3.&lt;/p&gt;

&lt;p&gt;The AI era generates more content than any previous era — but has no format to carry&lt;br&gt;
trust, provenance, or verification with that content.&lt;/p&gt;

&lt;p&gt;Today I'm releasing AKF — Agent Knowledge Format. Open source. Open spec.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is it?
&lt;/h2&gt;

&lt;p&gt;AKF is EXIF for AI. ~15 tokens of JSON that embed directly into any file:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Trust scores&lt;/strong&gt; — how reliable is this content? (0-1)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Source provenance&lt;/strong&gt; — where did it come from? (SEC filing → analyst → AI summary)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security classification&lt;/strong&gt; — who can see it? (public, internal, confidential)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI attribution&lt;/strong&gt; — which model generated it?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compliance metadata&lt;/strong&gt; — does it meet EU AI Act, SOX, NIST requirements?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;akf          &lt;span class="c"&gt;# Python&lt;/span&gt;
npm &lt;span class="nb"&gt;install &lt;/span&gt;akf-format   &lt;span class="c"&gt;# TypeScript&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  30-Second Demo
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Stamp a file&lt;/span&gt;
akf stamp report.md &lt;span class="nt"&gt;--agent&lt;/span&gt; claude &lt;span class="nt"&gt;--evidence&lt;/span&gt; &lt;span class="s2"&gt;"generated from quarterly data"&lt;/span&gt;

&lt;span class="c"&gt;# See what's inside&lt;/span&gt;
akf inspect report.md

&lt;span class="c"&gt;# Check compliance&lt;/span&gt;
akf audit report.md &lt;span class="nt"&gt;--regulation&lt;/span&gt; eu_ai_act

&lt;span class="c"&gt;# Embed into Word&lt;/span&gt;
akf embed report.docx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Zero Touch
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;akf shell-hook&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="c"&gt;# Now every file Claude, ChatGPT, OpenClaw, Aider, Ollama creates is auto-stamped&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why Now
&lt;/h2&gt;

&lt;p&gt;The EU AI Act Article 50 takes effect &lt;strong&gt;August 2, 2026&lt;/strong&gt;. AI-generated content&lt;br&gt;
published for public interest must carry transparency metadata. Penalties: up to&lt;br&gt;
€35M or 7% of global turnover.&lt;/p&gt;

&lt;p&gt;Colorado's SB 205 follows on June 30, 2026. DORA is already enforced.&lt;/p&gt;

&lt;p&gt;AKF maps directly to these requirements. One command gives you a compliance report.&lt;/p&gt;

&lt;h2&gt;
  
  
  Integrations
&lt;/h2&gt;

&lt;p&gt;Ships with integrations for LangChain, LlamaIndex, CrewAI, MCP (Model Context&lt;br&gt;
Protocol), VS Code, and GitHub Actions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://akf.dev" rel="noopener noreferrer"&gt;akf.dev&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/HMAKT99/AKF" rel="noopener noreferrer"&gt;HMAKT99/AKF&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spec:&lt;/strong&gt; &lt;a href="https://akf.dev/schema/v1.1.json" rel="noopener noreferrer"&gt;akf-v1.1.schema.json&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Open source. MIT licensed. Feedback welcome.&lt;/p&gt;

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