Skip to content

v0.10.0

Choose a tag to compare

@github-actions github-actions released this 07 Oct 01:05
· 96 commits to main since this release
v0.10.0
96ccee2

Highlights

Security release with a protocol change. FROST groups now speak KFP v2. Every member of a group must upgrade to v0.10.0 together: a v0.9.x node cannot sign with a v0.10.0 node, and a v0.10.0 node reports members still on the old protocol instead of failing silently.

Upgrading

  • Upgrade every member of a group. A running keep frost network serve logs peer runs another protocol version; every member must run v2 for each member still on v0.9.x; desktop and keep-web show it in their event logs.
  • Peer policies recorded under v0.9.x transport keys move to share indices on first start, keeping the stricter setting where both exist.
  • keep frost network sign --message now takes hex, like keep frost sign and keep frost verify. Pass the hex of the bytes to sign.
  • keep frost network dkg now requires --group-id, the id printed by keep frost network group-create. docs/USAGE.md describes the full ceremony: group-subkey, group-create --publish, then dkg.
  • Vaults written by earlier releases open unchanged, including their FROST shares. Shares that v0.10.0 writes use a newer layout that earlier releases cannot read, so do not downgrade a vault once v0.10.0 has used it.
  • Share exports now carry every member's verifying share. v0.10.0 imports exports from earlier versions; a share stored without the set learns it from the group (see below). v0.9.2 can import a v0.10.0 JSON export but not the new bech32 form.

Security

  • Transport keys come from each member's secret share (#994). Earlier versions derived a member's transport key from the group public key and its index, both public. Anyone who knew a group's public key could read its signing traffic, send messages as any member, and unwrap duress beacons. Keys are now derived from the member's signing share, announce proofs bind the key that authored them, and group broadcasts use public rendezvous addresses that carry no secret.
  • Every admitted peer is bound to its canonical verifying share (#991, #996). Announced indices must belong to the group, messages from unadmitted senders are dropped before decryption, and admission on a proof alone is gone. A share imported without the group's verifying shares learns them from members' announces; the set is accepted only when every point is proven and the whole set fits the group key, so a forged set cannot be learned.
  • A refreshed share stays consistent (#992), and duress recipients recorded before a refresh are discarded (#996).
  • Randomness failures stop signing (#953, #954, #955). RNG errors propagate instead of panicking, the entropy health check samples the OS, and a tripped RNG latch abandons in-flight sessions and discards pooled nonces.
  • The nonce store fails closed (#950, #951, #952): durable renames, a lock its own rename cannot unlink, and a reader lock that refuses on corruption.
  • Approvals and audit (#944, #946, #947, #948, #949): the baseline pre-sign policy runs before pre-approval, a refusal is remembered so a client cannot re-prompt indefinitely, and the audit log records refused requests and which peer asked.
  • Warden policy is always checked (#999). frost network sign --warden-url --hardware previously skipped the policy.
  • rustls updated for RUSTSEC-2026-0285 (#993).

Fixes

  • Signing rounds with three or more signers and no pre-exchanged nonces no longer time out (#996).
  • keep frost verify rejected every group key; it now verifies (#997).
  • keep frost network sign signs the decoded message, so --warden-url checks the bytes that get signed; the warden build feature now compiles on every platform (#999).
  • keep frost network dkg could not complete; it now pins the coordinator's group id (#1000).
  • An event no relay accepted is reported as a failed send instead of a success, with each relay's reason; DKG rounds and the first announce retry instead (#1001).

Other changes

  • Relay-driven DKG transport for creating a group on a device (#963), with the finalized share stashed durably before import so a storage failure cannot lose it (#971, #972, #978), and per-run DKG cancellation and cleanup (#979, #980).