2025-12-13 03:47:27 +00:00
---
2025-12-19 23:12:52 +01:00
summary: "Node discovery and transports (Bonjour, Tailscale, SSH) for finding the gateway"
2025-12-13 03:47:27 +00:00
read_when:
- Implementing or changing Bonjour discovery/advertising
- Adjusting remote connection modes (direct vs SSH)
2026-01-22 23:07:58 +00:00
- Designing node discovery + pairing for remote nodes
2026-01-31 16:04:03 -05:00
title: "Discovery and Transports"
2025-12-13 03:47:27 +00:00
---
2026-01-31 21:13:13 +09:00
2025-12-13 03:47:27 +00:00
# Discovery & transports
2026-01-30 03:15:10 +01:00
OpenClaw has two distinct problems that look similar on the surface:
2025-12-13 03:47:27 +00:00
2026-01-31 21:13:13 +09:00
1. **Operator remote control** : the macOS menu bar app controlling a gateway running elsewhere.
2. **Node pairing** : iOS/Android (and future nodes) finding a gateway and pairing securely.
2025-12-13 03:47:27 +00:00
2026-01-30 03:15:10 +01:00
The design goal is to keep all network discovery/advertising in the **Node Gateway** (`openclaw gateway` ) and keep clients (mac app, iOS) as consumers.
2025-12-13 03:47:27 +00:00
## Terms
2026-01-15 18:08:20 +01:00
- **Gateway**: a single long-running gateway process that owns state (sessions, pairing, node registry) and runs channels. Most setups use one per host; isolated multi-gateway setups are possible.
2026-01-22 23:07:58 +00:00
- **Gateway WS (control plane)**: the WebSocket endpoint on `127.0.0.1:18789` by default; can be bound to LAN/tailnet via `gateway.bind` .
- **Direct WS transport**: a LAN/tailnet-facing Gateway WS endpoint (no SSH).
2025-12-13 03:47:27 +00:00
- **SSH transport (fallback)**: remote control by forwarding `127.0.0.1:18789` over SSH.
2026-01-22 23:07:58 +00:00
- **Legacy TCP bridge (deprecated/removed)**: older node transport (see [Bridge protocol ](/gateway/bridge-protocol )); no longer advertised for discovery.
2025-12-13 03:47:27 +00:00
2026-01-12 04:44:14 +00:00
Protocol details:
2026-01-31 21:13:13 +09:00
2026-01-12 04:44:14 +00:00
- [Gateway protocol ](/gateway/protocol )
2026-01-22 23:07:58 +00:00
- [Bridge protocol (legacy) ](/gateway/bridge-protocol )
2026-01-12 04:44:14 +00:00
2025-12-13 03:47:27 +00:00
## Why we keep both “direct” and SSH
2026-01-22 23:07:58 +00:00
- **Direct WS** is the best UX on the same network and within a tailnet:
2025-12-13 03:47:27 +00:00
- auto-discovery on LAN via Bonjour
- pairing tokens + ACLs owned by the gateway
- no shell access required; protocol surface can stay tight and auditable
- **SSH** remains the universal fallback:
- works anywhere you have SSH access (even across unrelated networks)
- survives multicast/mDNS issues
- requires no new inbound ports besides SSH
2025-12-19 23:12:52 +01:00
## Discovery inputs (how clients learn where the gateway is)
2025-12-13 03:47:27 +00:00
### 1) Bonjour / mDNS (LAN only)
Bonjour is best-effort and does not cross networks. It is only used for “same LAN” convenience.
Target direction:
2026-01-31 21:13:13 +09:00
2026-01-22 23:07:58 +00:00
- The **gateway** advertises its WS endpoint via Bonjour.
2025-12-19 23:12:52 +01:00
- Clients browse and show a “pick a gateway” list, then store the chosen endpoint.
2025-12-13 03:47:27 +00:00
2026-01-10 14:51:21 -06:00
Troubleshooting and beacon details: [Bonjour ](/gateway/bonjour ).
2025-12-13 04:28:12 +00:00
2026-01-08 23:06:56 +01:00
#### Service beacon details
2025-12-13 03:47:27 +00:00
- Service types:
2026-01-30 03:15:10 +01:00
- `_openclaw-gw._tcp` (gateway transport beacon)
2025-12-13 03:47:27 +00:00
- TXT keys (non-secret):
2025-12-19 23:12:52 +01:00
- `role=gateway`
2025-12-13 03:47:27 +00:00
- `lanHost=<hostname>.local`
- `sshPort=22` (or whatever is advertised)
2026-01-22 23:07:58 +00:00
- `gatewayPort=18789` (Gateway WS + HTTP)
- `gatewayTls=1` (only when TLS is enabled)
- `gatewayTlsSha256=<sha256>` (only when TLS is enabled and fingerprint is available)
2026-02-14 14:55:10 +01:00
- `canvasPort=<port>` (canvas host port; currently the same as `gatewayPort` when the canvas host is enabled)
2026-01-30 03:15:10 +01:00
- `cliPath=<path>` (optional; absolute path to a runnable `openclaw` entrypoint or binary)
2025-12-20 16:43:08 +01:00
- `tailnetDns=<magicdns>` (optional hint; auto-detected when Tailscale is available)
2025-12-13 03:47:27 +00:00
2026-02-14 17:17:46 +01:00
Security notes:
- Bonjour/mDNS TXT records are **unauthenticated** . Clients must treat TXT values as UX hints only.
- Routing (host/port) should prefer the **resolved service endpoint** (SRV + A/AAAA) over TXT-provided `lanHost` , `tailnetDns` , or `gatewayPort` .
2026-02-14 17:47:13 +01:00
- TLS pinning must never allow an advertised `gatewayTlsSha256` to override a previously stored pin.
- iOS/Android nodes should treat discovery-based direct connects as **TLS-only** and require an explicit “trust this fingerprint” confirmation before storing a first-time pin (out-of-band verification).
2026-02-14 17:17:46 +01:00
2025-12-13 03:47:27 +00:00
Disable/override:
2026-01-31 21:13:13 +09:00
2026-01-30 03:15:10 +01:00
- `OPENCLAW_DISABLE_BONJOUR=1` disables advertising.
- `gateway.bind` in `~/.openclaw/openclaw.json` controls the Gateway bind mode.
- `OPENCLAW_SSH_PORT` overrides the SSH port advertised in TXT (defaults to 22).
- `OPENCLAW_TAILNET_DNS` publishes a `tailnetDns` hint (MagicDNS).
- `OPENCLAW_CLI_PATH` overrides the advertised CLI path.
2025-12-13 03:47:27 +00:00
### 2) Tailnet (cross-network)
For London/Vienna style setups, Bonjour won’ t help. The recommended “direct” target is:
2026-01-31 21:13:13 +09:00
2025-12-13 03:47:27 +00:00
- Tailscale MagicDNS name (preferred) or a stable tailnet IP.
2025-12-20 15:02:23 +01:00
If the gateway can detect it is running under Tailscale, it publishes `tailnetDns` as an optional hint for clients (including wide-area beacons).
2025-12-13 03:47:27 +00:00
### 3) Manual / SSH target
When there is no direct route (or direct is disabled), clients can always connect via SSH by forwarding the loopback gateway port.
2026-01-10 14:51:21 -06:00
See [Remote access ](/gateway/remote ).
2025-12-13 03:47:27 +00:00
## Transport selection (client policy)
Recommended client behavior:
2026-01-31 21:13:13 +09:00
1. If a paired direct endpoint is configured and reachable, use it.
2. Else, if Bonjour finds a gateway on LAN, offer a one-tap “Use this gateway” choice and save it as the direct endpoint.
3. Else, if a tailnet DNS/IP is configured, try direct.
4. Else, fall back to SSH.
2025-12-13 03:47:27 +00:00
## Pairing + auth (direct transport)
The gateway is the source of truth for node/client admission.
2026-01-10 14:51:21 -06:00
- Pairing requests are created/approved/rejected in the gateway (see [Gateway pairing ](/gateway/pairing )).
2026-01-22 23:07:58 +00:00
- The gateway enforces:
2025-12-13 03:47:27 +00:00
- auth (token / keypair)
2026-01-22 23:07:58 +00:00
- scopes/ACLs (the gateway is not a raw proxy to every method)
2025-12-13 03:47:27 +00:00
- rate limits
2026-01-08 23:06:56 +01:00
## Responsibilities by component
2026-01-22 23:07:58 +00:00
- **Gateway**: advertises discovery beacons, owns pairing decisions, and hosts the WS endpoint.
2026-01-08 23:06:56 +01:00
- **macOS app**: helps you pick a gateway, shows pairing prompts, and uses SSH only as a fallback.
2026-01-22 23:07:58 +00:00
- **iOS/Android nodes**: browse Bonjour as a convenience and connect to the paired Gateway WS.