docs / guide

view as .md

Errors#

The strings your app branches on when a deed fails to verify, plus the handful an operator's own boot-time self-check can raise. Source of truth: crates/grantor-verify/src/guard.rs's Rejected enum — the same codes in every language.

Verifying a presented deed#

These are what DeedGuard/DeedVerifier returns from a normal request — see Verify a deed. code() is the stable string an app branches on.

HTTPCodeWhen it happens
401MissingDeedThe caller sent no X-Grantor-Deed header.
401MissingChallengeThe caller sent no X-Grantor-Challenge header.
401UnknownChallengeThe challenge is unissued, expired, or already spent — burned before verification, so this also fires for a flood of bogus deeds.
401BadDeedEncodingThe deed header is not base64url JSON (a bare JSON object is tolerated).
401UnsupportedModetoken.mode is not one this verifier accepts (only agent-zk/user-sig reach verify_deed; admin-sig has its own entry point).
401WrongAudienceThe deed was minted for a different aud/tenant than this DeedPolicy.
401ChallengeMismatchThe deed is bound to a different challenge than the one presented.
401ExpiredPast its own exp, or exp exceeds the policy's max_ttl_secs.
401MalformedWrong field shape for its claimed mode (e.g. agent-zk carrying pubkey/signature, or user-sig carrying root/proof).
401BadProofThe ECDSA signature (user-sig) or Semaphore ZK proof (agent-zk) failed to verify.
401StaleRootagent-zk only — the membership root has aged out of the registry's recent-root window; possible revocation.
401TenantInactiveBilling — the tenant is neither Active nor Grace on-chain.
503ChainAn on-chain read (eth_call) failed.

Chain is 503 rather than 401 deliberately: an RPC outage is not the caller's fault, and answering 401 sends clients into a login loop that discards good credentials and cannot succeed. The verifier fails closed — if the chain cannot be read, no deed is accepted.

Ordering is load-bearing: a token that's the wrong version, wrong audience/tenant, wrong/replayed challenge, expired, unparseable, or carrying a bad proof fails before either chain read, so most rejections cost zero RPC calls. See Sovereign tier § What the verifier checks for the exact order.

The operator's own origin-vouch self-check (boot-time, not caller-facing)#

These three codes are not returned while verifying a caller's deed — they come only from DeedGuard::verify_own_origin_vouch / verifyOwnOriginVouchAt, the DX check an RP calls once at boot to catch its own misconfigured vouch before it causes a stream of failed logins. See Sovereign tier § Origin provenance.

CodeWhen it happens
OriginVouchExpiredThis guard's own origin vouch is past its exp. Checked before any chain read.
OriginVouchTtlExceededThis guard's own vouch has an exp further out than the maximum accepted TTL (90 days). Checked before any chain read.
BadOriginVouchThe vouch signature is malformed, or the chain says the recovered signer is not a current voucher for this tenant/epoch.

See also#

This page is also served as Markdown — agents should read that. The whole tree is indexed for machines in llms.txt.