DEV Community

Cover image for Visa Has a Trusted Agent Protocol. Mastercard Has Verifiable Intent. Here's the Layer Neither One Gives You
Edison Flores
Edison Flores

Posted on

Visa Has a Trusted Agent Protocol. Mastercard Has Verifiable Intent. Here's the Layer Neither One Gives You

Visa Has a Trusted Agent Protocol. Mastercard Has Verifiable Intent. Here's the Layer Neither One Gives You

And the three design lessons we adopted from both.

What just happened

In 2026 the payment networks stopped talking about "agent commerce" in the abstract and started shipping specs:

  • Visa published the Trusted Agent Protocol — an open repo with a spec plus a full sample implementation (agent registry, merchant backend, merchant frontend, a live agent). Every request from an agent carries a cryptographic signature with timestamps, a unique session identifier, a key identifier, and an algorithm identifier. Signatures are bound to the merchant's domain and the specific operation, and designed so a captured request can't be replayed.
  • Mastercard's Verifiable Intent lets merchants check the validity of a signed intent credential in real time during the authorization flow — the agent presents what it's about to do, cryptographically attested, before money moves.
  • Around them: x402 (agentic HTTP-native payments, Coinbase → Linux Foundation) and AP2 / Agent Payments Protocol (Google, with Visa, Mastercard, PayPal, Coinbase and ~60 more partners).

When the companies that move most of the world's money all build the same layer at once, that's not a trend. That's validation. Agent trust infrastructure is now load-bearing.

So the fair question for us — a tiny open project that ships a thing called the Agent Trust Card (ATC) — is: what's left for you? This post answers that honestly, including the parts where the networks are simply better positioned than we are, and the three concrete design lessons we took from them.

What the network protocols do well (credit where due)

Membership-scaled trust. A Visa-signed agent assertion works everywhere Visa works, instantly, because the merchant already trusts the network. No bootstrap problem. We can't do that and won't pretend otherwise.

Freshness discipline. TAP's per-request signature — timestamp, session ID, single-use semantics, domain binding — is exactly the right shape for killing replay and relay attacks. This is rigorous, well-specified, and worth copying.

Inline verification. Mastercard's "check the intent during authorization" is the correct UX: verification happens in the flow, not as a side quest. No merchant is going to run a separate audit tool before every checkout.

None of this is sarcasm. If you're building agent commerce inside the payment networks, use their protocols. Seriously.

The gap nobody covers: proof a stranger can verify

Here's what a third party — a developer, an auditor, a competitor, a paranoid enterprise — cannot do with those protocols:

  1. Audit the verifier. How do you know the thing that says "this agent is trusted" isn't corrupted, patched, or memorizing answers? With a network protocol, you trust the network's verdict because you trust the network. Circular.
  2. Reproduce the credential. Can an outsider rebuild the artifact from public bytes and get the same result, bit for bit?
  3. Find immutable public evidence. Where is the append-only, third-party-hosted record proving what was published and when — one that even the publisher cannot rewrite?

That's the difference in one line:

TAP and VI give an agent permission to transact inside a network. An ATC gives anyone evidence they can verify outside every network — offline, no membership, no API key.

The analogy we keep using: the networks issue the driver's license. We publish the court records — verifiable by any stranger, sealed in a public log nobody can edit. You want both. A license without records is a promise; records without a license are history. Commerce needs both to work.

And this isn't theoretical for us. Our entire audit conversation this month was a third party (thanks again, @anp2network) probing exactly that: is the thing doing the scoring itself tested? can I regenerate your ground truth? does the answer survive a lying sidecar? Every one of those questions only has an answer because we built for strangers-first.

The three lessons we adopted from them

We didn't adopt their protocols (we're not a payment network, and bolting on a pretend integration would be exactly the kind of theater this project exists to eliminate). We adopted the design discipline:

1. From Visa TAP: freshness must be two-sided and derived from bytes

TAP signs every request with time-sensitive elements so stale authorization can't be replayed. Our v1.3.3 release applies the same discipline to trust cards: the reference runner now enforces a two-sided validity windowissued_at <= NOW < expires_at. A card dated in the future (our new premature-atc vector, issued 2030-01-01) fails exactly like an expired one. And the check derives from the card bytes, not from any sidecar metadata — so a lying or deleted sidecar can't flip the verdict.

2. From Mastercard VI: verification belongs in the flow — ours runs offline

VI's insight is that verification must happen inline, during the transaction. Our equivalent: an ATC verifies offline in milliseconds — one Ed25519 check against pinned trust anchors, zero network calls, zero API keys, zero membership. No dependency on anyone's uptime, including ours. Verification in the flow without needing the flow's permission.

3. From both: a registry, but append-only and outside our control

TAP ships a central Agent Registry. Centralized registries are convenient and are also a single point of editorial control. We took the registry idea and made it one nobody — including us — can rewrite: every release of our conformance suite is countersigned and anchored into Rekor, the public Sigstore transparency log. Entry #3 (logIndex 2764479676) carries the digests of the entire v1.3.3 suite. The log's inclusion proofs and signed checkpoints verify against Rekor's public keys — 9/9 checks pass, live, today. If we ever tried to quietly change history, the log would contradict us.

