Remote Access
Remote Access with Tailscale
Secure remote access to your OpenClaw agent using Tailscale — an encrypted mesh VPN that works through NAT and firewalls without exposing ports to the internet.
Why Tailscale?
Traditional SSH exposes port 22 to the internet and requires port forwarding. Tailscale provides:
- Encrypted end-to-end — All traffic encrypted between devices
- No port forwarding — Works through NAT and firewalls automatically
- Access controls — Fine-grained ACLs per device and user
- SSH integration — Tailscale SSH replaces macOS sshd entirely
- MagicDNS — Access devices by name (e.g.,
ssh your-agent)
Installation
Important: Use the Homebrew CLI installation, not the GUI app.
brew install tailscalebrew services start tailscaleWhy not the GUI app? Both the Mac App Store and standalone
.pkgversions are sandboxed — they can’t host SSH or properly configure DNS. Only the Homebrew formula provides unsandboxedtailscaled.
Authenticate and enable SSH:
sudo tailscale up --sshSSH Configuration
Disable macOS sshd
Once Tailscale SSH is working, disable the built-in SSH server:
sudo systemsetup -setremotelogin offAdd SSH Config Entry
On your client machine, add to ~/.ssh/config:
Host your-agent HostName your-agent.your-tailnet.ts.net User AGENT_USER IdentityFile ~/.ssh/id_ed25519Now you can simply run:
ssh your-agentPATH for Non-Interactive SSH
Non-interactive SSH sessions have a minimal PATH. Prefix commands with the full PATH:
ssh your-agent "export PATH=/opt/homebrew/bin:/opt/homebrew/sbin:\$PATH; openclaw status"Tailscale Serve (Dashboard & Control UI)
Expose the OpenClaw gateway to your tailnet without opening ports:
sudo tailscale serve --bg 18789This maps https://your-agent.your-tailnet.ts.net to 127.0.0.1:18789 over the tailnet only. The gateway stays bound to loopback — do NOT change bind to "tailnet", as that breaks both BlueBubbles webhooks and Tailscale Serve (both proxy to loopback).
Token-Based Access
Access the dashboard from any device on your tailnet using a token in the URL:
https://your-agent.your-tailnet.ts.net/?token=YOUR_GATEWAY_TOKENFind your token:
openclaw config get gateway.auth.tokenControl UI with Tailscale Auth
For a better experience, enable the Control UI with Tailscale identity-based auth. This removes the need for ?token= in the URL — the gateway trusts Tailscale identity headers instead.
Add to the gateway block in openclaw.json:
"controlUi": { "enabled": true, "allowedOrigins": [ "https://your-agent.your-tailnet.ts.net" ]},"auth": { "mode": "token", "token": "${OPENCLAW_GATEWAY_TOKEN}", "allowTailscale": true}Why both settings are needed:
controlUi.allowedOrigins— The browser sends the Tailscale hostname as theOriginheader. Without it listed, the gateway rejects WebSocket/UI connections with “origin not allowed”.auth.allowTailscale— Lets the gateway trust Tailscale identity headers instead of requiring a token parameter.
Device Pairing
New browsers require a one-time pairing approval, even on the same tailnet. Local connections (127.0.0.1) are auto-approved.
openclaw devices listopenclaw devices approve <requestId>Clearing browser data or switching browser profiles triggers re-pairing.
ACL Configuration
Configure Tailscale ACLs so the agent machine cannot initiate connections to other devices:
{ "tagOwners": { "tag:agent": ["autogroup:admin"] }, "grants": [ // Personal devices talk freely { "src": ["autogroup:member"], "dst": ["autogroup:member"], "ip": ["*"] }, // Personal devices can reach agent { "src": ["autogroup:member"], "dst": ["tag:agent"], "ip": ["*"] } // IMPORTANT: No grant allows tag:agent as src. ], "ssh": [ // Personal devices — auto-accept { "action": "accept", "src": ["autogroup:member"], "dst": ["autogroup:self"], "users": ["autogroup:nonroot", "root"] }, // Agent — require browser re-authentication { "action": "check", "src": ["autogroup:member"], "dst": ["tag:agent"], "users": ["AGENT_USER", "root"] } ]}Tag the agent machine as tag:agent in your Tailscale admin console.
Verify Network Isolation
# From agent Mac — test actual traffic (should FAIL/timeout):tailscale ping --icmp your-main-macnc -z -w 3 your-main-mac 22
# From your main Mac (should SUCCEED):tailscale ping --icmp your-agentNote: Plain
tailscale ping(without--icmp) uses TSMP, which tests WireGuard path establishment — not ACL-enforced connectivity. TSMP pings can succeed even when ACLs correctly block all traffic. Always use--icmpor an actual TCP connection to verify isolation.
Tailscale Lock
Enable Tailscale Lock with your phone and laptop as trusted approval devices. This prevents unauthorized devices from joining your tailnet.
Common Remote Commands
# Check agent statusssh your-agent "export PATH=/opt/homebrew/bin:\$PATH; openclaw status"
# View recent logsssh your-agent "export PATH=/opt/homebrew/bin:\$PATH; openclaw logs --tail 50"
# Restart gatewayssh your-agent "export PATH=/opt/homebrew/bin:\$PATH; openclaw gateway restart"
# Run diagnosticsssh your-agent "export PATH=/opt/homebrew/bin:\$PATH; openclaw doctor --deep"Node Access (Multi-Mac Setup)
OpenClaw nodes let you connect additional Macs to your agent’s gateway. There are two types of node connections, each serving a different purpose:
| Connection | What It Does | Capabilities |
|---|---|---|
| macOS app (device node) | TUI, dashboard, canvas, browser proxy | browser, canvas, screen |
| CLI node host (core node) | Headless shell execution | browser, system (system.run) |
The macOS app gives you a UI for interacting with your agent. The CLI node host lets the agent execute commands on your Mac, which is useful when the agent needs to run something where you physically are rather than on the gateway machine.
macOS App (TUI and Dashboard)
Install the OpenClaw macOS app on your other Mac and connect it to the gateway:
- Open Settings and set the mode to Remote (another host)
- Set transport to Direct (ws/wss)
- Enter the gateway URL:
wss://your-agent.your-tailnet.ts.net - Enter the gateway token
- Approve the pairing on the gateway:
openclaw nodes pendingopenclaw nodes approve <requestId>Now you can use the TUI and dashboard from your other Mac:
openclaw tuiopenclaw dashboardCLI Node Host (Remote Execution)
The CLI node host registers as a separate node that supports system.run. This lets the agent selectively execute shell commands on your Mac instead of the gateway machine.
Install
# On your other Macnpm install -g openclawopenclaw node install --host your-agent.your-tailnet.ts.net --port 443 --tlsThis creates a LaunchAgent (ai.openclaw.node) that runs automatically and survives reboots.
Approve the Pairing
On the gateway machine, approve the new node:
openclaw nodes pendingopenclaw nodes approve <requestId>Configure Exec Approvals
On your other Mac, open the OpenClaw macOS app and go to Settings. Set exec approvals to Always ask (recommended) or Allowlist. Without this, the node will reject system.run.prepare calls from the gateway.
Verify
From the gateway, check that both connections are live:
openclaw nodes statusYou should see two entries for your Mac: one device node (macOS app) and one core node (CLI node host). The core node should list system in its capabilities.
Test remote execution:
openclaw nodes run --node "Your Mac (node)" --raw "echo hello && hostname"Manage the Service
openclaw node status # Check if runningopenclaw node restart # Restart after config changesopenclaw node stop # Stop the serviceopenclaw node uninstall # Remove the LaunchAgentThe node host config lives at ~/.openclaw/node.json:
{ "version": 1, "nodeId": "generated-uuid", "displayName": "Your Mac", "gateway": { "host": "your-agent.your-tailnet.ts.net", "port": 443, "tls": true }}How the Agent Uses Nodes
The agent doesn’t route all commands to nodes by default. It executes on the gateway machine unless a specific tool call includes host=node. This means you can configure the agent to selectively target your Mac for operations that make sense there (browser automation on your local network, accessing local files, etc.) while keeping everything else on the gateway.
Node Cleanup
Over time you may accumulate stale pairings (old devices, re-paired nodes). List and inspect them with:
openclaw nodes statusRename nodes for clarity:
openclaw nodes rename --node <id> --name "Descriptive Name"Troubleshooting
Tailscale DNS / Serve Not Working
Use the Homebrew CLI (brew install tailscale), not the GUI app.
Stale Tailscale Shim
If you previously installed the Mac App Store version, a shim script at /usr/local/bin/tailscale may shadow the real binary:
sudo rm /usr/local/bin/tailscaleSSH Hangs or Timeouts
Check that Tailscale SSH is enabled:
tailscale statusIf SSH is not shown, re-enable:
sudo tailscale up --ssh