Identity operations
Every operation, one by one: what the shipped validators do, and what the M1 return replaces it with.
Where this page stands
The Shipped today sections describe programs published on preprod and
exercised by settled transactions. The Under the accepted design sections
describe the accepted design,
proved in lean/CardanoKeri/Checkpoint.lean and playable in the
checkpoint simulator. Nothing designed is built. For evidence and
transaction IDs, start with the story ladder.
A KERI AID (Key Event Receipt Infrastructure Autonomic Identifier) has a signed KEL (Key Event Log). cardano-keri does not put the whole KEL on Cardano. It stores one current checkpoint in a sovereign UTxO (unspent transaction output) identified by a quantity-one token derived from the AID.
The datum
Shipped today, CheckpointDatumV1 is pure key state — nine fields, no
lifecycle flag (onchain/lib/cardano_keri/checkpoint/datum.ak):
- the AID;
- current controller public keys and their weighted threshold;
- commitments to the next controller keys and their next threshold;
- the current KERI witness set and its threshold, called
toad; - a Cardano checkpoint sequence; and
- the native KERI sequence.
Lifecycle state lives outside it, in the script role address the token sits at.
Datum V2, in the accepted design, adds what the new machine needs: poisoned
(the owner's own lock on the checkpoint), born_at (for juvenility: the age a
checkpoint must reach before a consumer trusts it), refund_to, and alive_at
and valid_until reserved for a future validity edge. The three sums of money
— D_reg the conviction bond, B the freeze bond and the pool of advance
funds — are value, not fields. That change lands on observer_advance,
which has three bytes of headroom, so epic
#319 measures before
epic #322 decides.
Operation status
| Operation | Shipped today | Under the accepted design |
|---|---|---|
| Register | Creates a bonded checkpoint at sequence zero. No uniqueness rule | A registry request: absence proof, insert and checkpoint mint together; no second first-registration |
| Advance | Applies one genuine witnessed rotation | The same, plus a bond option and the premium P (the fee the pool pays for landing a rotation) to whoever landed it. The refund address is never changed |
| Close | Current controllers burn the token and take the refund | Gone. There is no owner exit: a checkpoint is alive until it is convicted |
| Freeze | Moves a lagging checkpoint to ARMED for the response window | Payment to a hunter (anyone paid to land rotations, or to freeze a checkpoint that cannot pay for one) when the pool is short. The datum is untouched; B leaves |
| ClaimFreeze / thaw | Pays the recorded hunter after the deadline; thaw re-posts B |
Gone. No deadline, no claim, no timeout economy |
| Convict | Burns the token on a witnessed irreconcilable fork | A terminal Convicted state on a duplicity proof; D_reg in full to the convictor |
| Poison | — | New: the current quorum declares the epoch compromised |
| Top-up | — | New: anyone adds at least one premium to the pool, once between two rotations. No signature. The only datum change is the top-up mark |
Register
Shipped today
Registration is permissionless: anyone may relay a public KERI inception and fund the escrow. The inception itself determines the keys; the relayer cannot substitute different controller authority. It has two transactions.
1. BLAKE3 premint. The KERI AID is a BLAKE3 digest of the inception bytes in KERI's saidification form. Plutus has no native BLAKE3 builtin, so a dedicated Aiken policy performs that expensive check and mints a deterministic proof token. The token records one fact — the supplied inception bytes have the supplied KERI AID — and grants no identity authority.
2. Checkpoint mint. The checkpoint transaction:
- uses the bare mint redeemer
Register; - includes a zero-lovelace withdrawal from the registration observer;
- puts the complete
RegistrationEvidencein that observer's envelope; - consumes an input carrying the matching proof token and burns it;
- verifies the inception's controller signatures and witness receipts over the exact event bytes;
- verifies that the new datum projects the event's AID, keys, thresholds,
next commitments, witnesses, and
toad; - mints exactly one AID-derived checkpoint token; and
- creates exactly one output holding the token and the required escrow.
The checkpoint and observer programs are delivered by reference; the evidence is not duplicated in the mint redeemer. See Observer architecture.
The duplicate-registration residual. Registration uses no shared registry and no absence proof, so two independent transactions can mint live candidates for the same AID. A consumer must resolve exactly one and fail closed on zero or several — and it cannot prove no other exists. A holder of some retired epoch's keys can therefore mint a rival checkpoint and advance it exactly to their epoch.
Under the accepted design
Registration becomes a request against the registry: it identifies the AID, binds the inception evidence, and carries the bonds and a refund address chosen by whoever pays. It is applied in a batch by anyone. This does not require the raw inception to be stored in the request: the proposed earlier attestation would authenticate inception validity and its initial key state. Such an attestation may be issued more than once; registry admission supplies checkpoint uniqueness. Its concrete format and validation are still to be implemented. Application checks that the AID has no leaf, inserts one, and creates the checkpoint in the same transaction. The persistent leaf prevents a second first-registration of the AID, and there is no revival: a registered identity stays live until it is convicted. See the registration guarantee for the atomic mint/insertion obligation and the model's evidence limits.
The new checkpoint is juvenile: unconsumable for W slots. That window is
what bounds the stale-key registration above — anyone can advance the
checkpoint onward with the controller's later public rotations, and the moment
that happens the registrant's bonds answer to the controller's keys.
Advance
Shipped today
Advance moves one KERI rotation into the checkpoint. Anyone may relay it because the public event and its receipts determine the only valid successor.
The transaction consumes exactly one current checkpoint and creates exactly
one successor with the same quantity-one token, the same complete value, the
Cardano sequence increased by one, and the event's keys, thresholds, next
commitments, witnesses and toad.
The heavy checks run in observer_advance. They require:
- the event to continue from the stored prior event;
- revealed keys to match the stored next-key commitments;
- both KERI controller thresholds to pass — the event's own and the previously committed next threshold;
- signatures to cover the exact rotation bytes;
- witness receipts to cover the exact event bytes; and
- witness-set changes to satisfy the incoming witness threshold.
When incoming toad is greater than zero, elapsed time and controller
signatures never replace the required receipts. This prevents a controller from
activating an unpublished Cardano-first branch and repairing the KERI history
afterwards.
ixn, dip and drt are rejected: advance requires the type span to read
rot.
An unsettled parity question
The validator tallies receipts against the new witness set and the
new toad. Whether keripy does the same, or tallies against the
parent's set, is not established. Epic
#320 builds the
oracle that settles it. The two rules disagree exactly on rotations that
cut or add witnesses — that is, on witness replacement after a compromise.
Under the accepted design
The predicate is unchanged. What is added is everything around it:
- a bond option —
keep, ordeposit(the unfreeze: refillBwhen a hunter has taken it). There is no withdraw; - the premium
Ppaid from the pool to the payee the transaction names, when the pool covers it. An unpaid rotation is still a valid rotation: no transition ever requires the pool; - the poison cleared, unconditionally.
A deposit travels in a message signed by the keys of the epoch the rotation
opens (D-038). A relayer landing the owner's public rotation therefore
cannot unfreeze her. Absent means keep. No rotation changes the refund address:
it is chosen by whoever pays the registration and fixed for the checkpoint's
whole life.
Close
Shipped today
Close is the controller-authorized retirement path. Its signed evidence binds the network, checkpoint policy, exact checkpoint input reference, AID and current sequence, refund address, and current controller threshold. The transaction consumes the exact checkpoint, satisfies the current weighted threshold, burns the quantity-one token, creates no successor, and refunds the complete remaining value to the signed address.
Binding the input reference makes the authorization single-use. Binding the refund address prevents a transaction builder from redirecting the escrow.
The exposure it leaves. Close answers to the current keys, so a thief who steals them can burn the identity and take the escrow. The signed refund address limits where the money goes but not whether the identity dies.
Under the accepted design
There is no close. The owner keeps her checkpoint alive — bonds, rotations, unfreezing — until it is convicted; a relying party sees a checkpoint that is either alive or convicted. The current-key thief loses the close entirely: the only Cardano power the current keys retain is the poison, and a rotation clears that.
There is no pause, no parking and no revival. Only a conviction is final. Whether an owner who stops maintaining a checkpoint should recover its bonds and pool is an open economic question: today they leave a live checkpoint only through rotation premiums, a freeze and conviction.
Freeze
Shipped today
Freeze is a public challenge to a checkpoint that KERI evidence shows is
behind. The thin checkpoint requires an observer_enforcement withdrawal,
which proves the contested rotation belongs to the same AID, continues from the
recorded event, is strictly ahead of the tip, reveals committed keys, satisfies
its controller threshold, and carries enough receipts. The checkpoint moves to
ARMED — a different role address, so consumers fail closed — with the hunter
and a deadline recorded, and the complete escrow preserved.
A response is not an owner-only command: it is the same ordinary advance, applied before the deadline. Evidence is bound to the challenged tip, so after a response the old proof is stale and a new round needs fresh evidence at the new sequence.
Under the accepted design
Freeze survives, with a different job. It is not a punishment for lag — the party who can prove a later witnessed rotation can simply land it, which costs the owner nothing and leaves the checkpoint fresh, so paying for the freeze instead would pay for the harmful move.
Instead a hunter freezes only when the owner's pool is short: it presents
exactly the advance evidence, takes B, and leaves the datum untouched — the
old keys stay. Frozen is the absence of B, a value-level fact, not a role or
a flag. There is no deadline, no claim, no thaw window: the owner comes back by
a rotation with deposit, which restores both bonds.
There is no ARMED, no FROZEN role address, no recorded hunter in the datum, and no timeout.
Poison — new in the accepted design
A poison is the current quorum's declaration that this epoch is compromised.
The key holders sign, at cur_threshold, a short preimage bound to the
register policy, the AID and the current sequence — producible with stock
kli sign, no KERI-side change, no BLAKE3 — and anyone lands it. It is never
witnessed, because it is a Cardano-side declaration and not a projected KERI
event.
Its effect is one bit. The checkpoint becomes unconsumable. From a poisoned present checkpoint the machine still enables rotation, top-up, conviction, and close (the reap by the next keys). Only a second poison and a freeze are refused — those two require the epoch still clean. Consumer authorization fails because the checkpoint is unconsumable. A rotation clears the poison.
Two properties are worth stating precisely:
- The threshold matters. One stolen member key of a
k-of-ngroup cannot poison. In KERI an event signed below threshold is invalid rather than duplicitous, so a single-key poison would assert more than KERI does. - It is epoch-local. Any witnessed rotation clears it, because possession of the next keys is control by KERI's own rule. It serves the window between detection and rotation, and the case of lost next keys where no rotation will ever come. It does not serve next-key theft, where the thief's rotation is control.
Convict — new shape in the accepted design
Shipped today
convict_predicate accepts a second rotation at the tip's native_sn that
reveals exactly the tip's current keys, is signed at cur_threshold, carries
receipts from at least toad of the tip's witnesses, and differs in content. It
needs no history, because the revealed keys are the current keys. On the
shipped machine this burns the token and leaves no successor, and the CLI
exposes no command for it.
Under the accepted design
The same proof, a different effect. The convictor names a payee and takes
D_reg in full; B and the pool go to the refund address; the checkpoint
becomes Convicted, terminal; the token stays, and there is no
transition out — no rotate, no poison, no freeze, no top-up (D-030, D-031).
Terminality is not severity. KERI has no event that un-duplicates an identifier: superseding recovery is a rotation over an interaction, by rule and not by duplicity, while two establishment events at one sequence is duplicity and KERI's only answer is permanent distrust. A clearable conviction would be the chain inventing a recovery KERI lacks.
Who can trigger it is narrow. A stranger cannot: only a holder of the
pre-committed keys could have signed the second rotation, and only colluding
witnesses could have receipted both. The residual is real and bounded: a
next-key thief with toad colluding witnesses can convict the identity she
already controls under KERI and take D_reg on the way out. Exposure is
D_reg and the witness set the controller chose.
Top-up — new in the accepted design
Top-up adds value to the pool, at least one premium P at a time and only
once between two rotations. No signature, anyone. It is how a friend, an
employer or a consortium pays for an identity's maintenance. A top-up spends the
checkpoint output, so a stream of tiny ones could keep the controller's own
rotation and the hunters' transactions from landing; the datum therefore carries
a top-up mark that a top-up sets and every rotation clears, and a second top-up
before the next rotation is refused. Registration asks for the same minimum: the
first pool is at least P.
What is off chain
The ledger validates the event presented for a transition. It does not:
- discover new KERI events by itself;
- store or replay the entire KEL;
- operate KERI witnesses;
- decide whether an unseen event exists; or
- submit transactions.
Hunters, controllers and ordinary relayers discover evidence off chain. They do not become trusted authorities: the on-chain validators accept or reject the supplied bytes.