Chronicle.Key (chronicle v0.1.0)

Copy Markdown

A signing key descriptor with an explicit ledger sequence epoch.

source is resolved lazily by Chronicle.Integrity; it may be raw key material, an environment reference, or a zero-arity function. Keeping the epoch beside the key prevents a retained historical key from authenticating new entries.

Epochs are measured in ledger sequence, not in time

This is the decision the rest of key handling rests on, and it is worth understanding before adding a :from that looks like a date.

A rotation expressed in wall-clock terms — "this key was retired at midnight" — cannot be checked. Timestamps are not signed, clocks are not trustworthy, and the party you are defending against is frequently the one who can set them. A rotation expressed as a sequence boundary is checkable against data that is signed: sequence numbers are covered by the chain digest, they increase under a lock, and an entry cannot claim a position it does not hold.

So from and through are ledger positions. "Key 1 is valid through sequence 10,000" is a statement a verifier can enforce years later with nothing but the ledger in front of it, which is the only kind of statement worth making here.

through: nil means the key is still current and has no upper bound yet.

Summary

Types

source()

@type source() ::
  binary()
  | {:base64, binary()}
  | {:system, binary()}
  | {:system, binary(), :base64}
  | (-> term())

t()

@type t() :: %Chronicle.Key{
  from: pos_integer(),
  id: String.t(),
  metadata: map(),
  source: source(),
  through: pos_integer() | nil
}

Functions

valid_at?(key, sequence)

@spec valid_at?(t(), pos_integer()) :: boolean()