rate_limit_exceeded (429) in §11.3 but takes no position on policy — you choose the limits and the backend. The Server enforces per-route limits when you give it a RateLimiter and a per-route config; everything beyond the protocol routes — your app’s abuse and quota controls — is yours to layer on top.
Turn on per-route limits
Supply arateLimiter and a rateLimits map. Each named route enforces its own limit; routes you omit aren’t limited.
`${route}:${agentDid}` — per route, per agent DID (the signing keyid). Claim completion is keyed by token; the owner-gated key operations are keyed by owner userId, since those are owner-authenticated rather than agent-signed. An exhausted bucket returns 429 rate_limit_exceeded with a Retry-After header.
Choose a backend
RateLimiter is a one-method interface, so you can back it with anything:
| Implementation | Backend | Use for |
|---|---|---|
MemoryRateLimiter (@afauthhq/server) | in-process map | tests, single-instance services |
KvRateLimiter (@afauthhq/worker) | Workers KV, fixed-window | Cloudflare deployments |
| your own | Redis token bucket, Durable Object, Cloudflare Rate Limiting | horizontally-scaled production |
Limit the human, not just the key
Per-DID limits don’t stop a Sybil: an attacker spins up fresh keypairs, each with its own bucket. The defense is to bucket on the account, which groups all of a human’s agents. A default (attested_only) service attaches every agent carrying the same per-service human pseudonym sub_h onto one account_id (§10.4.4) — so a human’s whole fleet shares one quota no matter how many keys they spin up. For application-level quotas, bans, and abuse counters, key on account_id (resolve it with accounts.getByAgentDid(did)), not on the agent DID:
Client side — honor Retry-After
A well-behaved agent backs off on 429 instead of hammering:
429 rate_limited from the trust attestor (minting attestations too fast) is distinct from a service 429 and from a revocation — back off, don’t re-link. See Keep attested access live.
Where to next
Attestation & sub_h
How a human’s fleet groups onto one account.
Error codes
rate_limit_exceeded and the rest.Deploy to Cloudflare Workers
KvRateLimiter and the durable stores.Verify a request
Authenticate before you meter.