Skip to main content
An attested_only service that checks attestation once at signup and thereafter trusts the agent’s signature has a blind spot (§8.5): an attestor-side revoke or disable never reaches it. The stolen key keeps working until that service’s own revocation list catches it. §10.7 closes that gap without paying the cost of re-checking attestation on every request. The service keeps a currently-valid attestation on file per account — an attested session — and challenges with 401 attestation_required once it lapses. The agent answers by minting a fresh attestation and retrying. Revoke the binding at the attestor and the agent can no longer mint, so every attested-session service drops the account within its freshness window. It’s the OAuth refresh pattern applied to attestation: the agent’s live binding at the attestor is the refresh grant — it re-mints by signing /v1/token with its account key — the attestation is the short-lived access token, and revoking the binding kills the access within the access token’s lifetime.
Opt-in, for attested_only services (the defineService default). Advertise support with the attested_session feature in your discovery document. Services that don’t opt in keep the signup-only behaviour.
The feature has two ends that line up: the service gates on freshness; the agent refreshes on challenge.

Service side — gate on freshness

Configure attestedSession on your Server (alongside the attestor you already use at signup) and call verifyAttested on your own authenticated routes:
verifyAttested:
  1. verifies the RFC 9421 signature (the per-request authenticator);
  2. if the request carries an AFAuth-Attestation header, verifies it (audience-pinned to your serviceDid) and slides the freshness window forward;
  3. throws 401 attestation_required when no currently-valid attestation is on file.
The signature is always required — the attested session is an additional liveness gate, never a replacement for it. For requests with a body, pass it so the content digest can be checked: server.verifyAttested(req, bodyBytes).

Strict vs extended

On Cloudflare Workers

The gate is reactive — no background timer — so the only difference is where attestedUntil lives. Use the KV-backed store from @afauthhq/worker; it sets each KV entry’s TTL to the remaining window, so lapsed sessions self-evict:

Agent side — refresh on challenge

Wrap your Agent and TrustClient (both constructed with the same key) in an AttestedFetcher:
On 401 attestation_required it mints a fresh attestation (via trust.token()), re-signs with a fresh nonce, and retries once. Any other status — including a 401 with a different code — is returned unchanged.
  • Reactive (default). The attestation rides only the retry, so steady-state requests carry no attestation header.
  • Proactive (proactive: true). Attach a (cached) attestation on the first attempt to skip the extra round-trip at each window boundary.
A refused mint surfaces as a terminal TrustHttpError — don’t retry it, re-link instead:
The loop retries at most once, so a revoked binding fails fast instead of hammering the attestor.

Revocation latency, honestly

Revoke or disable at the attestor and the agent can no longer mint. Each attested-session service then drops the account within its freshness window — strict within the attestation TTL (≤ 15 min), extended within your sessionTtlSeconds. That’s the deliberate trade-off:
  • vs per-request attestation (instant revocation, but the attestor is on every request’s critical path);
  • vs signup-only (no per-request cost, but never revokes — the blind spot).
Agents re-mint roughly once per service per window. The trust attestor caps mints per binding per UTC day (TRUST_PER_BINDING_DAILY_TOKEN_LIMIT, default 10,000); raise it for very high service fan-out. A throttle returns 429 rate_limiteddistinct from a revocation.

Further reading

  • Revocation — the global-vs-local model an attested session fits into.
  • Attestation — the §10 mechanism and the afauth-trust attestor.
  • Recover a compromised key — how attested sessions make an attestor-side revoke reach already-signed-up services.
  • Spec §10.7 and §8.5 — normative rules and revocation coverage.