Docs · Reference
Revocation.
A credential is signature-valid forever. Freshness is a separate question. Revocation is how PoA tells verifiers that a still-valid signature should no longer be trusted.
Two paths into the revocation list
Operator-initiated
The controller can revoke at any time. Same shape as issuing: request a challenge, sign a revoke message, post to /poa/api/revoke. The signed message uses a different prefix from issuance, poa-revoke:<agentId>:<nonce>, so a signature collected for one operation cannot be replayed for the other.
# 1. Get a challenge
curl -X POST https://theseus.network/poa/api/challenge \
-H 'content-type: application/json' \
-d '{ "agentId": "5GrwvaEF...HGKutQY" }'
# 2. Sign 'poa-revoke:<agentId>:<nonce>' with the controller key
# (same wallet flow as issuing, different prefix)
# 3. Post the revoke
curl -X POST https://theseus.network/poa/api/revoke \
-H 'content-type: application/json' \
-d '{
"agentId": "5GrwvaEF...HGKutQY",
"nonce": "...",
"signatureHex": "..."
}'The credential is marked revoked with reason operator-revoked. The credential page immediately shows the void state. The verify endpoint reports freshness.status === "revoked" on the next request.
Automatic, on chain state change
PoA periodically reconciles every active credential against live chain state. A change that contradicts the signed snapshot triggers revocation with one of these reasons:
- agent-deregistered. The agent no longer has an
AgentInfoon chain. - balance-zero-90d. The agent is in the dormant or collectable state. State is removed at ninety days at zero seus balance; PoA marks the credential void as soon as the funding goes inactive.
- abg-changed. The on-chain ABG hash no longer matches the snapshot. The agent's behavior surface has been updated; the old credential is no longer descriptive of what runs.
- controller-rotated. The controller account on chain is different from the one that attested to the credential.
- sovereignty-flipped. Only meaningful once the chain implements sovereignty. A credential issued claiming the agent was sovereign is revoked if the agent later acquires a controller.
The public list
GET /poa/api/revoked returns every revoked credential the issuer knows about. Use it for offline verification or for caching the freshness check independently of /poa/api/verify.
{
"issuer": "theseus.network/poa",
"generatedAt": "2026-05-03T12:00:00.000Z",
"revoked": [
{
"jti": "01HQXY...",
"agentId": "5GrwvaEF...HGKutQY",
"reason": "abg-changed",
"at": 1735689600000
}
]
}The list grows monotonically. Credentials do not come back from revoked. To re-credential an agent after a revoke, the operator mints a fresh credential, which gets a new jti.
What revocation does not do
- It does not invalidate the JWS. The signature still verifies. Verifiers must check the revocation list separately. That is why
/poa/api/verifyreportsvalidandfreshnessas independent fields. - It does not touch the chain. Revocation lives in the issuer's store. The on-chain agent is unaffected.
- It does not delete data. The original credential and its signed claims are still retrievable at
/poa/api/credential/<jti>withrevokedpopulated.
Sovereign agents and revocation
A sovereign agent has no controller, so the operator-initiated revoke path is unavailable. There is nobody authorized to sign the revoke message. This is by design: a sovereign agent's credential can only be invalidated by chain state changes that the agent itself cannot make. In the current alpha, no agents are sovereign; this constraint is documented for the future.