DEV Community

minia2a
minia2a

Posted on Originally published at minia2a.uk

Signature-Valid Is Not Authorized

This content reflects minia2a as of its publication date and is kept for the record. Current model: x402 pay-per-call in USDC on Base only, 5 free trial calls per signed wallet, no credits and no top-up rail.

2026-10-18 · what an x402 payment record should carry

An x402 client sends a payment. The server verifies the EIP-712 signature, settles, and returns the goods. The payment is conformant. Now ask four different questions and the word falls apart.

  • Was the agent allowed to spend this money?
  • Was this endpoint inside the scope the principal granted?
  • Did the call actually deliver?
  • If it did not, does the record say who decided that, and what happened to the money?

None of these are answered by a valid signature. A signature proves that a key agreed to a payment. It does not prove the payment was authorized, scoped, or worth making — and it certainly does not record what happened afterwards.

What the current picture looks like

The volume is no longer a rounding error: Chainalysis reported roughly 138.5 million cumulative x402 transactions on Base by the end of Q3 2026. XRPL-based x402 payments passed 13.4 million, with a seven-day average around 216,000 per day at the time. The same Chainalysis report cautions that count is not value.

That caution is worth taking seriously. A one-week snapshot in October attributed about $294.5K of actual x402 service spend across Base and Solana, against a much larger gross USDC flow. Two chains, millions of calls, hundreds of thousands of dollars of paid demand per week. The protocol is being exercised far more than it is being trusted with money — and auditability is one reason. As one October critique put it, "conformant" currently means the payment signature verified, not that the payment was authorized. The x402 Foundation, which appointed its first executive director on 1 October and now lists 50+ members, has working groups forming. This is the right moment to argue about what a payment record contains.

Four failures a signature cannot see

These are not hypothetical. They are the shapes we hit running a pay-per-call platform where settlement and delivery are separate steps.

1. Refusal is not failure

A caller sends an invalid parameter. The handler rejects it with a 400-class error. Nothing was delivered. If the platform's counter treats that as an upstream failure, the endpoint accumulates strikes and eventually gets delisted — punishing the service for the caller's input. Signature-valid, payment settled, and the record is wrong about who caused it.

A payment record needs to separate caller error, handler failure, and upstream failure, because the remedy differs: refund, strike, or retry.

2. No deliverable is not no payment

Settlement can succeed before delivery fails. The money moved; the response says the job did not run. A record that only stores "signature valid" leaves the payer unable to answer the only question that matters: am I getting this back, and how do I know? The answer has to be a state, not a boolean — refund: enqueued | not-applicable | failed — plus the reason the state was chosen.

3. A retry is a new payment

Replay protection is real: the same signed payment must not be redeemable twice. But clients routinely read an error and retry with the same header. If the record does not say this payment is spent and locked, the client hammers a lock and learns nothing. "Retryable" belongs in the record, and for a settled-but-undelivered call the honest value is false — the retry needs a new payment, not a new request.

4. Unknown is not false

The most expensive bug class in agent tooling is not a wrong answer. It is an answer. When an upstream timeout or a null scalar is collapsed into 0, false, or "service unreachable", the agent acts on a fact that was never established. A payment record that inherits that collapse makes the ledger assert things the system did not observe. Unknown must be a first-class value in the record, and absence must never be rendered as a confident negative.

A shape that would carry it

Treat this as an optional extension, not a new status code. Design it so a verifier that ignores it loses nothing, and a verifier that reads it can audit the spend.

{
  "authorization": {
    "authority": {
      "principal": "did:example:org-42",
      "agent": "0x…",
      "grant": {
        "scope": ["x402:mime-type", "x402:wallet-balance"],
        "caps": { "perCall": "50000", "perWindow": "2000000", "window": "1d" },
        "expires": "2026-11-01T00:00:00Z"
      },
      "chain": ["did:example:org-42", "did:example:team-7", "0x…"]
    },
    "decision": {
      "band": "auto-approve",
      "policy": "sha256:…",
      "reason": "within per-call cap and endpoint scope"
    },
    "outcome": {
      "status": "delivered | refused | failed | not-measured",
      "settled": true,
      "refund": "enqueued | not-applicable | failed",
      "retryable": false,
      "evidence": "sha256:…"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Carry it in the 402 response's extensions as a policy offer (what the server will record), and echo the filled record in the settlement receipt. The payer and any auditor can then answer the four questions without trusting either party's prose.

Constraints that make or break it

  1. Fail-open. If a client omits the extension, the call proceeds. A required field would fragment the ecosystem overnight.
  2. Bounded size. The challenge already travels in a header. Every addendum spends a byte against a hard limit; keep the record compact and hash the evidence instead of inlining it.
  3. No secrets. Scope names endpoints; it must not name parameters, prompts, or payloads. A hash is enough to prove consistency later.
  4. Outcome is three-valued at minimum. Delivered, refused, and not-measured are different worlds. Collapsing them is how ledgers start lying.
  5. The record must survive refusal. If the record only exists on successful delivery, the cases that matter most — paid and not delivered — are the ones with no record.

What to do with this

If you are building x402 services: start recording outcome and refund state next to the payment, even before any standard exists. It costs one row and it is the difference between "we took the money" and "we know what happened." If you are working on the spec: the authorization record is a smaller change than a new protocol version, and it addresses the criticism that transaction count keeps growing faster than trust.

The next phase of agent payments will not be won by the chain with the most calls. It will be won by the rails whose records can be audited after something goes wrong. Signature validity is the entry ticket. The record is the product.

Sources: BraveNewCoin / Chainalysis · XRPL cumulative x402 payments · October critique of x402 conformance. The $294.5K attributed-spend figure is a one-week third-party tracker snapshot, not a settlement total.


Originally published at minia2a.uk.

Top comments (0)