Teams who hit pain here: OpenClaw Gateway already runs end-to-end, but TCP 18789 must not linger on untrusted WAN paths—while laptops, CI hosts, and on-call workstations still finish handshakes over a consistent trust island using CLIs or channel glue. Bottom line: align upstream gateway.bind with tailnet semantics, then describe in Tailscale ACL hujson exactly who may open TCP 18789 to whom. Validate in order: openclaw gateway status, tailscale ping smoke, smallest successful chat transcript. How articles split work: This post forms one corner of the triangle beside Nginx/Caddy reverse-proxy TLS checklist and Linux systemd + Cloudflare Tunnel runbook—public TLS ingress versus outbound tunnels versus pure tailnet with no public listeners. Container-only details loop back through Docker Compose pairing runbook and remote access discipline in zero-trust remote Mac checklist.
Leaving the WAN does not magically delete failure modes—you traded internet-side scanning for flattened intra-mesh lateral movement unless ACLs discipline every hop. When something misbehaves, capture both OpenClaw and Tailscale timelines with matching UTC stamps so auditors can correlate policy pushes with flaky WebSocket outages.
*:*) or sloppy tag unions let every node probe 18789; you relocated the attacker model, not removed it.GATEWAY_URL values, Tailscale reachability succeeds while handshake paths still chase stale IPs.Think of ACL hujson as the firewall that moved inward: disciplines from security hardening CVE response playbook still apply—they now govern tailnet principals instead of only iptables buckets.
| Exposure model | When it fits | Leading trade-offs |
|---|---|---|
| Internet + TLS reverse proxy | External SaaS webhooks or roaming clients without coordinated agents everywhere. | Certificate issuance, edge WAF tuning, throttle math; see TLS checklist companion. |
| Outbound tunnel (Cloudflare Tunnel and peers) | Must hide origin IP without punching inbound forwarding holes. | Reliance on POP edge and SaaS controls; Tunnel runbook deep dive. |
Tailnet-only + gateway.bind="tailnet" |
Every teammate already enrolls fleet devices; Gateway runs on a dedicated remote Mac Mini or Tailscale-ready Linux anchor. | Requires crisp tags; machines without Tailscale legitimately unreachable is a feature—not a loophole excuse. |
Never treat mesh membership as covert admin VPN: handing group:dev blanket ping rights makes post-incident forensics worthless—during an audit you cannot say who grabbed 18789 on Tuesday night. Tie each stanza to a ticket and owner.
Picture three roles: Gateway node (often a remote dedicated Mac), Operator laptop, and optional SR subnet router. After tailscale up on G, advertise TCP 18789 only toward allow-listed tags. On O, set OPENCLAW_GATEWAY_URL to the MagicDNS stable name or tailnet IPv4/v6 string—do not resurrect retired LAN URLs once you declared tailnet-only intent.
CI runners that must speak directly enroll under a distinct tag (tag:ci) and ACL allows only tag:ci → tag:gateway:18789 on TCP; avoid collapsing runners into permissive mega-groups.
Where remote infrastructure spans six selectable regions, zero-trust remote Mac checklist covers SSH and tunnel trade-offs—this adds the OpenClaw listener framing on top.
tailscale up to meaningful first packet inside the meshtailscale status; change tickets cite those strings, not folklore about “the Osaka box.”gateway.bind: in config (default ~/.openclaw/openclaw.json or mirrored container volume), set tailnet; cross-check gateway.mode versus current release docs. Post-change listener reachability is tailnet-prefixed only. Field hierarchy evolves—mirror release notes on upgrades.OPENCLAW_GATEWAY_TOKEN with nested gateway.auth.token fingerprints; Compose pairing compares both columns.openclaw gateway status then openclaw doctor; when either fails, gather paired logs from mesh control plane and gateway host.curl -v --max-time 5 https://… or the documented WebSocket probe, then a minimal assistant exchange to ensure context streaming works; post-install doctor triage orders remaining branches.{
"gateway": {
"mode": "local",
"bind": "tailnet",
"port": 18789,
"auth": {
"mode": "token",
"token": "${OPENCLAW_GATEWAY_TOKEN}"
}
}
}
// NOTE: Illustrative only—validate every field against your shipping schema; restart the gateway process or container after edits.
// ACL sketch: allow operators to reach the gateway control port only—rename tags to your org standard
{
"groups": { "group:ops": ["[email protected]"] },
"tagOwners": { "tag:gateway": ["autogroup:admin"], "tag:ops": ["autogroup:admin"] },
"acls": [
{
"action": "accept",
"src": ["tag:ops"],
"dst": ["tag:gateway:18789"],
"proto": "tcp"
}
]
}
tailscale ping before widening binds or reopening WAN.gateway healthy stays green—document MagicDNS split rules inside the change appendix.Sleep, lid-close, patching, and flaky residential uplinks shred predictable 18789 SLA; co-mingling personal volumes with gateway journaling complicates forensic chain-of-custody. Dedicated Apple silicon remote Mini nodes—especially when inventory spans six selectable regions—become steady mesh anchors for automation that must stay awake through nights and weekends.
Teams may keep three modalities (public TLS, tunnel egress, tailnet-local) mapped to distinct environments, each with RACI. MACCOME pairs hardware posture with elastic rental cadence once budgets align—start from public Mac Mini rental pricing and the help center, then reconcile binding knobs with your smoke checklist.
When WAN exposure returns for a webhook-only slice, revisit the reverse-proxy TLS checklist and ensure tokens plus ACL evidence track both surfaces without configuration drift.
If you cannot draw who may talk to TCP 18789 on a five-minute whiteboard, editing config files prematurely creates MagicDNS folklore for the next on-call. “Tailnet-only” should mean repeatable traceroute-class explanations, not marketing language.
Next hops: Compose pairing, TLS reverse proxy stack, Tunnel runbook, CVE hardening playbook, or elasticity decisions once SLAs hinge on anchored hardware.
FAQ
Do we have to abandon Docker?
No. Containers change net namespaces, not the policy story—reuse Docker Compose pairing runbook as long as host tailnet addresses and published ports stay coherent.
Can we still layer SSH jump hosts after tailnet hardening?
Yes; zero-trust remote Mac checklist explains SSH, tunnel, and direct paths. Keep separate ACL lines for 18789/tcp—do not merge them with port 22 commentary.