Gateway Dashboard Access and Authentication Guide
Learn how to access the Gateway Control UI dashboard and understand the authentication methods for WebSocket handshake, including token, password, Tailscale, and trusted-proxy modes.
Read this when
- Changing dashboard authentication or exposure modes
The Gateway dashboard is the browser Control UI served at / by default (override with gateway.controlUi.basePath).
Quick open (local Gateway):
- http://127.0.0.1:18789/ (or http://localhost:18789/)
- With
gateway.tls.enabled: true, usehttps://127.0.0.1:18789/andwss://127.0.0.1:18789for the WebSocket endpoint.
Key references:
- Control UI for usage and UI capabilities.
- Tailscale for Serve/Funnel automation.
- Web surfaces for bind modes and security notes.
Auth is enforced at the WebSocket handshake via the configured gateway auth path:
connect.params.auth.tokenconnect.params.auth.password- Tailscale Serve identity headers when
gateway.auth.allowTailscale: true - trusted-proxy identity headers when
gateway.auth.mode: "trusted-proxy"
See gateway.auth in Gateway configuration.
Warning
The Control UI is an admin surface (chat, config, exec approvals). Do not expose it publicly. The UI keeps dashboard URL tokens in sessionStorage for the current browser tab and selected gateway URL, and strips them from the URL after load. Prefer localhost, Tailscale Serve, or an SSH tunnel.
Fast path (recommended)
- After onboarding, the CLI auto-opens the dashboard and prints a clean (non-tokenized) link.
- Re-open anytime:
openclaw dashboard(copies the link, opens a browser if possible, prints an SSH hint if headless). - If clipboard and browser delivery both fail,
openclaw dashboardstill prints the clean URL and tells you to append your token (fromOPENCLAW_GATEWAY_TOKENorgateway.auth.token) as the URL fragment keytoken; it never prints the token value in logs. - If the UI prompts for shared-secret auth, paste the configured token or password into Control UI settings.
Auth basics (local vs remote)
- Localhost: open
http://127.0.0.1:18789/. - Gateway TLS: when
gateway.tls.enabled: true, dashboard/status links usehttps://and Control UI WebSocket links usewss://. - Shared-secret token source:
gateway.auth.token(orOPENCLAW_GATEWAY_TOKEN).openclaw dashboardcan pass it via URL fragment for one-time bootstrap; the Control UI keeps it in sessionStorage for the current tab and selected gateway URL, not localStorage. - Missing-config runtime token: if startup says it generated a runtime token, that token is ephemeral and is not available through
openclaw config get gateway.auth.token. Loopback still requires auth. Runopenclaw doctor --generate-gateway-token, restart the Gateway, then paste the configured token in Control UI settings. - If
gateway.auth.tokenis SecretRef-managed,openclaw dashboardprints/copies/opens a non-tokenized URL by design, to avoid exposing externally managed tokens in shell logs, clipboard history, or browser-launch arguments. If the ref is unresolved in your current shell, it still prints the non-tokenized URL plus actionable auth setup guidance. - Shared-secret password: use the configured
gateway.auth.password(orOPENCLAW_GATEWAY_PASSWORD). The dashboard does not persist passwords across reloads. - Identity-bearing modes: Tailscale Serve satisfies Control UI/WebSocket auth via identity headers when
gateway.auth.allowTailscale: true; a non-loopback identity-aware reverse proxy satisfiesgateway.auth.mode: "trusted-proxy". Neither needs a pasted shared secret for the WebSocket. - Not localhost: use Tailscale Serve, a non-loopback shared-secret bind, a non-loopback identity-aware reverse proxy with
gateway.auth.mode: "trusted-proxy", or an SSH tunnel. HTTP APIs still use shared-secret auth unless you intentionally run private-ingressgateway.auth.mode: "none"or trusted-proxy HTTP auth. See Web surfaces.
Open in Telegram
Telegram bots can open the dashboard as a Telegram Mini App with /dashboard.
Requirements:
gateway.tailscale.mode: "serve"or"funnel"so Telegram gets an HTTPS Mini App URL.- The Telegram sender must be the bot owner: a numeric Telegram user ID in
commands.ownerAllowFromor the selected account's effectivechannels.telegram.allowFrom. - Run
/dashboardin a DM with the bot. Group invocations only tell you to open the command in DM and do not include a button. - Docker installs: Serve/Funnel modes require the gateway to bind loopback next to
tailscaled, which bridge networking with published ports cannot satisfy. Run the gateway container withnetwork_mode: hostand mount the hosttailscaledsocket (/var/run/tailscale) plus thetailscaleCLI into the container.
The Mini App performs a one-time owner handoff and redirects to Control UI with a short-lived bootstrap token. It does not expose a shared gateway token in the URL.
Non-goals for v1:
- Telegram Web iframe is unsupported.
- Tailscale Serve/Funnel is the only supported published URL path.
If you see "unauthorized" / 1008
- Confirm the gateway is reachable: local
openclaw status; remote, SSH tunnelssh -N -L 18789:127.0.0.1:18789 user@gateway-hostthen openhttp://127.0.0.1:18789/. - For
AUTH_TOKEN_MISMATCH, clients may do one trusted retry with a cached device token when the gateway returns retry hints; that retry reuses the token's cached approved scopes (explicitdeviceToken/scopescallers keep their requested scope set). If auth still fails after that retry, resolve token drift manually. - For
AUTH_SCOPE_MISMATCH, the device token was recognized but does not carry the requested scopes; re-pair or approve the new scope set instead of rotating the shared gateway token. - Outside that retry path, connect auth precedence is: explicit shared token/password, then explicit
deviceToken, then stored device token, then bootstrap token. - On the async Tailscale Serve path, failed attempts for the same
{scope, ip}are serialized before the failed-auth limiter records them, so a second concurrent bad retry can already showretry later. - For token drift repair steps, see Token drift recovery checklist.
- Retrieve or supply the shared secret from the gateway host:
- Token:
openclaw config get gateway.auth.token - Password: resolve the configured
gateway.auth.passwordorOPENCLAW_GATEWAY_PASSWORD - SecretRef-managed token: resolve the external secret provider, or export
OPENCLAW_GATEWAY_TOKENin this shell and rerunopenclaw dashboard - Runtime token generated because no shared secret was configured: run
openclaw doctor --generate-gateway-token, restart the Gateway, then use the configured token
- Token:
- In the dashboard settings, paste the token or password into the auth field, then connect.
- The UI language picker lives in Settings -> General -> Language, not under Appearance.