Three different agents hit a publisher's API. See what happens with and without AgentPKI. Real cryptography, real production Workers, ~150ms end-to-end.
Two paths, both walked through in the dashboard:
Each button mints + sends to the production verifier. Verdicts come back in ~150ms. Hover any button to preview the trust flow without firing the API; click to run it for real.
Expected: verdict: allow
Expected: verdict: not_allowed
Expected: verdict: not_allowed
Hover a button above to preview the diagram — the trust flow updates without firing the API.
Like HTTPS for agents — every outbound call carries a signed identity any server can verify. Mint a real passport below, hand it to a live verifier, watch verdict: allow.
Start here · no signup, no install
Three other ways are linked below if the browser flow isn’t how you work.
yourname.agents.agentpki.dev, minting a real PASETO passport against it, and running it through the live verifier — entirely in your browser, no install, ~30 seconds to verdict allow.No DNS work, no domain purchase. Your subdomain is yours to use forever.
_____.agents.agentpki.devOne click. Real PASETO v4 token from the live demo issuer, signed with a real Ed25519 key. We wire your handle in as the agent's sub.
Same endpoint any bot-defense vendor or website would call: POST verify.agentpki.dev/v1/verify. Two ways to test it.
———
That's the whole protocol — real signature, real verdict, your handle as the sub.
Where to go from here:
· Claim a real issuer — bring your domain, get keys, mint production passports.
· Adding to an existing agent? Path 04 has the 5-line drop-in.
Step 3 returned allow. Now make it deny — you choose how.
Mint → corrupt → verify. You drive each step.
Pick a kid → inspect the CRL → verify.
Same deny, different failure_reason: bad_signature = forged. revoked_key = legit signature, dead key. AgentPKI tells you which.
@agentpki/sdk installed, Anthropic-backed agent, live verifier call) into StackBlitz or Codespaces. You hit Run. No npm install, no local Node setup, no boilerplate.Both buttons spin up a fresh sandbox with the SDK pre-installed and a working index.mjs.
One click forks agentpki/test-agent-template into a cloud IDE with @agentpki/sdk already installed and three demo commands wired up: npm run demo:allow, npm run demo:tamper, npm run demo:revoked — the same trust contract Path 01's labs exercise, but from a real Node project you own.
Open index.mjs — the whole demo is 12 lines.
// index.mjs — pre-wired test agent import { mintPassport, verify } from '@agentpki/sdk'; import Anthropic from '@anthropic-ai/sdk'; const token = await mintPassport({ sub: 'agent:test/v1' }); const claude = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY }); const resp = await claude.messages.create({ model: 'claude-3-5-sonnet', max_tokens: 200, messages: [{ role: 'user', content: 'What is AgentPKI?' }], }); const verdict = await verify(token); console.log('claude says:', resp.content[0].text); console.log('verifier says:', verdict.verdict);
Paste your Anthropic key into the .env, hit ▶ Run. You see Claude's response AND the verifier's verdict in the same terminal.
npm i-ing anything until I know it works."/check/result/<id> URL — without installing anything, claiming a domain, or signing up./bootstrap and /bootstrap.ps1 are deployed at agentpki.dev and smoke-tested against the demo issuer + verifier. The script mints a demo passport, verifies it, and prints verdict: allow. Two HTTP calls, nothing destructive — full source linked from each script.
Same end-to-end behaviour, native syntax for each shell. The Copy button copies only the command — the prompt marker ($ or PS>) is stripped, so you can't paste it by accident.
$ curl -fsSL https://agentpki.dev/bootstrap | sh
Requires curl + sed (both POSIX standard). Tested on macOS 14 and Ubuntu 22.04.
PS> iwr https://agentpki.dev/bootstrap.ps1 | iex
iwr = Invoke-WebRequest, iex = Invoke-Expression. Pure PowerShell — no bash, no sh, no WSL needed. Tested on Windows PowerShell 5.1 and PowerShell 7+.
Never hide what runs on your machine. Inspect without executing:
bash · preview
$ curl -fsSL https://agentpki.dev/bootstrap
PowerShell · preview
PS> iwr https://agentpki.dev/bootstrap.ps1 | Select-Object -Expand Content
Click Simulate to animate the actual 3-scenario v1.0 output. Every value is what the live bootstrap returns — 6 real HTTP calls in ~1 sec.
passportProvider — every outbound HTTP call is now signed and verifiable, nothing else in your code changes.@agentpki/sdk is live on npm today, so the Vanilla fetch tab works right now.
@agentpki/langchain and @agentpki/vercel-ai are preview package names — we'll publish them once Path 04 gets HN signal. The snippets show the shipped API surface, but npm i on those two will 404 today.
// 1. install (preview — not yet on npm) $ npm i @agentpki/langchain // 2. wrap your existing chain import { withAgentPKI } from '@agentpki/langchain'; const chain = withAgentPKI(myChain, { passportProvider: async () => ({ token: process.env.AGENTPKI_TOKEN!, }), }); // done. every outbound HTTP tool call is now signed.
// 1. install (preview — not yet on npm) $ npm i @agentpki/vercel-ai // 2. add the middleware to your generateText call import { generateText } from 'ai'; import { agentpkiMiddleware } from '@agentpki/vercel-ai'; await generateText({ model: openai('gpt-4o'), experimental_telemetry: agentpkiMiddleware({ passportProvider: async () => ({ token: process.env.AGENTPKI_TOKEN! }), }), });
// 1. install (@agentpki/sdk is live on npm) $ npm i @agentpki/sdk openai // 2. give OpenAI the AgentPKI client's fetch import OpenAI from 'openai'; import { AgentPKI } from '@agentpki/sdk'; const pki = new AgentPKI({ passportProvider: async () => ({ token: process.env.AGENTPKI_TOKEN! }), }); const client = new OpenAI({ fetch: pki.fetch.bind(pki), });
// 1. install (@agentpki/sdk is live on npm) $ npm i @agentpki/sdk @anthropic-ai/sdk // 2. give Anthropic the AgentPKI client's fetch import Anthropic from '@anthropic-ai/sdk'; import { AgentPKI } from '@agentpki/sdk'; const pki = new AgentPKI({ passportProvider: async () => ({ token: process.env.AGENTPKI_TOKEN! }), }); const client = new Anthropic({ fetch: pki.fetch.bind(pki), });
// 1. install (@agentpki/sdk is live on npm) $ npm i @agentpki/sdk // 2. use the AgentPKI client as a drop-in fetch import { AgentPKI } from '@agentpki/sdk'; const pki = new AgentPKI({ passportProvider: async () => ({ token: process.env.AGENTPKI_TOKEN! }), }); const res = await pki.fetch('https://reuters.com/api/article/123'); // AgentPKI-Token header + RFC 9421 signature attached automatically.
In a separate terminal (or paste the token into agentpki.dev/check), run:
$ curl -X POST https://verify.agentpki.dev/v1/verify \ -H 'content-type: application/json' \ -d '{"token":"<paste-token-here>"}' { "verdict": "allow", "issuer": "mybot.agents.agentpki.dev", "elapsed_ms": 47 }
That's end-to-end inside your real project. Your existing agent now carries a verifiable cryptographic identity for every outbound call.
Three assertions. If any stops passing against your prod verifier, the trust system regressed.
// agentpki.test.ts — drop this into your existing test suite import { describe, it, expect } from 'vitest'; const VERIFY = 'https://verify.agentpki.dev/v1/verify'; const MINT = 'https://demo.agentpki.dev/mint'; async function verify(token: string) { const r = await fetch(VERIFY, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ token }), }); return r.json(); } describe('AgentPKI trust contract', () => { it('allow on a real signed token', async () => { const { token } = await fetch(MINT).then(r => r.json()); const v = await verify(token); expect(v.verdict).toBe('allow'); }); it('deny + bad_signature on tampered token', async () => { const { token } = await fetch(MINT).then(r => r.json()); const [v, p, p2, f] = token.split('.'); const tampered = `${v}.${p}.${p2.slice(0, -4)}AAAA.${f}`; const result = await verify(tampered); expect(result.verdict).toBe('deny'); expect(result.failure_reason).toBe('bad_signature'); }); it('deny + revoked_key when issuer rotated the kid', async () => { const { token } = await fetch(`${MINT}?revoked=1`).then(r => r.json()); const result = await verify(token); expect(result.verdict).toBe('deny'); expect(result.failure_reason).toBe('revoked_key'); expect(result.failure_detail).toContain('demo-2026-q1-rotated'); }); });
Your browser executes the same three assertions against verify.agentpki.dev. If any of these stops passing, the trust system regressed — not your code, not your network. Click run as many times as you like; cached responses produce different latencies but the same verdicts.
Got stuck somewhere? Tell us where.
That’s our next bug.
Apache 2.0 · v0.2 live · bootstrapped from San Francisco
The verdict from §3 isn't the final answer — it's one signal that flows into the vendor's existing scoring pipeline. AgentPKI never overrides; it only adds. Same shape as how vendors already consume third-party threat-intel feeds.
// Cloudflare bot-management scoring (simplified) let score = 0; score += fingerprint(req); // 0.30 — looks scripted score += ipReputation(req.ip); // 0.20 — fresh residential score += behaviorAnalysis(session); // 0.15 — no human variance // Total: 0.65 → above 0.5 threshold → CAPTCHA
// One new signal — never replaces, only adjusts.
const apki = await verifyAgentPKI(req);
if (apki?.verdict === 'allow') {
score -= 0.40 * tierWeight(apki.passport.tier);
// ↑ tier 2 (KYB) = 1.0 · tier 3 (HSM) = 1.25
} // 0.65 (fingerprint+ip+behavior) − 0.40 (tier-2 AgentPKI signal) // = 0.25 → below threshold → ALLOW // Result: Anthropic's research bot gets through. // Unsigned Python script (no AgentPKI header) still hits 0.65 → CAPTCHA. // Tampered token → AgentPKI verify returns 'deny' → no adjustment.
The vendor stays in control. They pick the weight (we suggest 0.40 for tier 2, 0.50 for tier 3). They decide the threshold. AgentPKI never sees the request itself — only the token. The vendor's behavioral models, IP reputation databases, customer-specific rules — all still run and still matter. AgentPKI just adds the one thing nobody could measure before: "this traffic carries a verifiable claim of legitimacy from a known issuer."
Reference 30-line integration on GitHub: github.com/agentpki/bot-defense-reference — drops into Cloudflare Workers, DataDome's API hook, hCaptcha's enterprise endpoint, Arkose's signal-API, or your own edge.
If you run an API that wants to apply different limits to different agents (Stripe, Shopify, Reddit, anyone with a developer tier), AgentPKI gives you a verifiable answer to "whose agent is this and what are they authorized to do?"
// Your API gateway, after AgentPKI verification:
const passport = await verifyAgentPKI(req);
// 1. Rate-limit by issuer, not just IP
rateLimiter.check(`agent:${passport.iss}/${passport.sub}`);
// 2. Authorize by scope
if (req.path.startsWith('/articles/') && !passport.scope.includes('read:articles')) {
return res.status(403).send({ error: 'insufficient_scope' });
}
// 3. Bill the issuer's account, not the user's
billing.charge(passport.iss, calculateUsage(req));
// 4. Audit-log who did what
audit.log({ issuer: passport.iss, agent: passport.sub, path: req.path, tier: passport.tier }); Without AgentPKI, the API can only see User-Agent headers (which lie) and IP addresses (which rotate). With AgentPKI, the API gets a cryptographically signed, revocable, auditable claim of who's calling and what they're authorized to do — without needing every agent operator to register an API key with you in advance.
read:articles, valid for 5 minutes.reuters.com/api/article/123.verify.agentpki.dev/v1/verify.anthropic.com/.well-known/agentpki-issuer.json (cached at edge), validated the Ed25519 signature, consulted Anthropic's CRL (also cached), returned verdict: allow + passport metadata.No shared secrets between Reuters and Anthropic. No central authority. No blockchain. Just standards-grade cryptography (PASETO v4 + Ed25519 + RFC 9421) over a public protocol that any verifier on the web can check.
Three real network calls to two different production-deployed Workers. Click to expand the raw responses.
Issuer signs a PASETO v4 token with Ed25519. Returns the token + decoded passport metadata.
{
"token": "v4.public.eyJpc3M…",
"passport": {
"iss": "demo.agentpki.dev",
"sub": "agent:browser-demo/visitor",
"scope": ["read:articles"],
"tier": 2,
"kid": "demo-2026-q2"
},
"expires_in": 300
} Verifier fetches the issuer's public key, validates signature, consults CRL, returns verdict.
{
"verified": true,
"verdict": "allow",
"passport": { "issuer": "demo.agentpki.dev", … },
"crl_fresh": true,
"abuse_score": 0.02,
"elapsed_ms": 21
} Two paths, both walked through in the dashboard: