openclaw onboard --install-daemon, default gateway port 18789, and optional OPENCLAW_HOME trees for multiple instances. Cross-links stay on MacPull without a login wall: gateway security hardening, config validate CI gate, Argo CD webhook summaries. Prefer Console for a no-paywall peek at nodes before you buy.
① Topology and least-privilege principles
Run the OpenClaw daemon under a dedicated macOS user or role account with its own home. Keep SSH administration on the primary interface while model traffic exits only through WireGuard so firewall rules stay small.
- Split control plane: CI webhooks hit a reverse proxy or SSH tunnel terminating on
127.0.0.1, not the raw LAN. - Default deny egress: allow DNS resolver, NTP, your model hostnames, and any registry your tools require—nothing else.
- Audit path: store
openclaw.jsonand env files mode600; rotate tokens when staff rotates.
② Official install and doctor verification
Install a supported runtime first. OpenClaw upstream expects Node 22 LTS or Node 24; older majors fail subtle parser paths. Use the official curl installer from OpenClaw docs, then register the daemon.
node -v # expect v22.x or v24.x # Run the curl one-liner from the official OpenClaw install page (URL changes by release) openclaw onboard --install-daemon openclaw doctor openclaw gateway status --deep || true
For multiple gateways, export OPENCLAW_HOME or OPENCLAW_CONFIG_HOME per instance before onboard so staging JSON never overwrites production plists. Document the mapping in your runbook.
- Global
openclawbinary matches the user that ownslaunchdjob labels. openclaw doctorreports clean DNS, disk, and provider reachability from the same environment as the daemon.- Port
18789is free or intentionally forwarded; no duplicate listeners after upgrades.
③ WireGuard routing and DNS split
Narrow AllowedIPs to provider CIDR blocks instead of 0.0.0.0/0 unless you truly need a full tunnel. Point only model-related FQDNs at the resolver advertised inside the tunnel; keep corporate Git on the default resolver to avoid surprise latency.
wg-quick up wg0 wg show scutil --dns | head -n 80 curl -4sv --max-time 15 https://api.openai.com/v1/models \ -H "Authorization: Bearer $OPENAI_API_KEY" -o /dev/null
| Pattern | When to use | Risk if skipped |
|---|---|---|
| Split tunnel + split DNS | Vendors need fixed egress; Git and artifact CDN stay local | CI pulls crawl through the VPN hop |
| Full tunnel | Strict compliance enclaves | Single point of failure; higher reconnect sensitivity |
| Static egress IP only on WG peer | Vendor IP allowlists | NAT drift breaks API keys mid-run |
④ Gateway bind, bearer token, and domain whitelist
Bind the HTTP gateway to 127.0.0.1:18789 and terminate TLS at the edge. Store the inbound webhook bearer in Keychain or a root-only env file referenced from launchd. Mirror the outbound table from hardening notes: model APIs, optional embeddings hosts, npm registry if the skill pipeline needs it.
export OPENCLAW_GATEWAY_TOKEN="$(openssl rand -hex 32)" launchctl print gui/$(id -u)/com.openclaw.gateway 2>/dev/null | head curl -sS -H "Authorization: Bearer $OPENCLAW_GATEWAY_TOKEN" \ http://127.0.0.1:18789/health || curl -sS http://127.0.0.1:18789/
⑤ Disconnect recovery and health probes
Treat WireGuard flap as normal. After wg-quick restarts, restart the OpenClaw daemon so in-memory DNS caches align. Use a lightweight probe every sixty seconds from launchd or a sidecar container; alert if two consecutive probes fail.
- Log
wg handshakeage and last successful model HEAD request in the same line for triage. - Apply
ThrottleIntervalon rapid restart loops to avoid tight crash spirals. - Keep a tarball of last-known-good
openclaw.jsonbefore touching routes; pair with rollback flows in skills rollback doctor.
⑥ CI webhook example: merge failure summaries
CI should not spam twenty messages per matrix cell. Collect stderr tails from failed steps, cap payload size near four kilobytes, sort unique, and POST one JSON object with fields such as job_id, commit_sha, and summary_text. Reuse the same exponential backoff ladder documented for GitOps hooks so the gateway stays responsive when the VPN is warming up.
FAIL_LINES=$(grep -hE 'error|fatal' "$CI_LOG_DIR"/*.log | tail -n 40 | sort -u)
curl -fsS -X POST "https://edge.example/v1/webhooks/ci" \
-H "Authorization: Bearer $OPENCLAW_GATEWAY_TOKEN" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg t "$FAIL_LINES" --arg j "$CI_JOB_ID" --arg c "${CI_COMMIT_SHA:-}" \
'{summary_text:$t,job_id:$j,commit_sha:$c}')"
FAQ: common errors
Handshake ok but TLS to vendor fails: clock skew or missing intermediate trust store for the daemon user—run openclaw doctor as that user.
Works in Terminal, fails under launchd: compare printenv versus plist EnvironmentVariables; missing OPENCLAW_HOME is the usual culprit.
Webhook 401 bursts after rotation: update both proxy header injection and gateway secret atomically, then bounce the daemon once.
Closing checklist
Ship the smallest surface: WireGuard for predictable egress, split DNS, loopback 18789, bearer-gated webhooks, and merged CI text. When you outgrow DIY hosts, pricing and purchase stay one click away—Apple Silicon remote Mac pools cut VPN flapping costs because NIC queues stay local to the runner. Open help or the blog index anytime; this page stays readable without signing in.
Remote Mac for OpenClaw + WireGuard labs
Dedicated Apple Silicon with clean APFS, fast reinstalls, and static networking options for gateway proofs. Browse pricing and checkout freely; Console opens for a limited free look at inventory.