Trusted Agent Protocol · Cloudflare Workers
Tell a real agent
from a scraper.
AI agents like ChatGPT and Perplexity are starting to browse and buy on real merchant sites on behalf of real users. Before you can let them, you need to tell a legitimate agent apart from a scraper — cryptographically, at the edge, on every request.
That's the merchant's one job in the Trusted Agent Protocol. TAPKit makes it one import.
TAP was co-developed by Cloudflare and Visa. TAPKit is the canonical Cloudflare-native implementation.
import { verifyTap } from "@mconroy-cf/tapkit-workers";
export default {
async fetch(request, env) {
const result = await verifyTap(request, {
tag: "agent-payer-auth",
nonceStore: env.NONCE_STORE,
});
if (!result.ok) return result.toResponse();
// Signature verified. Body is in result.rawBody.
const order = JSON.parse(result.rawBody);
return Response.json({ status: "approved", order });
}
};
What a merchant actually has to do.
Agentic commerce has a lot of moving parts — agent platforms, user passkeys, payment tokenisation, network controls. Almost none of them are the merchant's problem.
You don't build the agent.
That's Visa, OpenAI, Perplexity and others. You don't handle user passkeys, tokenisation, or network controls. Those are all upstream of you.
You don't enrol the user.
Card-on-file, payment tokens, consumer identity — all handled before the agent ever hits your site.
You do verify the signature.
Every agent request to your Worker carries an RFC 9421 HTTP Message Signature. You verify it against the scheme's agent registry and check the intent tag. Valid → let it through. Invalid → reject like any other bad bot.
That's it. Really.
One verification call, two variants (browsing and payer), correct failure handling. Everything else in agentic commerce is somebody else's problem.
The work TAPKit is doing for you.
That one verification step sounds small. Here's what it actually contains — and what you'd otherwise have to build yourself.
-
RFC 9421 + structured-fields parsing
Signature-InputandSignatureheaders, covered-field inner lists, structured-field parameters like"query-param";name="agent-id". Get the parser wrong and you open a cross-merchant signature replay. -
Both signing algorithms
Ed25519 and RSA-PSS-SHA256. The spec leaves PSS salt length ambiguous — JOSE says 32, Visa's reference implementation uses
MAX_LENGTH. TAPKit tries both. Catching that ambiguity cost us half a day. -
Byte-exact signature-base reconstruction
@authority,@path(which confusingly includes the query string despite strict RFC 9421 saying otherwise), query-param components resolved from the URL. One character off and the crypto fails with no useful hint. -
Nonce replay protection at Cloudflare scale
KV-backed, cross-colo, with the right check-early/write-late timing so a malformed request can't race and consume a legitimate request's nonce.
-
Tag enforcement
agent-browser-authon browsing routes,agent-payer-authon checkout — the spec splits them for a reason, and mixing them is a subtle auth bypass. -
Bidirectional interop with Visa
We run Visa's own
tap-agentagainst TAPKit and TAPKit's signer against Visa's reference verifier. If your signatures don't round-trip against their reference, merchants won't accept real agent traffic. Full test matrix in the repo. -
Everything a first implementation gets wrong
Covered-field uniqueness, duplicate-param smuggling, whitespace preservation in signature bases, wrong-tag routing, nonce timing races. TAPKit has tests for each.
Three things, one repo.
TAPKit ships the three pieces a merchant actually needs to go from "I've read the TAP spec" to "we're accepting agent traffic in production."
@mconroy-cf/tapkit-workers
Drop-in middleware
One import, one function call. Verifies the TAP v1 Agent
Recognition Signature on incoming requests: RFC 9421 parsing,
freshness window, nonce replay protection, JWKS discovery,
Ed25519 and RSA-PSS verification. Returns a discriminated
result with a toResponse() helper.
@mconroy-cf/tapkit-cli
Signing test agent + conformance runner
npx @mconroy-cf/tapkit-cli sign <merchant-url>
generates a TAP-compliant signed request against your staging
site.
npx @mconroy-cf/tapkit-cli check <merchant-url>
runs a 13-scenario conformance suite — valid, replay, expired,
window-too-large, wrong-tag, missing-signature, unknown-keyid,
CRO and APC variants — and reports pass/fail per scenario.
Reference merchant
Live, deployable, cloneable
A minimal Cloudflare Worker showing exactly what correct TAP verification looks like, running against real Ed25519 keys and real JWKS discovery (including Visa's production endpoint). Use it as a verified baseline when integrating into your own stack — it's the same verifier the middleware ships.
See it run.
Run the TAPKit conformance suite live against our reference merchant — or point it at your own staging URL to see how close you are to spec.
Click "Run check" above to stream live results.
Quick start
Two steps, about five minutes. Assumes a Cloudflare Worker you
already have shipping on wrangler deploy.
1. Install the middleware
npm install @mconroy-cf/tapkit-workers
2. Bind a KV namespace for replay protection
Create the KV namespace and bind it as
NONCE_STORE:
{
"kv_namespaces": [
{ "binding": "NONCE_STORE", "id": "<your-kv-id>" }
]
}
3. Verify incoming requests
import { verifyTap, TAP_TAGS } from "@mconroy-cf/tapkit-workers";
export default {
async fetch(request, env) {
if (new URL(request.url).pathname === "/checkout") {
const result = await verifyTap(request, {
tag: TAP_TAGS.PAYER,
nonceStore: env.NONCE_STORE,
});
if (!result.ok) return result.toResponse();
const order = JSON.parse(result.rawBody);
// ...process the verified order...
return Response.json({ status: "approved", order });
}
return new Response("Not found", { status: 404 });
}
};
4. Confirm with the conformance suite
Deploy, then run the suite against your URL. You want 13 / 13:
npx @mconroy-cf/tapkit-cli check https://your-merchant.example.com
Frequently asked
Is this a Cloudflare product?
Not yet. TAPKit is open-source and MIT-licensed, built as part
of Cloudflare's agentic commerce work. The
@mconroy-cf/tapkit-workers package is designed to
run on any Cloudflare Worker but doesn't require a Cloudflare
account or paid plan to use. The current scope is a
partner-feedback release; an official
@cloudflare/-scoped package will follow.
What is the Trusted Agent Protocol?
TAP is an open, Visa-led standard for AI agents to cryptographically prove their identity and intent to merchants. It's built on HTTP Message Signatures (RFC 9421), Ed25519, JWKS for key discovery, and nonce + timestamp freshness. TAPKit implements all three TAP v1 layers: Agent Recognition Signature, Consumer Recognition Object, and Agentic Payment Container. Read the spec ↗
What about AP2 or Mastercard Agent Pay?
TAPKit's architecture is protocol-pluggable — adapters live in
packages/cli/src/protocols/<name>. We'll
land AP2 and Mastercard Agent Pay adapters when those specs
are merchant-ready. Until then, TAP is the one with a
published spec and live pilot deployments.
Do I need Visa-issued keys to get started?
No. TAPKit ships with a test keypair so you can verify your integration end-to-end without any external dependency. For production you'd trust Visa's JWKS (the default) or your issuer's equivalent.
How do I get real TAP credentials?
Through Visa's payment scheme onboarding. TAPKit exists precisely so you can do everything else in parallel — build and verify your integration before credentials land so the critical path isn't waiting on NDA.
Is the package on npm?
Yes — @mconroy-cf/tapkit-workers and
@mconroy-cf/tapkit-cli are both
live on npm
as partner-feedback releases. Once the official
@cloudflare/ scope ships, both packages will
deprecate and point at the canonical names.
Ship TAP support this week.
Clone the repo. Run the conformance suite against your staging site. Open an issue if you hit something weird.