Skip to content

Key lifecycle

The protocol treats keys as having a lifecycle. When a key is compromised, retired, or lost, the protocol offers on-chain primitives for dealing with that, without requiring central escrow or email-based recovery flows.

AnchorRotation publishes a signed anchor moving a signer from epoch n to n+1.

  • Optionally caps old-epoch nonces, giving in-flight transactions under the old key a bounded window.
  • Rotation is signed by the current epoch key; no guardian involvement required.

Use this when you want to rotate a key proactively (key hygiene, staff rotation, scheduled key age-out) and still hold the old key.

AnchorInvalidation freezes an epoch so no further transactions at that epoch are admitted.

Use this when you know an epoch is compromised, burn it and keep going.

When the subject no longer holds their key:

  1. Init, M of N guardians sign a GuardianRecoveryInit naming a new public key and a time-lock window (default 1h to 1yr, configurable).
  2. Veto, the legitimate owner, if they still have a copy of the old key, signs a GuardianRecoveryVeto during the time-lock and cancels the recovery.
  3. Commit, once the time-lock elapses without a veto, any guardian submits a GuardianRecoveryCommit and the subject rotates to the new key.

Guardians must have already signed a GuardianSetUpdate consenting to their role. See QDP-0002: Guardian-Based Recovery.

GuardianResign lets a guardian withdraw consent without the subject’s cooperation. It is prospective only, it does not unwind any in-flight recovery the guardian already initiated. See QDP-0006: Guardian Resignation.

  • A compromised single key cannot rotate itself to lock out the subject because rotation requires a signature matching the current epoch, not just any signature.
  • A compromised M-1 of N guardians cannot recover; quorum is enforced.
  • A compromised M of N guardians can recover, which is why you choose your guardian set carefully. The time-lock + veto window exists to give a conscious subject a chance to react.
  • An AnchorInvalidation signed by the current epoch key shuts everything down immediately, use this if you detect compromise early.

The signer.Signer interface accepts PKCS#11 / HSM and WebAuthn / FIDO2 backends, no private keys need to live in-process. See pkg/signer/hsm/ and pkg/signer/webauthn/.