401 revoked_key. Revocation is an owner-binding operation: it’s gated on a fresh owner-authenticated session, never the agent’s signature (the whole point is that the key may be stolen). An agent cannot revoke its own claimed account — that’s the two-step-verify invariant.
Turnkey: handleKeyRevocation
If you advertise the key_revocation endpoint, extract the owner session with your own auth layer and hand the request to the SDK:
account_id, or by any one of its agent credentials via agent_did (revoke the account that device belongs to). It enforces the §7.5 freshness floor, checks the session owns the account, then revokes — blocking every credential on the account (§10.4.4: one account, many devices). Response: 200 { account_id, revoked_at }. Re-revoking is idempotent.
Bare primitive: Server.revoke(accountId)
For internal or abuse-handling tooling, Server.revoke(accountId) marks the whole account revoked and adds every one of its agent credentials to the revocation list. It’s un-gated, so you must gate it on a fresh owner session yourself. If you only hold a credential DID, resolve its account first:
examples/recipes/revoke.ts for both paths.
After revoke: resume by re-keying
Revoke pauses the agent. To bring it back, the owner re-keys — installs a fresh key on the same account from an owner session (§8.2). Walk the full incident flow in Recover a compromised key.Coverage & limits
This is the local lever; the revocation model sets it beside the global one (an attestor-side binding revoke).- Per-service. Revocation is local to your service; there’s no cross-service revocation transport (§8.3). An owner recovering from compromise acts at each service and at the trust attestor.
- In-flight attestations. If you gate on trust attestations, revoking the binding at the attestor stops new tokens — already-issued ones stay valid until they expire (≤ 15 min). Revoke at your service too for an immediate cut-off. Recovering a stolen key end to end? Follow the ordered runbook in Recover a compromised key.