docs / guide

view as .md

Agent tokens (agent-zk)#

An enrolled agent authenticates with an agent-zk deed: a zero-knowledge proof that it belongs to your tenant's on-chain membership registry, without revealing which member. There's no browser, no issuer, no /token endpoint, and no client secret — ZkAgent.mintDeed (every language) is the entire mint API. If you haven't already, read Concepts for the mental model (deeds, pseudonymity, the on-chain trust anchor).

Don't need on-chain enrolment? Use user-sig instead#

If your agent is authenticating straight to an app's own API and you don't need per-agent revocation or anonymous membership, the permissionless user-sig mode needs no enrolment round trip — any signing key works. See Wallet login; the same authenticate() helper composes discover → challenge → mint for you:

import { authenticate } from "@grantor/agent";

const deed = await authenticate("https://api.example.com", signMessage, {
  chainReader,
  chainRegistry: REGISTRY,
});

chainReader (an eth_call seam) and chainRegistry (the on-chain registry address YOU trust, pinned out-of-band) are REQUIRED: authenticate() uses them to verify the application can show a tenant admin's on-chain vouch for this origin before it signs anything. See Constructing a chainReader.

The agent-zk recipe#

authenticate() does not apply to agent-zk — an already-enrolled agent composes discover(), a challenge fetch, and ZkAgent.mintDeed by hand instead. The full worked example (all four languages), the same-origin rule, and the origin-provenance vouch check mintDeed performs before it proves, are documented once, in Sovereign tier § What it is and § Discovery — how an agent finds all this. Read those rather than a second copy here.

⚠️ Read the caveats, not just the recipe. mintDeed's provenance check closes agent-zk cross-origin linkability and membership disclosure by prevention — but only when your holder actually runs it, and only against an origin that has published a valid vouch. See Sovereign tier § Origin binding — what this closes, and what still does not and § Origin provenance for exactly what is and is not closed today.

Prerequisites (one-time, on-chain, done by the tenant operator)#

Before an agent can mint an agent-zk deed, the tenant operator must, on GrantorRegistry:

  1. createTenant and keep it funded (Active or Grace — see Concepts).
  2. registerZkAgent — enrol the agent's Semaphore identity commitment in the tenant's on-chain membership tree (registerZkAgentBatch to enrol several agents in one call).
  3. Sign and publish an origin vouch for the app's origin, so ZkAgent.mintDeed's provenance check can pass — see Sovereign tier § Origin provenance. A tenant admin revokes a vouch with bumpOriginEpoch if an origin is decommissioned or compromised.

Verifying it#

Your app verifies an agent-zk deed exactly the way it verifies a user-sig one — the same DeedGuard/DeedVerifier, the same verify_deed call. See Verify a deed.

Full agent-integration walkthrough#

See Agent integration and Agent onboarding.

This page is also served as Markdown — agents should read that. The whole tree is indexed for machines in llms.txt.