Value authorization
Value authorization is a future consumer of the identity checkpoint. The small settled stories prove checkpoint creation and lifecycle transitions; they do not yet ship an application that authorizes value writes from it.
This page states the current integration boundary so later application validators do not reintroduce the retired shared-registry model.
Where this page stands
The resolution rules, the indexer boundary, the authorization modes and
the rotation race are shipped on main today and survive the M1
return. What changes is the predicate an application applies to the
checkpoint it resolved: role addresses go, and a bit plus the checkpoint's
own value take their place. Both are given below.
Resolve current authority
For the deployed V1 checkpoint family, given a KERI AID an application derives the expected checkpoint asset:
(checkpoint_policy_id, deriveAidAssetName(cesr_aid))
It includes the candidate checkpoint as a CIP-31 reference input. CIP-31 lets the transaction read the UTxO without spending it.
The application validator must require:
- exactly one supplied candidate for that AID;
- the accepted checkpoint policy and script lineage;
- exactly one AID-derived token;
- a well-formed inline
CheckpointDatumV1; - the expected AID and current sequence;
- the bare ACTIVE role address; and
- the operation's controller authorization against the current weighted key state.
Every other case fails closed: no checkpoint; multiple ACTIVE candidates; a stale or already spent outref; a wrong policy or asset; a malformed or mismatched datum; ARMED; or FROZEN.
A convicted identity (the terminal state after a duplicity proof) is not a further role to reject. Conviction burns the AID token, so it leaves nothing to resolve and the application meets the no-checkpoint case. There is no identity-root inclusion proof and no separate Freeze-registry absence proof: Freeze changes the sovereign checkpoint's own role address.
Under the accepted design
The older checkpoint design retains steps 1 to 5. The pending Singular integration also changes token and registry authentication as described below. Steps 6 and 7 become the consumer predicate, which reads only the datum and the checkpoint's value:
authorize iff present
∧ D_reg full ∧ B full — bonded: not frozen
∧ ¬poisoned — the controller has not disowned this epoch
∧ now − born_at ≥ W — past the juvenility window
∧ the operation's own signature satisfies the current threshold
and, once the validity edge ships, now ≤ valid_until. Everything else fails
closed: absent, frozen (the freeze bond taken), poisoned (locked by the
owner's own declaration), juvenile (younger than the window W), convicted,
and pending conviction custody. There is no parked state: a checkpoint is
alive until it is convicted.
Three consequences an integrator should plan for:
- Frozen is not a flag. A frozen checkpoint is missing
B. An application that looks for a status field will find none, and must compare against the deployment'sD_regandB. - Step 1 becomes a guarantee rather than a hope. The redesigned registry admits one incarnation per AID, ever within that registry, so "exactly one candidate" is enforced on chain instead of being a residual the consumer carries.
- Conviction is the only end, and it is terminal. The chain follows
KERI: no key event un-duplicates an identifier, so
Convictedhas no exit. There is no owner exit either, so a registered AID is alive until it is convicted. An application must not expect a convicted one to return.
Pending Singular registry integration
As a contract author adopting the redesigned registry, require a token bound
to the intended registry as well as the AID. The V1 formula above is not the
new registry token formula. Under the public
Singular reader design,
the registry address
carries the state policy S and registry name R, with the network in the
bech32 prefix. The expected policy is S = state(A_keri) for the chosen
application release. The name R commits a State preimage containing the
seed; the active token name commits an Active preimage containing (S, R)
and the AID key. Both names use blake2b_256 over serialized Plutus Data.
Those are conceptual commitments, not byte formats. The exact preimage bytes and termination approval vectors are not settled upstream. Registration approval binds the full holding address, including its payment and stake parts. The KERI AID key encoding still needs an explicit binding.
flowchart TB
R[Registry and AID] -->|derive| T[Exact asset]
T -->|found| H[Check holding]
H -->|eligible| C[Authorize]
T -->|missing| P[Check history]
A future consumer queries that exact asset under S, requires quantity one,
authenticates the canonical registry and checks the holding's KERI datum
and eligibility. A token in pending termination custody is not
an eligible checkpoint. A missing token alone does not distinguish terminal
from never registered; that requires registry history or a proof against the
on-chain root. Provider failure must be reported as unavailable.
Cardano KERI's model at 7cb4e716107d8ca7cc53dcdb0cd26549315ee256
still has the earlier registry and dependency binding. The consumer changes
remain pending under the
Lean correspondence register
and the
consumer predicate
work. Parking, described by earlier revisions of this page, is removed:
there is no owner exit
(#493). No model or runtime behavior is
changed by this documentation. See the
complete mapping for the remaining stories
and evidence.
Indexer boundary
An indexer may return the candidate outref for
(checkpoint_policy_id, aid_asset_name). It is not trusted for authority.
The ledger validations above remain mandatory.
- A stale result refers to an input that no longer exists and rejects.
- A false result fails token, script, datum, or AID validation.
- An outage prevents construction but cannot authorize a fallback key.
Clients should refresh on contention and fail over between indexers or local chain sync when availability matters.
Authorization modes
Two application patterns remain useful.
Native Cardano signer
The application may require Cardano transaction signatures corresponding to the current checkpoint controller keys. This is simple for software that can make those KERI-controlled Ed25519 keys available through a compatible signing interface.
The validator:
- resolves the ACTIVE checkpoint;
- reads the current weighted key set;
- checks the required transaction signatories; and
- evaluates the checkpoint's threshold.
This mode binds authorization to the complete Cardano transaction body but may not fit existing KERI wallet APIs.
Detached intent signature
A future wallet bridge may put domain-separated signatures in the redeemer. The signed intent must bind at least:
AuthorizationIntent {
domain
network_id
application_policy
operation
checkpoint_policy
aid_asset_name
checkpoint_input
checkpoint_sequence
application_input
intended_output_or_effect
nonce_or_counter
valid_from
valid_until
}
The application reconstructs this message rather than accepting caller-supplied message bytes. It then evaluates signatures under the current checkpoint's weighted controller threshold.
Binding the exact checkpoint input and sequence makes an authorization stale after rotation. Binding application input/output or operation effect prevents a batcher from repurposing a valid signature. Domain, network, policy, and validity fields prevent cross-protocol and cross-deployment replay.
The exact envelope remains a later roadmap deliverable. This shape is a security requirement, not a claim that the SDK is published.
Value-cage oracle
Some MPFS value-cage designs — a cage is an MPFS store, a Merkle Patricia Forestry map behind one validator — have an operator or oracle that serializes writes to their own cage UTxO. That authority is separate from AID authority.
If a cage keeps an oracle, a mutation should require both:
- the AID controller threshold resolved from the current ACTIVE checkpoint; and
- the cage's own operator authorization.
The oracle is then necessary but not sufficient. It may affect liveness or ordering, but it cannot forge the identity owner's authorization.
Rotation and transaction races
A value transaction references one exact checkpoint UTxO. If Advance spends that checkpoint first, the value transaction becomes invalid and must be rebuilt against the successor.
This is the desired safety property: pending authorization does not silently survive a key rotation. It is also an operational race that builders must handle.
Refusal behavior
Shipped today. As soon as Freeze settles, the checkpoint token moves from ACTIVE to ARMED. A value transaction referring to the old ACTIVE input is stale, and a new transaction resolving ARMED must reject by role. A timely response Advance creates a new ACTIVE checkpoint at the next sequence, so the application must obtain fresh authorization against that input. Conviction produces no output to resolve at all.
Under the accepted design. Every refusal is a spend of the checkpoint that changes what the datum or the value says, so the mechanics are the same: the referring transaction is stale and a rebuild against the successor applies the predicate afresh. The refusals differ in who caused them and in how they clear:
| Refusal | Caused by | Clears when |
|---|---|---|
| Poisoned | the owner's current quorum | any witnessed rotation |
| Frozen | a hunter (anyone paid to land rotations, or to freeze a checkpoint that cannot pay for one), because the pool of advance funds was short | a rotation with deposit (the unfreeze) |
| Juvenile | time, after a registration | W slots elapse |
| Pending conviction | anyone, with a duplicity proof | its associated consuming Registry fold completes retirement |
| Convicted | the associated fold after a duplicity proof | never |
An application should not treat any of these as an error condition to retry. Each is a statement that the identity is currently unfit to authorize, and each has a party who can make it fit again — except the last two rows, where the answer is respectively "never" and "not by anyone but the owner".
Compromised controller keys
Every check on this page answers "do the current controllers of this AID authorize this operation?". An attacker holding the current KERI signing keys answers it correctly, and no validator can separate them from the owner.
That is the intended boundary, not a defect in the checks: identity authorization is only as strong as the controller's key custody. Two consequences an integrator must plan for:
- Rotation is the remedy, and it is not retroactive. Once a rotation settles, authorizations bound to the previous checkpoint input are stale, but a transaction that already settled under the old ACTIVE checkpoint stands.
- Freshness policy is load-bearing. The narrower the accepted checkpoint age, the smaller the window a stolen key can be used in.
Under the accepted design the owner gains one instrument here, and the application
must honour it: the poison. A quorum of the current keys can declare their
own epoch compromised, and a consumer that checks ¬poisoned shuts the stolen
keys out immediately, before the owner has assembled a rotation. An application
that skips that conjunct discards the only signal the owner can send on her
worst day.
Compromise of the current keys states the full case, including why an interaction event is an off-chain instrument and never touches the checkpoint.
Credential-gated actions
Identity authorization answers:
Do the current controllers of this AID authorize the operation?
It does not answer:
Does this AID represent a particular legal entity or hold a current role?
A credential-gated application must additionally verify the required ACDC credential chain and TEL non-revocation evidence. Those layers are later roadmap work.
Minimum consumer checklist
Before treating an integration as secure, prove with applied-boundary tests that it rejects:
- the right token at the wrong role;
- the right AID with multiple ACTIVE candidates;
- a stale checkpoint outref;
- a well-signed intent for another checkpoint sequence;
- a well-signed intent for another application input or output;
- signatures below the weighted threshold;
- an expired intent;
- a wrong network or policy; and
- a valid identity signature with missing or revoked credentials when the application requires credentials.
See the Trust model and Architecture overview.