multisig-hsm/docs/QUICK-START.md
mineracks 7a17ffd12e Initial public release — multisig HSM reference + recipe book
Open-source 2-of-3 policy-enforced threshold HSM: auto-signs cold→hot treasury
refills under on-device Coldcard policy, no human in the loop. Includes the full
operator manual + quick-start, the reference coordinator/signing code, and a
signer-host bootstrap. No keys, seeds, or secrets — placeholders only.

Live signet demo: https://multisighsm.mineracks.com

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 13:56:51 +10:00

3.6 KiB
Raw Permalink Blame History

Quick-start & operator checklist — mineracks multisig HSM

The one-page version. Full detail + the security model: Operator Manual. Do the entire provisioning run on signet/testnet first; only move to mainnet after rehearsing a refill, a failover, a policy change, and a restore-from-backup.

Provision (once)

  • 1. Seeds — generate 3 distinct seeds, one per Coldcard (never clone one to three). Steel-backup each; store geographically separated.
  • 2. Wallet — build the wsh(sortedmulti(2,k1,k2,k3)) descriptor; create the watch-only wallet on the node (receive /0/* + change /1/*); record the descriptor offsite (it's load-bearing for recovery).
  • 3. Register the 2-of-3 wallet on each Coldcard (so change is recognised as internal).
  • 4. Policy — per-device HSM JSON: max_amount, per_period (= ⅔ × global cap), whitelist (your hot-wallet deposit addresses), period, wallet, must_log:true.
  • 4b. TOTP (only if using the surge tier) — enrol the same owner secret on all 3 Coldcards. Production: the owner loads it directly over USB — never via the coordinator (which only relays the live code at spend time).
  • 5. ORDER (the #12 trap): register wallet → enrol TOTP (4b) → load policy → VERIFY the wallet survived on the device.
  • 6. HSM start on each device (two-step on-device approval).
  • 7. Coordinator — set global cap G; whitelist; refill floor + amount; round-robin the signer pair; session secret chmod 600 (never in git).
  • 8. Placement — 3 signers in independent failure domains, ≥1 offsite. Never two keys behind one PSU/switch/host.
  • 9. Verify — within-policy refill signs · over-cap refused · off-list refused · velocity burst blocked at G · restore-from-backup rehearsed.

Daily / on-call check

  • Quorum = 3/3 online, HSM-active, wallet-registered. (Alert fires at exactly 2 — one more failure = frozen.)
  • Global velocity has headroom for the period; no unexpected policy denials.
  • All 3 signer hosts + coordinator replica(s) up; USB/device health green.

Sizing (memorise)

  • Worst case if the coordinator is compromised = 1.5 × per-device velocity V (2 sigs burned per 1× value).
  • Set V = ⅔ × G ⇒ worst case = your intended global cap G.
  • any-2-of-3 = 1.5× worst case but unattended failover · 2-auto + 1 human break-glass = 1.0× worst case but no unattended failover. Pick deliberately.

Incident cards

Situation Do this
One signer down Run on the other two; restore + re-arm it; do not drop a second.
Two signers down Spending is frozen — safe, by design. Restore one to resume.
Coordinator compromise suspected Funds are bounded (no keys · whitelist confines destination · ≤ 1.5V). Rotate host + secret; review denial/refill logs.
Large / exception spend Use the human break-glass (3rd key / CKBunker), off the automated path.
Suspected single-key compromise One key moves nothing. Rotate to a fresh 2-of-3; sweep funds under the old policy to the new wallet.

Never

  • Never clone one seed to multiple devices · never co-locate two keys on a shared PSU/switch/host/hypervisor.
  • Never take a second signer offline while one is already down.
  • Never load policy before registering the multisig wallet (it can delete the wallet).
  • Never put the coordinator secret / seeds / descriptor in git.
  • Never hold mainnet value on a single host running more than one signer (no failure-domain independence).