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>
3.6 KiB
3.6 KiB
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
ownersecret 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 secretchmod 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 capG. - 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).