x402 handles the payment — what handles the identity?#
x402 is a clean answer to a real question: how does an agent pay for a request without a human, a card, or an account? A 402 with a payment requirement, a USDC settlement, done.
But paying is not the same as being allowed. Once the money clears you still don't know who is calling, whether they're a member of anything, or how you'd revoke them tomorrow. x402 doesn't answer that — and it shouldn't; it's a payment protocol, not an identity one. The agent web needs both halves.
Two gates, not one#
The pattern is to stack them. The payment gate (402) sits outermost; behind it, an identity gate (401) checks a credential. An agent pays, and then proves who or what it is:
request → [ 402: pay in USDC ] → [ 401: present a deed ] → handler
The identity half is a Grantor deed — a self-certifying credential the relying app verifies in-process against a public on-chain registry, with no authorization server anywhere. In agent-zk mode the agent proves it's an enrolled member of your registry without revealing which member; membership is the authorization, and rotating the on-chain root is the revocation. Payment says they paid; the deed says who they are and whether they're allowed.
One chain, one asset, no facilitator in between#
The reason this pairs so cleanly is that both halves live on the same chain in the same asset. An agent earns USDC through x402 settlements on Base, and funds its own access with that same USDC — topUp is a public contract call on the registry, no bridge and no facilitator between the money it earned and the identity it needs. Money in, identity out, one hop. Becoming a paying tenant is four ordinary calls (createTenant → topUp → drawPeriod → enroll); the only human moment is funding the wallet once.
It runs today#
There's a working reference: an x402 server with the payment gate outermost and a deed identity gate inside it, end to end (just x402-e2e). Both the 402 payment challenge and the 401 deed challenge are wire-faithful.
Honest caveat: the example's settlement uses a devnet shim — the mock USDC it runs against has no EIP-3009, so production settlement swaps in a real EIP-3009 token. The pairing pattern — payment outermost, deed inside, same asset same chain — is exactly what ships. It's an unaudited developer preview, live on Base mainnet (8453) with a free Base Sepolia (84532) path.
The short version#
- x402 answers did they pay?
- A deed answers who are they, and are they allowed?
- You want both, and they compose on one chain in one asset.
Try it#
- The deed verifier:
@grantor/verify(npm),grantor-verify(PyPI, crates.io) — TypeScript, Python, Go and Rust. - The kit:
npx grantor-onboard preflight. - The machine channel: llms.txt.
- More on the model: OAuth with no authorization server.