The agent-fraud cure
The whole agentic-commerce stack authenticates a claim, never the machine. An A2A Agent Card is a JSON file whose signature is optional; an AP2 mandate is signed but defers whose key signed it; an x402 payment is a bare wallet that proves control of funds, not which agent holds it. So an impostor presents a look-alike card, replays a captured mandate, or pays from a wallet no one can attribute. No revocation protocol shuts any of it down.
Whisper cures it by making the address be the agent: a routable IPv6 /128 derived from the key the agent already holds, DNSSEC-anchored and DANE-pinned, that no counterparty can forge and one call can revoke worldwide. A cloned card with no agent key behind it authenticates to nothing. This page walks the abuse end-to-end, the reframe, and the exact live calls: keyless to verify, one keyed call to provision, one more to revoke. It also covers the wallet binding the rails leave open and the attribution companion that names whoever already transacted in your agent's name.
The abuse, at class level
It is not a breach. The A2A, AP2 and x402 protocols are used exactly as they were built, by an agent that was never yours, wearing an identity no counterparty can check. The mechanics repeat across every rail, and they follow the same six moves every time.
Discover and impersonate. Agent Cards are fetched at /.well-known/agent-card.json (a well-known URI, RFC 8615) and the map of who-can-transact is public by design. A third party publishes a shadow-cloned card at a plausible domain (A2A does not mandate how a card is verified; it delegates that to implementers), or simply lifts a bearer token, a static API key, or a leaked wallet key. Now it holds a credential the counterparty cannot tell from the real one.
Enter the flow and transact. Auth says yes to whoever holds the secret, so the impostor becomes a participant inside an A2A/AP2/x402 exchange indistinguishable from a legitimate peer. From there the payment is triggered two ways. Prompt-inject the victim's own agent: injected instructions in a page, an email, or a tool result steer it into an unauthorized purchase or leak its token. Or play confused deputy, persuading an over-permissioned agent to spend “on your behalf” and drain a wallet faster than a human can react.
The root cause is a trust vacuum the rails were built without: today an agent is authenticated by a bearer credential, not a forge-proof identity. An API key “grants access to anyone who possesses it, not a verified identity”; an OAuth token is portable; an Agent Card is self-asserted. That leaves three structural holes every counterparty inherits: no forge-proof identity (steal the token, become the agent), no cross-platform attribution (each domain validates in isolation), and no revocation (“when one domain revokes, connected domains have no standard mechanism to receive that signal”: not a latency problem, but a missing protocol).
Replay, rotate and persist. The abuser reuses a captured mandate (or exploits an SDK signature-verification bypass of the kind disclosed against x402 tooling in 2026), then rotates its egress across AWS, GCP and Azure, or a residential-proxy swarm, so with no stable identity to correlate, its sessions cannot be linked. Finally it survives the response: there is no cross-domain revocation protocol, so a compromised identity keeps working elsewhere, and a “revoked” agent often keeps its registration: a dormant but persistent threat. This is not hypothetical. A single compromised agent integration spread across 700+ trust domains in about ten days on stolen OAuth tokens, and the revocation never propagated. Analysts project non-human identities now outnumber humans ~109:1, most authenticated by a bearer secret, and the WEF estimates ~1 in 4 data breaches could stem from AI-agent exploitation by 2028.
Detection will always be a step behind a credential that is genuinely valid and a card that is well-formed. You can tune fraud models forever and the abuser still looks exactly like a legitimate agent. To your backend, it is one. The strictly-stronger move is to change what the counterparty trusts.
The reframe: the address is the agent
Whisper has one primitive: the address is the identity. A routable IPv6 /128 out of 2a04:2a01::/32 (announced by AS219419), deterministically derived from a key, DNSSEC-signed to the IANA root, DANE-EE pinned (3 1 1), and RDAP-registered: re-derivable and verifiable by anyone with dig.
Point it at the agent. Whisper derives each agent's /128 from the public key it already holds (the same key behind its A2A Agent Card signature, its AP2 mandate signer, or its x402 wallet), with the agent id as its domain-separating input, which you pass as device_id. The derivation is deterministic and tenant-bound: the same device key and agent id always yield the same /128, and the mapping is unlinkable across marketplaces to an outsider. The private key never leaves the agent; only its public SubjectPublicKeyInfo is an input.
The counterparty then authorizes on the agent's pinned identity, not a stealable artifact: a request either proves it is the agent it claims to be, before a single fraud rule runs, or it has no authority at all.
The agent id is the public index. The /128 is its cryptographic counterpart. An agent id is meant to be shared: it flows through every A2A discovery and every mandate, and that is exactly what an impostor weaponizes. But the /128 derives from the in-agent key with the id as its domain-separating input, so the id alone yields nothing. You cannot go id → /128 without the key, there is no enumerable directory, and RDAP and reverse DNS return the registry object, never where the agent runs. The same key under two platforms yields two unrelated /128s, so no outsider can link an agent across marketplaces.
What changes
Nothing here is a new fraud rule. Each row is an abuse technique that stops being possible, not one you catch after the fact.
| The abuse today | Why it dies under identity |
|---|---|
| Present a shadow-cloned Agent Card | You cannot present an agent identity whose device key you do not hold. Every forgery is a DNSSEC / DANE inconsistency any verifier catches with stock tools: dig -x names an identity whose AAAA and TLSA don't agree, before the mandate is signed. |
| Rotate egress across clouds / residential proxies | Identity is not the source IP. The last IP was never the credential, so rotating it (across AWS, GCP, Azure, or a proxy swarm) changes nothing about whether the caller can prove the agent. |
| Replay a captured mandate or a stolen bearer | The artifact has no agent key behind it. A state-changing request terminates mutually-authenticated to the agent's /128, and the agent co-signs, so a valid-looking mandate that can't prove the signer's identity never had authority. Reaching any account no longer reaches any agent. |
| Pay from an unattributable x402 wallet | The wallet is pinned to the verifiable identity: a facilitator resolves the agent, checks the DANE pin, and confirms the wallet is bound to a known, non-revoked agent before honoring the 402. That's the “who” x402 deliberately left out. |
| Survive the “revoke” and persist elsewhere | One revoke tears down the /128, its PTR, and its DANE pin worldwide at DNS-TTL speed, verifiable by anyone, no membership required. No dormant registration outlives its own revocation; compromise one agent and you have compromised that agent, not every counterparty it ever touched. |
Provision an agent identity
Provisioning is one control-plane call to POST https://graph.whisper.security/api/query with your X-API-Key header. You pass the agent's public key material (the base64 SubjectPublicKeyInfo of the key behind its Agent Card / mandate signer / wallet) and its agent id as the device_id; you get back the deterministic /128 and a WireGuard config to source the agent's traffic from that address.
The call
CALL whisper.agents({op:'connect', args:{
tier:'wireguard',
identity_public_key:'<base64 SPKI of the agent key>', # public half of its Agent-Card / mandate / wallet key
device_id:'ag_9e0a9e7c14ab2e44f9' # the agent id, carried in A2A / AP2 / x402
}}) YIELD op, ok, status, result, error
RETURN op, ok, status, result, error
Over stock tools: jq builds the JSON body so the Cypher's own quotes never fight the shell:
# the public key only: the private key never leaves the agent's process / secure element
Q="CALL whisper.agents({op:'connect', args:{tier:'wireguard', \
identity_public_key:'MFkwEwYHKoZIzj0…SPKI', device_id:'ag_9e0a9e7c14ab2e44f9'}}) \
YIELD op, ok, status, result, error RETURN op, ok, status, result, error"
curl -s https://graph.whisper.security/api/query \
-H "X-API-Key: whisper_live_xxx" \
-H "content-type: application/json" \
--data "$(jq -nc --arg q "$Q" '{query:$q}')"
The response
# result carries the deterministic identity plus a ready-to-apply tunnel
address 2a04:2a01:9e0::a9e7
fqdn ag-9e0a9e7.<tenant>.agents.whisper.online
ptr ag-9e0a9e7.<tenant>.agents.whisper.online
state active # DNSSEC + DANE-EE (3 1 1) live at provision time
wireguard_config [Interface] … # source the agent's traffic from its own /128
The agent now has a name it can prove and an address it egresses from. Reverse DNS resolves the /128 to that identity, a TLSA record pins the leaf key, and RDAP registers the object under 2a04:2a01::/32. That's the full seven-proof chain, published atomically with the allocation, with each mint recorded in the Merkle transparency log.
Idempotency and errors
The call is deterministic and honest about conflicts: conservative in what it emits, liberal in what it accepts.
| You send | You get |
|---|---|
| The same device key + agent id again | The same /128: idempotent, safe to retry, safe to run on every start-up. No duplicate identities. |
| The same device key with a different agent id on your tenant | 409 Conflict. A device key binds to exactly one identifier, and the error.detail tells you which id it is already bound to. |
A non-string device_id (a number, an array, null) |
400 with an actionable detail, never an opaque 500. Send the agent id as a string. |
Shipped & live. This provisioning path (an agent /128 derived from the agent's public key + its device_id) is in production today. The device_id argument is generic: pass an A2A agent id, an AP2 signer reference, or your own agent handle. A first-class typed --agent-id flag is on the roadmap; today, provision through the control-plane call above, then drive it with whisper verify / whisper policy / whisper logs / whisper kill --revoke.
Revoke worldwide and govern in between
A compromised agent, a key rotation, an ownership change, a decommission: one call tears down the /128, its PTR, and its DANE pin everywhere at DNS-TTL speed. It's provable with the same stock tools that proved the identity existed, no Whisper software required.
# the control-plane op…
CALL whisper.agents({op:'revoke', args:{agent:'2a04:2a01:9e0::a9e7'}})
# …or the CLI
whisper kill --revoke 2a04:2a01:9e0::a9e7
# now prove it, worldwide, at DNS-TTL speed:
dig -x 2a04:2a01:9e0::a9e7 +short # -> nothing
curl -s https://whisper.online/verify-identity/2a04:2a01:9e0::a9e7
# -> {"is_whisper_agent": false, ...}
Revocation is the kill-switch the protocols never defined. But the same control plane governs what a live agent may reach in between. Because egress is source-bound to the agent's /128, policy is enforced by name and by address: default-deny, allow only your PSP and your facilitator, cap the traffic and spend, and kill it in one call:
# default-deny: this agent may reach ONLY its PSP and its x402 facilitator
whisper policy set --default deny --allow api.your-psp.com,facilitator.x402.org
# per-agent firewall (allow/deny by host, cidr or port) + a budget with a kill-switch
CALL whisper.agents({op:'firewall', args:{agent:'2a04:2a01:9e0::a9e7', deny:['0.0.0.0/0','::/0'], allow:['api.your-psp.com:443']}})
CALL whisper.agents({op:'budget', args:{agent:'2a04:2a01:9e0::a9e7', max_mb_per_day:200}})
A compromised agent can't phone an exfil host it was never allowed to reach, and a drained-wallet incident stops itself at the budget ceiling. This is the least-privilege layer identity makes enforceable: it does not stop a fully-authorized agent's bad decision, but it bounds the blast radius and makes every action attributable. Full policy surface: Egress governance.
Pin the agent's wallet: accountable x402
x402 is deliberately pseudonymous: the payment is an EIP-3009 authorization signed by the from wallet (an externally-owned account that proves control of funds, not which agent holds it, and that cannot be revoked). Pin-a-wallet converts that pseudonymous wallet into an accountable, revocable, publicly-verifiable agent, without changing a single line of the x402 flow. It is the exact wallet↔agent binding x402 omits and AP2 explicitly defers to FIDO.
The binding is a signed statement in the agent's own name, not a side database anyone has to trust. The agent issues a compact Verifiable Credential: a JWS whose issuer and subject are the agent's own did:web, signed with the same P-256 key family that backs its DANE TLSA pin. It asserts “this wallet is mine,” and publishes it next to its did.json:
# the agent publishes a signed wallet binding next to its did.json (issuer = subject = the agent)
# header: {"alg":"ES256","kid":"did:web:ag-9e0a9e7.<tenant>.agents.whisper.online#key-1"}
# payload: {"vc":{"type":["VerifiableCredential","AgentWallet"],
# "credentialSubject":{"chain":"eip155:8453","address":"0x9F2b…c41A","purpose":"x402"}}}
curl -s https://ag-9e0a9e7.<tenant>.agents.whisper.online/.well-known/wallets/eip155-8453.jwt
# a facilitator verifies the agent BEFORE honoring the 402: keyless, no account, no onchain change
whisper verify --trustless 2a04:2a01:9e0::a9e7 # establishes key-1 (DANE pin, DNSSEC to the IANA root)
# then check the JWS signature against that key with any stock JOSE library, and confirm it names the from-wallet
Honest status. Pin-a-wallet composes from primitives that ship today: did:web, DANE, the transparency log, and the keyless whisper verify --trustless check, plus one DIY step: signing the credential with a stock JOSE library. There is no single whisper pin-wallet command yet, and whisper verify today takes an address or FQDN, not a --credential file, so the credential's own signature is checked with the JOSE step above. It is the pattern you assemble from shipped parts. The full recipe: Pin-a-wallet · A2A-trust · verify.
Verify it: keyless, no account
The identity is public by design, so anyone (a merchant, a facilitator, a peer agent, a PSP, an auditor) can check an agent without your key and without taking Whisper's word for it. This is the keyless half of the two-tier surface: verify with no key, provision and govern with your key. It is also the a2a-trust step A2A and MCP lack: before two agents talk, each resolves the other's /128 and checks the DANE pin.
# no key, no account: re-derive and verify the agent's identity, trustless to the IANA root
whisper verify --trustless 2a04:2a01:9e0::a9e7
# or with only curl: the keyless full-chain verdict
curl -s https://whisper.online/verify-identity/2a04:2a01:9e0::a9e7
# { "is_whisper_agent": true, "dane_ok": true, "jws_ok": true, "evidence": { ... } }
# the address IS the agent: forward-confirmed reverse DNS names it
dig -x 2a04:2a01:9e0::a9e7 +short
# ag-9e0a9e7.<tenant>.agents.whisper.online.
# the registry object for the /128: RDAP, typed JSON
curl -s https://whisper.online/ip/2a04:2a01:9e0::a9e7 | jq '.handle, .parentHandle'
# "2A04:2A01:9E0::A9E7/128"
# "2A04:2A01::/32"
The --trustless flag is the point: nothing there calls back to Whisper's own API as an authority. The CLI re-derives the DNSSEC chain to the IANA root, on your machine, with your resolver. A merchant can verify an agent without joining Visa's directory or Mastercard's registry, and without trusting the platform that issued it. Full mechanics: Verify an agent and DANE & TLSA.
See who checked your agent
An identity you can prove is also an identity you can watch. Because every agent's name resolves through Whisper's own authoritative DNS and RDAP, the owner can ask who looked: both halves of the picture, and neither one the well-known JWKS ever gave you. A legitimate merchant vetting your agent before it transacts shows up here as verification analytics; an adversary enumerating your fleet shows up as a reconnaissance tripwire (step 01 of the kill chain), surfaced while it's happening:
# who resolved / RDAP-queried this agent's identity, and when
CALL whisper.agents({op:'lookups', args:{agent:'2a04:2a01:9e0::a9e7', window:'24h'}})
# the same reverse-observability view, keyless, per address
curl -s https://whisper.online/ip/2a04:2a01:9e0::a9e7/lookups | jq
# → one source resolved 4,000+ agent PTR/AAAA/TLSA records in 30 minutes: a fleet sweep, before any mandate is signed
Paired with op:logs (the agent's own outbound activity) and /ip/<addr>/transparency (its ordered lifecycle), you have what an agent reaches out to and who is reaching in to enumerate it: the cross-platform visibility each domain-in-isolation never had.
Name what already transacted as you
Identity stops the next impostor. It does not name the operator behind the sessions already in your logs, so the same platform back-traces them. The attribution survives the rotation because it fingerprints the operator's infrastructure and tooling, not the ephemeral egress IP.
Take a suspect egress IP straight from your fraud logs and ask the graph who really operates it. This runs read-only over the same public graph API, with your key:
# who really operates a host, even behind a CDN or a cloud front
curl -s https://graph.whisper.security/api/query \
-H "X-API-Key: whisper_live_xxx" -H "content-type: application/json" \
-d '{"query":"CALL whisper.identify(\"34.90.x.x\")"}'
# operator fingerprinted across AWS / GCP / Azure; residential swarm collapsed by JA4
The read-only verbs (identify, origins, walk, variants, history) run over that one endpoint against a live internet-infrastructure graph of fused BGP, DNS, WHOIS, TLS, hosting, and threat intelligence. Cloud rotation collapses through origins and walk, which cluster shared ASN, hosting, and certificate lineage into one infrastructure genealogy. You can express agent impersonation directly as read-only Cypher, such as “one source transacting as N distinct agent identities in a window.” Every answer is reproducible, replayable JSON: the paper trail a chargeback fight or a PSD3 audit needs, not a screenshot.
These graph verbs are the API surface: you call the endpoint directly, as above. There is no whisper identify / graph / export CLI subcommand; the CLI covers the control plane (create, verify, policy, logs, kill), and the graph is the query API. See Graph & cognition.
Honest scope: what this is, and what it is not
A verifiable, revocable agent identity is necessary. It is not, by itself, sufficient, so here is the candid line. Whisper closes the “which agent / for whom / prove it / attribute it / revoke it” gaps the payment protocols left open, and makes every other control enforceable and auditable. It is deliberately not several other things.
- Not a payment processor. We never settle a payment, tokenize a PAN, issue an Agentic Token, or move funds. Whisper is the identity layer beneath the tokens and rails: additive to A2A, AP2, x402, Visa and Mastercard, never a replacement.
- Not PSD2/SCA compliance itself. SCA assumes a human authenticates, and the EBA has ruled the responsibility “cannot be outsourced” (Q&A 6141). Whisper supplies the verifiable identity of the agent that acted under a mandate so the SCA/mandate evidence chain has a durable, attributable subject: evidentiary only, never an SCA factor. PSD3/PSR RTS alignment is forward-looking; the text isn't published.
- Identity is not intent. Identity proves who acted and for whom, not whether the decision was good. It does not stop a fraud a fully-authorized agent commits within its mandate; it does not prevent the prompt-injection of an agent's own reasoning (it faithfully attributes the hijacked-within-authority action and lets you revoke after); and it does not stop a confused-deputy trick inside granted scope. Those need spend caps, least-privilege mandates, injection defense, and human-in-the-loop, which the budgets, firewall and revocation above make enforceable and auditable. And a binding says which agent should hold a wallet; it can't stop a thief who has the private key itself; that's HSM/mTLS key custody, complementary.
- Not the only DNS-anchored scheme. We're candid: Identity Digital's DNSid, the Agent Name Service (ANS), and DNS-AID also anchor agent identity in DNS. Where they anchor a name or ownership record (DNSid, by its own words, “does not authenticate agents or enforce run-time policy”), Whisper differentiates on the working layer on top: a routable
/128(the address is the identity), egress governance, pin-a-wallet, DNS-TTL revocation, and a cross-platform attribution graph.
The honest one-liner: verifiable identity is the missing anchor the rails were built without, and the thing that makes spend caps, mandate scope, injection defense and human approval actually mean something. Not a substitute for the guardrails on top; the foundation they stand on.
Where it fits: standards, SIEM, integrations
Whisper is additive. It rides on top of the protocols you already speak and the SIEM you already run. It replaces none of them, and it never settles a payment.
Compliance. The per-/128 egress logs, the op:lookups stream, and the attribution graph are ready-made evidence for exactly the questions the new rails ask. Pinned identity plus one-call revocation maps cleanly to Mastercard Agent Pay (“only registered agents can transact, governed and traceable,” authorization revocable in real time; Whisper's “revocable in one call” mirrors the registry pull), and to Visa's Trusted Agent Protocol, where an agent proves identity with RFC 9421 HTTP Message Signatures against a well-known key directory. DNSSEC/DANE is a well-known, publicly-verifiable public-key directory, network-neutral instead of one silo. It is the durable identity an OpenAI/Stripe ACP delegated-payment token or an AP2 mandate points at, and it delivers the KYA pillars of “crypto identity” and “continuous accountability” directly. For PSD2/SCA and FATF Travel-Rule attribution the mapping is evidentiary and forward-looking, never a certification. The clause-by-clause detail lives in PSD2 · agent-payment protocols.
Nothing issued in the dark. Every identity mint and every revoke lands in a public, append-only RFC 6962 Merkle transparency log: Ed25519-signed C2SP checkpoints, each root anchored to Bitcoin via OpenTimestamps. It's an auditable, non-repudiable issuance and revocation trail a dispute or a regulator can replay, and the timestamp that proves a wallet binding predates the transaction under scrutiny. Honest status: it is tamper-evident and Bitcoin-anchored today, but not yet independently witnessed (our two servers co-signing is availability, not independence); the log already speaks the C2SP witness protocol, so any external witness can co-sign.
Shipped vs roadmap. The Splunk, Microsoft Sentinel and OpenCTI connectors ship today; findings arrive as signed JSON mapped to CEF and ECS fields. Roadmap, labelled as such and not yet available: STIX 2.1 over TAXII export, a per-sector machine-readable export, and the first-class typed --agent-id CLI/API argument.
Integrations (proposed, not vendor-endorsed). Whisper anchors the identity and IP boundary, never the interop protocol itself and never the settlement of a payment:
- A2A Agent Card. DANE-pin the card's
urlandAgentCardSignatureto the agent's/128, so a verifier resolves the identity and confirms “this card belongs to this agent” (stronger than a CA saying “belongs to the domain”), and revocation becomes pulling the DNS/RDAP record. Complements Signed Agent Cards; does not replace them. - AP2 mandate. Bind the VC's
verificationMethodsigner key to the DNSSEC/DANE-anchored/128, so the Credentials Provider and Merchant confirm the Shopping Agent's key is a verifiable, non-revoked agent: the Authenticity and Accountability AP2 explicitly defers to FIDO. Complements the mandate chain; never redefines it. - x402 wallet. Pin-a-wallet binds the
fromwallet to the verifiable identity so a facilitator honors the402for a known, revocable agent, no onchain-flow change. Complements settlement; we never move the funds. - MCP server & Cloudflare Web Bot Auth. DANE on the
/128is DNSSEC-anchored server identity beyond CA-trust and a2a-trust addresses the confused-deputy / token-passthrough threat; DNS-TTL revocation complements short-lived OAuth bearers and Web Bot Auth's per-request Ed25519 signatures. Complements; never the in-band handshake.
And it is built to fail open: a Whisper outage never blocks a checkout. Checks degrade to the anchors the rails already ship, and connectivity is preserved. Anycast on AS219419, no single node in the path.
Next
- Agent identity: how the
/128is derived from the agent's key and its id, in depth - Pin-a-wallet · A2A-trust · verify: runnable recipes covering pinning an x402 wallet, mutually verifying two A2A agents, and keyless-verifying a counterparty
- Control plane: the full
whisper.agentsop set the provisioning call belongs to - PSD2 · agent-payment protocols: the evidentiary mapping across A2A, AP2, x402, Visa TAP and Mastercard Agent Pay