Web (Gateway)
The Gateway serves a small browser Control UI (Vite + Lit) from the same port as the Gateway WebSocket:- default:
http://<host>:18789/ - optional prefix: set
gateway.controlUi.basePath(e.g./openclaw)
Webhooks
Whenhooks.enabled=true, the Gateway also exposes a small webhook endpoint on the same HTTP server.
See Gateway configuration → hooks for auth + payloads.
Config (default-on)
The Control UI is enabled by default when assets are present (dist/control-ui).
You can control it via config:
Tailscale access
Integrated Serve (recommended)
Keep the Gateway on loopback and let Tailscale Serve proxy it:https://<magicdns>/(or your configuredgateway.controlUi.basePath)
Tailnet bind + token
http://<tailscale-ip>:18789/(or your configuredgateway.controlUi.basePath)
Public internet (Funnel)
Security notes
- Gateway auth is required by default (token, password, trusted-proxy, or Tailscale Serve identity headers when enabled).
- Non-loopback binds still require gateway auth. In practice that means token/password auth or an identity-aware reverse proxy with
gateway.auth.mode: "trusted-proxy". - The wizard creates shared-secret auth by default and usually generates a gateway token (even on loopback).
- In shared-secret mode, the UI sends
connect.params.auth.tokenorconnect.params.auth.password. - In identity-bearing modes such as Tailscale Serve or
trusted-proxy, the WebSocket auth check is satisfied from request headers instead. - For non-loopback Control UI deployments, set
gateway.controlUi.allowedOriginsexplicitly (full origins). Without it, gateway startup is refused by default. gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=trueenables Host-header origin fallback mode, but is a dangerous security downgrade.- With Serve, Tailscale identity headers can satisfy Control UI/WebSocket auth
when
gateway.auth.allowTailscaleistrue(no token/password required). HTTP API endpoints do not use those Tailscale identity headers; they follow the gateway’s normal HTTP auth mode instead. Setgateway.auth.allowTailscale: falseto require explicit credentials. See Tailscale and Security. This tokenless flow assumes the gateway host is trusted. gateway.tailscale.mode: "funnel"requiresgateway.auth.mode: "password"(shared password).
Building the UI
The Gateway serves static files fromdist/control-ui. Build them with: