Verification in an agent payment is the set of checks performed in the seconds before money moves — not the paperwork done when an account was opened. At that moment a payment service is handed a request from software claiming to act for a human, pointed at a merchant it has probably never transacted with, carrying signed artifacts it must decide to believe. Three questions have to be answered under a hard latency budget: is each party who it claims to be, is the requesting agent actually permitted to spend this user’s money in this way, and is the counterparty legitimate? Getting these confused — treating a valid signature as proof of permission, or a known merchant name as proof of merchant identity — is how otherwise sound systems authorize fraud. This piece walks the runtime checks, the order to run them in, and what to do when the answer is neither yes nor no.

Two different questions: authentication and authorization

The most common failure in payment verification is collapsing two questions into one. Authentication asks who is this party? It is answered with cryptography and credentials: a signature that verifies against a known key, a device attestation, a session bound to a biometric unlock. Authorization asks a completely different question — is this authenticated party permitted to do this specific thing? That is answered by policy and by the scope of the authority the user actually granted.

An agent can be perfectly authenticated and still wholly unauthorized. Its key may be genuine, its request well-formed, its signature valid — and the purchase still outside anything the user ever approved: wrong merchant category, wrong amount, an authority that expired last week. A verifier that stops at ‘the signature checks out’ has answered only the first question. In agent payments the second one carries most of the risk, because the party presenting valid credentials is software that can be induced to act against its principal’s interest without its keys ever being stolen.

Advertisement

The authority chain back to the user

Every agent-initiated payment should be traceable, by verification rather than by assumption, to a human decision. The chain has links: a user authenticated to their wallet or account provider; that user granting a scoped authority to a named agent; the agent presenting a request that falls inside that scope; and the specific transaction being covered by the specific grant, not merely by some grant.

Verifying the chain means checking each link and each join. A grant issued to agent A does not authorize agent B, even if B is operated by the same vendor. A grant made under one user session does not survive that user revoking access. And critically, the chain must be checked toward the principal: start from the transaction and walk back to a human act, rather than starting from a credential and assuming a human stands behind it. Delegation adds depth — an orchestrating agent invoking a sub-agent creates another link, and unverified depth is where authority silently widens.

Validating credentials, chains, and trust anchors

Verifying a credential is more than a signature check. A signature tells you that the holder of some private key produced this data. Turning that into an identity requires anchoring: the key must chain, through certificates or an issuer registry or a resolvable identifier document, to a trust anchor the verifier independently decided to trust. Everything hangs on that anchor, and it must be configured, not discovered from the message being verified: a credential that supplies its own root of trust proves nothing.

The practical checklist is unglamorous and each item has caused real incidents: the signature algorithm is one you accept (never one the message names for you); the chain terminates at a configured anchor; every certificate in the path is within its validity window; the credential’s subject really is the party making the request; and the credential’s stated purpose covers payments. A correctly signed credential presented by someone other than its subject is a replayed credential, not an identity.

Freshness: expiry and revocation

Credentials are statements about the past. A certificate issued three months ago asserts what was true then; keys get compromised, employees leave, agents get decommissioned, and users revoke access. Verification therefore has a time dimension: is this credential still good right now?

Expiry is the cheap half — a date comparison, worth doing always, with attention to clock skew and to the fact that a short-lived credential is safer precisely because it limits how wrong a stale answer can be. Revocation is the expensive half. Status can be pulled from a published revocation list, queried from a status endpoint, or read from a compact status registry, and each option trades freshness against latency and availability. The design question that matters is what happens when the status source is unreachable inside your payment window. Failing open quietly converts a revoked agent into a spending one; failing closed converts a status outage into an outage of your own. Pick per risk tier and state the choice explicitly.

Verifying the merchant, not just the payer

Verification is usually described as the network checking the payer. In agent payments the arrow points both ways, and the neglected direction is more dangerous. A human shopper has weak but real defenses against an impostor storefront — the look of the page, an odd URL, a gut feeling. An agent has none of that. It will pay whatever endpoint its instructions and its search results led it to.