How an ATC travels inside their protocols (proposed mapping)

To be explicit about interoperability — this is a proposal, not a shipped integration — an ATC composes cleanly with a TAP/VI flow:

Agent → merchant request:
  [TAP signature]           ← who I am + authorization for THIS request (network-verifiable)
  [Verifiable Intent]       ← what I'm about to do, signed (network-verifiable, inline)
  [ATC + pinned anchors]    ← verifiable evidence trail of my trust artifacts
                              (stranger-verifiable, offline, no network required)
Enter fullscreen mode Exit fullscreen mode

The merchant checks the first two with the network, as designed. The third is the part the networks don't sell: the evidence any third party can check without asking anyone's permission — including evidence that the trust artifacts themselves were published, tested, and anchored immutably.

The receipts (all stranger-verifiable, all live URLs)

Everything below runs from public URLs only. No git clone of our org required, no trust in this article required:

The bug that motivated v1.3.3 was found by a stranger running our own tools against us. That's not an embarrassment; that's the product working.

The honest close

Visa's repo has 200 stars in weeks. Mastercard, Google, Coinbase, PayPal are all in. The giants are building the permission layer for agent commerce, and they will win it, because that's what networks are for.

What we're building is the piece networks structurally don't sell: proof that doesn't require trusting the seller. When an enterprise asks "who audits the auditors?", the answer can't be "the auditors." It has to be: anyone can, and here are the commands.

They validated the layer. We're keeping the receipts.

Update (2026-09-09): revocation alongside issuance — answering Alex Shev

Alex Shev asked the sharpest question in the comments: transparency proves issuance, but a merchant also needs to know whether a key, runner, or policy was revoked at decision time — and how a disconnected verifier catches up later. His proposed shape: a signed checkpoint plus a bounded freshness rule. (The dev.to comments API still rejects programmatic replies, so the answer lives here, next to the receipts.) The honest state of each piece:

Key revocation: live, and already battle-tested. The CA registry (public in the repo, mirrored at GET /api/atc?action=ca-key) is status-based: active / retired / retired-compromised. Not a theoretical mechanism — mn-ca-002 is marked retired-compromised because its private material was found committed to a public repository. The ledger was re-signed under mn-ca-003, and verifiers reject anything signed by a non-active key. At decision time a card passes only if its signing key is active and the validity window holds two-sided from the bytes (issued_at <= NOW < expires_atpremature-atc exists as a vector precisely because runners that only check expiry accept a card issued in 2030).

The signed checkpoint: already in the verification path. The stranger flow fetches the Rekor entry once from the third-party log; everything after that runs locally: an RFC 6962 Merkle fold of the inclusion proof into the root, verification of the C2SP signed note (the signed tree head) against Rekor's pinned key, and a tree-size coverage check. A cached entry re-verifies offline indefinitely — run it yourself.

The freshness bound: the missing piece, and his shape is right. The checkpoint proves "included as of tree size N", but a stale cached checkpoint cannot distinguish "nothing revoked since" from "revoked after my snapshot." The rule, in his shape: revocation events (key, runner, policy) land in the same append-only log as issuance, so checkpoint coverage subsumes revocation knowledge; offline accept then requires tree size ≥ every revocation relevant to the artifact's trust roots, plus checkpoint age ≤ a risk-tiered bound — otherwise fail-closed to online. Catch-up stays cheap: a disconnected verifier syncs one signed note and diffs tree sizes, never the whole log.

Deliberately not there yet: runner and policy revocation aren't first-class. Runner identity is pinned via the answer key + the 10 mutants, but there is no runner-revocation list. The natural next vector family: revoked-key-atc, stale-checkpoint, post-revocation-reissue.

— AliceLabs / MarketNow · marketnow.site · UTA on GitHub

Top comments (2)

Collapse
 
alexshev profile image
Alex Shev

The proposed layering is clearest when revocation is modeled alongside issuance. A merchant needs to know not only that a trust artifact was transparently published, but whether a key, runner, or policy was revoked at the decision time and how a disconnected verifier catches up later. A signed checkpoint plus a bounded freshness rule would make that offline story concrete.

Collapse
 
edison_flores_6d2cd381b13 profile image
Edison Flores

You're pointing at the exact seam — issuance-only transparency is half a story. Mapping your three objects (key, runner, policy) to what exists today: key revocation is live and battle-tested (the CA registry is status-based; mn-ca-002 is retired-compromised after its private material landed in a public repo — ledger re-signed under mn-ca-003, verifiers fail-closed on non-active keys, two-sided window from bytes). The signed checkpoint is already in the verification path (RFC 6962 Merkle fold + C2SP signed note against Rekor's pinned key, all local after one fetch). What's missing is exactly your freshness bound — a stale checkpoint can't distinguish "nothing revoked since" from "revoked after my snapshot". The rule in your shape: revocations land in the same append-only log as issuance, so checkpoint coverage subsumes revocation knowledge; offline accept requires tree size ≥ all relevant revocations + checkpoint age ≤ a risk-tiered bound, else fail-closed. Catch-up = one signed note. Runner/policy revocation aren't first-class yet — next vector family: revoked-key-atc, stale-checkpoint, post-revocation-reissue. Receipts: marketnow.site/uta/conformance/