Add cryptographic authorization to AI agents in 5 minutes
All For Scie
·
2026-04-23
·
via DEV Community
<p>You have AI agents calling each other. You're using API keys or mTLS. You're worried it's not enough.</p> <p>API keys authenticate. They don't authorize. They don't scope. They don't audit delegation chains.</p> <p>Here's how to add all four in under 5 minutes using <strong>Codios</strong> — an A2A security layer built on signed capability contracts.</p> <p><a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodios.midlantics.com%2F_next%2Fimage%3Furl%3D%252Fimages%252Flogo.png%26w%3D256%26q%3D75" class="article-body-image-wrapper"><img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodios.midlantics.com%2F_next%2Fimage%3Furl%3D%252Fimages%252Flogo.png%26w%3D256%26q%3D75" alt="codios" width="256" height="208"></a></p> <h2> What you'll build </h2> <ul> <li>Two agents with cryptographic identities (Ed25519 keypairs)</li> <li>A signed contract granting specific permissions</li> <li>A protected API endpoint that verifies contracts offline</li> <li>Full audit logs of every authorization decision</li> </ul> <p><strong>Time:</strong> ~5 minutes</p> <p><strong>What you need:</strong> Node.js and a Codios account (free at codios.midlantics.com)</p> <h2> Step 1: Install the SDK </h2> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code>npm <span class="nb">install</span> @codios/sdk </code></pre> </div> <h2> Step 2: Generate keypairs using the CLI (easiest) </h2> <p>The Codios CLI can generate a keypair and save it to your .env file automatically:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code>bash codios keygen <span class="nt">--save</span> .env </code></pre> </div> <p>This appends CODIOS_PUBLIC_KEY and CODIOS_PRIVATE_KEY to your .env file.</p> <p><strong>To generate manually in TypeScript:</strong><br> </p> <div class="highlight js-code-highlight"> <pre class="highlight typescript"><code><span class="k">import</span> <span class="p">{</span> <span class="nx">generateAgentKeyPair</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">@codios/sdk</span><span class="dl">"</span> <span class="kd">const</span> <span class="nx">agent</span> <span class="o">=</span> <span class="k">await</span> <span class="nf">generateAgentKeyPair</span><span class="p">()</span> <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">DID:</span><span class="dl">"</span><span class="p">,</span> <span class="nx">agent</span><span class="p">.</span><span class="nx">did</span><span class="p">)</span> <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">Public key:</span><span class="dl">"</span><span class="p">,</span> <span class="nx">agent</span><span class="p">.</span><span class="nx">publicKey</span><span class="p">)</span> <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">Private key:</span><span class="dl">"</span><span class="p">,</span> <span class="nx">agent</span><span class="p">.</span><span class="nx">privateKey</span><span class="p">)</span> <span class="c1">// Save this securely</span> </code></pre> </div> <h2> Step 3: Register your agent in the dashboard </h2> <p>Log into the <a href="https://codios.midlantics.com/dashboard" rel="noopener noreferrer">Codios dashboard</a></p> <ol> <li>Go to the Agents tab</li> <li>Click <strong>Register agent</strong> </li> <li>Enter a name (e.g., "billing-agent")</li> <li>Optional: Add capabilities (e.g., transfer, quote)</li> <li> <strong>Leave Public key blank</strong> — Codios generates a keypair for you</li> <li>Click Register <strong>Important:</strong> The private key is shown once. Copy and store it immediately. It cannot be recovered.</li> </ol> <p><strong>Alternative using CLI:</strong><br> </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code>codios register <span class="nt">--name</span> billing-agent <span class="nt">--public-key</span> <span class="nv">$CODIOS_PUBLIC_KEY</span> </code></pre> </div> <h2> Step 4: Issue a contract using the 4-step wizard </h2> <ol> <li>Go to the Contracts tab in the dashboard</li> <li>Click Connect agents</li> <li>Issuer — Select the agent that will make requests (or choose Codios Platform to have Codios sign on your behalf)</li> <li>Targets — Select one or more agents that will receive requests (each gets its own independent contract)</li> <li>Permissions — Define allowed actions (e.g., <code>transfer</code> ). Set duration (1h / 1d / 7d / 30d) and optional max calls</li> <li>Review — Confirm the flow, then click Issue contract After issuance, each target's <strong>contract token</strong> is shown. Copy each token — you'll pass it as the <code>X-Codios-Contract</code> header.</li> </ol> <p><strong>Contract status:</strong> <code>active</code> → <code>expired</code> (TTL elapsed) or <code>revoked</code> (manually revoked)</p> <h2> Step 5: Protect your service with middleware </h2> <div class="highlight js-code-highlight"> <pre class="highlight typescript"><code><span class="k">import</span> <span class="nx">express</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">express</span><span class="dl">"</span> <span class="k">import</span> <span class="p">{</span> <span class="nx">codiosGuard</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">@codios/sdk</span><span class="dl">"</span> <span class="kd">const</span> <span class="nx">app</span> <span class="o">=</span> <span class="nf">express</span><span class="p">()</span> <span class="nx">app</span><span class="p">.</span><span class="nf">post</span><span class="p">(</span> <span class="dl">"</span><span class="s2">/transfer</span><span class="dl">"</span><span class="p">,</span> <span class="nf">codiosGuard</span><span class="p">({</span> <span class="na">action</span><span class="p">:</span> <span class="dl">"</span><span class="s2">transfer</span><span class="dl">"</span><span class="p">,</span> <span class="c1">// Must match contract's allowed action</span> <span class="na">publicKey</span><span class="p">:</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">SERVICE_AGENT_PUBLIC_KEY</span><span class="p">,</span> <span class="na">gatewayUrl</span><span class="p">:</span> <span class="dl">"</span><span class="s2">https://codios-api.midlantics.com</span><span class="dl">"</span><span class="p">,</span> <span class="p">}),</span> <span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span> <span class="c1">// Only reaches here if the contract is valid</span> <span class="nx">res</span><span class="p">.</span><span class="nf">json</span><span class="p">({</span> <span class="na">ok</span><span class="p">:</span> <span class="kc">true</span> <span class="p">})</span> <span class="p">}</span> <span class="p">)</span> <span class="nx">app</span><span class="p">.</span><span class="nf">listen</span><span class="p">(</span><span class="mi">3000</span><span class="p">)</span> </code></pre> </div> <h2> Step 6: Call the protected service </h2> <div class="highlight js-code-highlight"> <pre class="highlight typescript"><code><span class="kd">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="k">await</span> <span class="nf">fetch</span><span class="p">(</span><span class="dl">"</span><span class="s2">http://localhost:3000/transfer</span><span class="dl">"</span><span class="p">,</span> <span class="p">{</span> <span class="na">method</span><span class="p">:</span> <span class="dl">"</span><span class="s2">POST</span><span class="dl">"</span><span class="p">,</span> <span class="na">headers</span><span class="p">:</span> <span class="p">{</span> <span class="dl">"</span><span class="s2">Content-Type</span><span class="dl">"</span><span class="p">:</span> <span class="dl">"</span><span class="s2">application/json</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">X-Codios-Contract</span><span class="dl">"</span><span class="p">:</span> <span class="nx">contractToken</span><span class="p">,</span> <span class="c1">// The token from Step 4</span> <span class="p">},</span> <span class="na">body</span><span class="p">:</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">stringify</span><span class="p">({</span> <span class="na">amount</span><span class="p">:</span> <span class="mi">100</span> <span class="p">}),</span> <span class="p">})</span> </code></pre> </div> <h2> What happens on every request </h2> <div class="table-wrapper-paragraph"><table> <thead> <tr> <th>Step</th> <th>Time</th> </tr> </thead> <tbody> <tr> <td>Verify Ed25519 signature (offline)</td> <td>~0ms</td> </tr> <tr> <td>Check expiry, actions, max_calls</td> <td>~0ms</td> </tr> <tr> <td>Nonce check (Redis SET NX)</td> <td>~1ms</td> </tr> <tr> <td>Async audit log write</td> <td>Non-blocking</td> </tr> </tbody> </table></div> <p><strong>Total overhead:</strong> 1-2ms</p> <p>If a contract is expired, out of calls, or already used → HTTP 403 or 409.</p> <h2> Dashboard features you'll use </h2> <div class="table-wrapper-paragraph"><table> <thead> <tr> <th>Tab</th> <th>What it does</th> </tr> </thead> <tbody> <tr> <td>Overview</td> <td>Stats: registered agents, active contracts, audit entries (24h), denied requests</td> </tr> <tr> <td>Agents</td> <td>Register agents, view DID/public key, see heartbeat status (green/yellow/red)</td> </tr> <tr> <td>Contracts</td> <td>Issue contracts via wizard, revoke, check status</td> </tr> <tr> <td>Audit Log</td> <td>Filter by outcome, action, agent. Retention: Free=7d, Starter=30d, Pro=90d</td> </tr> <tr> <td>Threat Detection (Pro)</td> <td>Scans for off-hours access, action bursts, unknown agents, repeated denials</td> </tr> <tr> <td>Alert Rules (Starter+)</td> <td>Email on denial spikes, rate limit exceeded, agent inactive</td> </tr> <tr> <td>API Keys</td> <td>Create codios_sk_... keys for backend services</td> </tr> </tbody> </table></div> <h2> Next steps </h2> <ul> <li> <strong>Add heartbeat</strong> – Have your agent call <code>POST /agents/{id}/heartbeat</code> every minute to keep status green</li> <li> <strong>Set up alert rules</strong> – Get email notifications when something goes wrong</li> <li> <strong>Review the audit log</strong> – See every allow/deny decision</li> <li> <strong>Try the Python SDK</strong> – FastAPI middleware also available</li> </ul> <p><strong>Get your API key:</strong> <a href="https://codios.midlantics.com" rel="noopener noreferrer">codios.midlantics.com</a></p> <p><strong>Full documentation:</strong> <a href="https://codios.midlantics.com/docs" rel="noopener noreferrer">codios.midlantics.com/docs</a></p> <h2> Why this matters </h2> <p>API keys were designed for humans. AI agents are different — autonomous, fast, and chained.</p> <p>Codios gives you the security model agents actually need, without adding latency to your hot path.</p> <p><a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodios.midlantics.com%2F_next%2Fimage%3Furl%3D%252Fimages%252Flogo.png%26w%3D256%26q%3D75" class="article-body-image-wrapper"><img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodios.midlantics.com%2F_next%2Fimage%3Furl%3D%252Fimages%252Flogo.png%26w%3D256%26q%3D75" alt="codios" width="256" height="208"></a></p>
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。