Files
apress/deploy/uno-q/zeroclaw-lockdown.sh
T
Omar SobhandClaude Opus 4.8 7233a4b1c0 feat(uno-q): LAN-open boot + Telegram self-serve + guided lockdown modalities
Boards now boot LAN-open (host 0.0.0.0, allow_public_bind, require_pairing=false)
so a team reaches its node's embedded ZeroClaw dashboard + web chat directly by
IP with no token — the 'Open your node' path. Two more modalities ride the same
default (cloud-first) agent:

- Telegram: config seeds [channels.telegram.default] disabled + pre-bound to the
  default agent; a team enables it from the dashboard by pasting a @BotFather
  token. Dashboard writes only set pending_reload, and /admin/reload is
  loopback-only, so a new zeroclaw-reload-watcher.sh (loopback) applies dashboard
  config edits within seconds — no shell. provision-fleet pushes + launches it.
- Lockdown: zeroclaw-lockdown.sh flips require_pairing=true, reloads, and mints a
  pair code (open -> locked harden step); documented as a board/adb action since
  minting + reload are loopback-only.
- Voice: seeds a commented [channels.voice_duplex.default] + documents the
  aarch64 build (embedded-web + gateway-voice-duplex); build/hardware work is
  separate.

Onboarding scripts (apess-selfregister.sh, provision-uno-q.sh) now tolerate
open-boot: when the gateway mints no pair code, they announce with a placeholder
token (the open board ignores auth) instead of hard-failing.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-07-15 16:35:28 -07:00

63 lines
3.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# The "harden" step — flip a node from open (setup) to paired (locked). Boards
# boot LAN-open so a team can set up tokenless; once they're done, this locks the
# node so only their group can reach it.
#
# Runs ON the board (loopback): pair-code minting + /admin/reload are localhost-
# only, so this can't be a LAN-browser button. Trigger it over adb, from a board
# shell, or wire it to a physical button — then hand the team the pair code it
# prints (they enter it once in the dashboard's pairing screen).
#
# ./zeroclaw-lockdown.sh # on the board
# adb -s <serial> shell '/home/arduino/zeroclaw-lockdown.sh' # from the host
#
# Env:
# ZC_CONFIG config file (default /home/arduino/.zeroclaw/config.toml)
# GATEWAY_PORT loopback gateway port (default 8080)
# ZC_BIN zeroclaw binary (default /home/arduino/zeroclaw)
set -uo pipefail
CONFIG="${ZC_CONFIG:-/home/arduino/.zeroclaw/config.toml}"
PORT="${GATEWAY_PORT:-8080}"
ZC_BIN="${ZC_BIN:-/home/arduino/zeroclaw}"
BASE="http://127.0.0.1:${PORT}"
echo "==> locking down this node (require pairing)"
# 1) Persist require_pairing=true. Prefer the running gateway's config API
# (loopback → allowed even while pairing is off); fall back to editing the
# toml directly if the endpoint isn't reachable.
if ! curl -sf --max-time 5 -X PUT "${BASE}/api/config/prop?path=gateway.require_pairing" \
-H 'content-type: application/json' -d 'true' >/dev/null 2>&1; then
echo " (config API unreachable — editing $CONFIG directly)"
if grep -qE '^\s*require_pairing\s*=' "$CONFIG"; then
sed -i 's/^\(\s*require_pairing\s*=\).*/\1 true/' "$CONFIG"
else
# insert under [gateway]
sed -i '/^\[gateway\]/a require_pairing = true' "$CONFIG"
fi
fi
# 2) Reload so the live PairingGuard picks up require_pairing=true.
curl -sf --max-time 8 -X POST "${BASE}/admin/reload" >/dev/null 2>&1 || true
# give the daemon a moment to come back paired
for _ in $(seq 1 15); do
curl -sf --max-time 2 "${BASE}/health" >/dev/null 2>&1 && break
sleep 1
done
# 3) Mint a fresh pair code (localhost-only). Try the admin endpoint, then the CLI.
CODE="$(curl -sf --max-time 5 -X POST "${BASE}/admin/paircode/new" 2>/dev/null | grep -oE '[0-9]{6}' | head -1)"
[ -n "$CODE" ] || CODE="$("$ZC_BIN" gateway get-paircode --new --port "$PORT" 2>/dev/null | grep -oE '[0-9]{6}' | head -1)"
echo
if [ -n "$CODE" ]; then
echo " ┌───────────────────────────────────────────┐"
echo " │ Node locked. Pairing code: ${CODE} │"
echo " └───────────────────────────────────────────┘"
echo " Enter it once in the dashboard's pairing screen (http://<board-ip>:${PORT}/pairing)."
else
echo " ! Node lockdown persisted, but couldn't mint a pair code automatically."
echo " Run on the board: ${ZC_BIN} gateway get-paircode --new --port ${PORT}"
fi