--- # Signer-host bootstrap — see ansible/README.md. Minimal, adapt to your environment. # Never handles key material: seeds live on the Coldcard, created by you. - name: Bootstrap a multisig-HSM signer host hosts: signers become: true vars: signer_user: signer # Point this at your built signer agent (a thin authenticated service wrapping ckcc-protocol). signer_agent_exec: "/usr/bin/python3 /opt/signer-agent/agent.py" tasks: - name: Install prerequisites ansible.builtin.package: name: - python3 - python3-pip - python3-venv - libusb-1.0-0 # Coldcard USB access state: present - name: Install ckcc-protocol (Coldcard CLI / library) ansible.builtin.pip: name: ckcc-protocol virtualenv: /opt/ckcc-venv virtualenv_command: python3 -m venv # udev rule so the signer user can talk to the Coldcard over USB (vendor 0d2b). - name: Coldcard udev rule ansible.builtin.copy: dest: /etc/udev/rules.d/51-coinkite.rules mode: "0644" content: | SUBSYSTEMS=="usb", ATTRS{idVendor}=="d13e", ATTRS{idProduct}=="cc10", GROUP="plugdev", MODE="0660" notify: reload udev # Example mesh join — swap Tailscale for your own VPN/WireGuard. Provide your own auth key out-of-band. - name: Join private mesh (Tailscale example) ansible.builtin.debug: msg: > Install your mesh VPN here (e.g. Tailscale/WireGuard) so the coordinator can reach this signer agent privately. Signer agents are RPC *clients* — they do not bind a public port. - name: Install signer-agent service ansible.builtin.copy: dest: /etc/systemd/system/signer-agent.service mode: "0644" content: | [Unit] Description=Multisig-HSM signer agent (wraps ckcc-protocol; holds no keys) After=network-online.target Wants=network-online.target [Service] ExecStart={{ signer_agent_exec }} Restart=always RestartSec=5 [Install] WantedBy=multi-user.target notify: reload systemd handlers: - name: reload udev ansible.builtin.command: udevadm control --reload-rules - name: reload systemd ansible.builtin.systemd: daemon_reload: true