Install
- pnpm
- npm
- yarn
Configure a Server
defineService is the opinionated convenience factory. It returns a
Server — the same class that wraps
Verifier and exposes endpoint handlers for
discovery, signup, account introspection, owner invitation, claim
completion, and key rotation — but with two spam-resistance switches
flipped ON by default:
- Discovery advertises
billing.unclaimed_mode: "attested_only"(§9.2). - The attestor defaults to
trustAttestor()(AFAP-0006 §10).
sub_h (§10.4) — are grouped onto one account (§10.4.4: one account,
many devices). Bucket your free-tier quota, rate limits, and bans on the
account and a human’s whole fleet shares one bucket, no matter how many
keypairs they spin up — while their legitimate PC and phone agents both
keep working.
Because this default rejects un-attested signups, an agent reaches your
service by linking to a human at trust.afauth.org
and presenting an
AFAuth-Attestation JWT — the agent
quickstart shows that step
(the afauth signup CLI auto-mints it). To accept un-linked agents while
you ramp, set attestation: "optional" below.baseUrl: /afauth/v1/accounts, /afauth/v1/accounts/me/owner-invitation,
/afauth/v1/accounts/me/keys/rotate, and /afauth/v1/claim (plus the
/claim claim page). These match the paths @afauthhq/agent signs, so a
default agent interoperates out of the box. To customize paths, advertise
additional accepted_attestors, or declare limits, pass a discovery
override — it merges on top:
HmacAttestor, or fully custom
discovery, drop to new Server({...}) directly — see @afauthhq/server
overview.
Route incoming requests to the handlers
Verify it works
Hit the discovery endpoint:Verifier in your own test suite — @afauthhq/server’s test suite already does this, so cloning that pattern is the fastest path. The canonical vectors live at AFAuthHQ/spec/vectors.
Production checklist
- Swap
Memory*stores for durable backends.@afauthhq/workershipsD1AccountStore(multi-agent accounts; atomic device-grouping via the(iss, sub_h)index),KvNonceStore,KvRevocationList. See Deploy to Cloudflare Workers. - Replace
consoleEmailHandlerwith a real email transport. - Host the claim page — the SDK doesn’t route it for you because it’s service UI. Reference:
examples/worker/src/index.ts. - Decide your billing mode. The
defineServicedefault isattested_only— setattestation: "off"to opt out, or"optional"for a migration path.
Next steps
- The ceremony — what your service is actually enforcing, and why.
- Error envelope — the shape your service must return.
@afauthhq/serveroverview — full API surface.