Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Bundles & grants

The share/verify exchange is the product’s central moment. This page covers the share grant (the worker’s consent record), the sealed verification bundle (everything a verifier needs, offline), and how the two move between wallet, registrar, and verifier.

The share grant

A share grant is signed by the worker’s per-employer key — it is the consent record, not a server setting. It names a grant_id, the exact attestations being disclosed, the audience (a known verifier key, or a link), the scope (view or monitor), and an expiry.

The granularity dial lives here: a threshold-only share lists only the threshold attestation, and the bundle built for it contains no bytes of the exact variant at all. Selective disclosure is enforced by what is in the bundle, not by hiding fields. A matching holder-signed revocation withdraws a grant — killing future fetches and recency, though it cannot delete copies already viewed.

The verification bundle

The bundle is self-contained, enough for fully offline verification:

FieldSigned byWhat
employer descriptorEmployerthe root employer record
KYB attestationKYB attesterbinds the employer key to a legal entity
epoch chainEmployerthe epochs back to the first
delegationsEmployerthe delegations covering the granted mints
attestationsRegistraronly the granted variants
supersede entriesRegistrarfamily-supersession evidence, when it exists
revocation commitmentsthe public commitments as of the checkpoint
latest checkpointRegistrarthe freshness anchor (“as of”)
grantHolderthe consent record
inclusion receiptsRegistraroptional extra witness evidence

The verifier presents this bundle together with a presentation context — who it has authenticated as, and whether it wants a view or a monitor. That context is an input to the verify predicate, which checks the grant’s audience against it, so a bundle sealed for one verifier cannot be replayed by another.

Sealing

The bundle is sealed (age-style: X25519 + ChaCha20-Poly1305) to its audience. When the verifier’s key is known, it is sealed to that key; otherwise it is sealed to a key derived from the link secret. The capability URL carries the secret while the stored grant carries only a hash of it, so the registrar never holds the secret itself.

The exchange

  1. The wallet signs the grant, seals the bundle to the audience, and stores both with the registrar (POST /grants).
  2. The worker shares a link or QR code. Opening it fetches the sealed bundle (GET /share/:grant_id); that fetch lands in the worker’s access log.
  3. The verifier unseals the bundle and runs the predicate. For a live recency check it also pulls the public checkpoint and revocation list; for an offline check it uses only what the bundle carries, and the verdict shows the head age either way.
  4. A billing call (POST /verifications) records the verdict and issues a receipt.

Monitoring

A monitor-scope grant additionally authorizes a subscription. Polling it returns event classes only — that employment status changed, an attestation was superseded, or the grant was revoked — never the new values. Learning what changed requires a fresh share the worker consents to, and the subscription dies with the grant.