So the agent side needs its own verification: the merchant’s domain genuinely controlled by the entity it names, its payment endpoint presenting a valid certificate for that domain, its merchant identity signed by an acquirer or registry the wallet recognizes, and the party that will actually be credited matching the party the user intended to pay. Homograph domains and lookalike checkout endpoints are cheap to produce and invisible to a system that only verifies the payer. Where a merchant cannot be verified, that is itself a signal.

Advertisement

Step-up authentication and when to demand it

Step-up is deliberate friction: pausing the flow to obtain a fresh, human-present authentication — a biometric confirmation, a device prompt, a challenge from the issuer — before proceeding. It is powerful and it is expensive, because every step-up costs conversion and trains users toward reflexive approval when overused. The discipline is to trigger on risk, not on ritual.

Sensible triggers are all forms of ‘something about this transaction sits outside what the user already approved’: an amount above the granted ceiling, a merchant or category outside the authority’s scope, a first transaction with an unfamiliar counterparty, a new device or agent instance, an authentication that has gone stale, or a risk engine flagging anomalous velocity. Step-up should escalate to the human, not to the agent — a challenge an agent can answer on the user’s behalf verifies nothing about user presence. Regulated flows may separately require strong customer authentication with its own exemption rules; treat those as a floor, not as your whole policy.

Binding the check to this transaction

A verification result is only as good as what it is bound to. If the checks confirm a party and the party then submits a different transaction, the verification has been laundered. Binding closes that gap: the verifier must check that the signed artifact it just validated actually commits to the transaction now being executed, rather than accepting it as a general token of goodwill. A signature over one purchase must not be liftable onto another.

Three mechanisms do most of the work. A nonce supplied by the verifier proves the response was produced now rather than replayed from a captured session. A timestamp with a tight acceptance window bounds how long a valid response stays useful. An idempotency key ties the exchange to exactly one movement of money, so a retried request cannot become a second payment. Combined, they turn ‘this party is legitimate’ into the far narrower claim ‘this party authorized this payment, once, just now.’

The latency budget inside a payment flow

Every check listed so far consumes time, and payment flows are not patient. Users abandon; timers at the acquirer and the scheme expire; an agent orchestrating a multi-step purchase compounds each delay. Verification design is therefore budgeting, not maximizing: decide how many milliseconds the whole check may take, then spend them where they buy the most risk reduction.

The structure that usually falls out is a fast local path plus a narrow remote path. Signature and chain validation, expiry, scope and policy evaluation are local computation and cheap. Remote lookups — revocation status, merchant registry, risk scoring — are the costly ones, and should be cached with deliberate TTLs, run in parallel rather than in series, and given per-call timeouts with defined behavior on timeout. Order matters too: run the cheap deterministic checks first so an obviously invalid request is rejected without ever paying for a network round trip.

When the result is inconclusive

Verification has three outcomes, not two. Verified and failed are easy. The third — the revocation endpoint timed out, the registry returned an unparseable answer, the merchant certificate is valid but its identity attestation is missing — is where most bad decisions are made, because the tempting response is to treat ‘we could not check’ as ‘nothing was wrong.’ It is not. An attacker who can degrade your status lookup gets exactly that conversion for free.

Handle it as its own class. Route inconclusive results to a defined action tied to risk: below a low-value threshold, proceed and record the gap; above it, demand step-up so a human absorbs the uncertainty; above a higher threshold, decline and tell the agent to retry rather than silently approving. Whatever the choice, the response to the agent should distinguish ‘denied’ from ‘could not determine, retry’ — an agent that cannot tell them apart will either hammer a permanent failure or abandon a transient one. Record which checks ran, which were skipped, and why: when the charge is disputed months later, that record is the only reconstruction of how the decision was reached.

Runtime verification answers three questions in the seconds before money moves: is each party who it claims to be, is this agent permitted to spend this user’s money this way, and is the merchant real. Keep authentication and authorization separate — a valid signature is never a grant of permission. Walk the authority chain from the transaction back to a human act, anchor every credential in a trust root you configured rather than one the message supplied, and treat revocation as first-class. Verify the merchant too, because an agent has none of a human’s instincts about a fake storefront. Bind the result to this transaction with a nonce, a timestamp, and an idempotency key so it cannot be replayed. Budget the latency deliberately: cheap local checks first, remote lookups cached and parallel. And give inconclusive its own path — step up or decline, but never let ‘could not check’ quietly become ‘approved.’