Gateway Dashboard: Access and Authentication
Learn how to access the Gateway dashboard (Control UI) and configure authentication. Essential for administrators managing the Gateway's web interface.
Read this when
- Changing dashboard authentication or exposure modes
The Gateway dashboard is the browser-based Control UI, served by default at / and configurable via gateway.controlUi.basePath.
Quick access (local Gateway):
- http://127.0.0.1:18789/ (alternatively http://localhost:18789/)
- When
gateway.tls.enabled: trueis enabled, point the WebSocket endpoint athttps://127.0.0.1:18789/andwss://127.0.0.1:18789.
Useful references:
- Control UI covers usage and UI features.
- Tailscale explains Serve/Funnel automation.
- Web surfaces documents bind modes and security considerations.
Authentication happens at the WebSocket handshake, driven by the gateway auth path you configure:
connect.params.auth.tokenconnect.params.auth.password- Tailscale Serve identity headers when
gateway.auth.allowTailscale: trueis set - trusted-proxy identity headers when
gateway.auth.mode: "trusted-proxy"is set
Details live in gateway.auth within Gateway configuration.
Warning
The Control UI is an admin surface (chat, config, exec approvals). Keep it off the public internet. The UI stores dashboard URL tokens in sessionStorage for the active browser tab and chosen gateway URL, then removes them from the URL after loading. Stick to localhost, Tailscale Serve, or an SSH tunnel.
Fast path (recommended)
- Once onboarding finishes, the CLI launches the dashboard automatically and shows a clean link.
- To reopen or fix a browser at any time, run
openclaw dashboard. It copies or opens a single-use pairing link that grants administrator access to that exact signed browser, even recovering from a previously limited credential, without enabling blanket remote auto-approval. - If both clipboard and browser delivery fail,
openclaw dashboardeither offers a safe manual-token hint or directs you to runopenclaw dashboard --jsonand open its short-livedbrowserUrl; the shared token value never appears in interactive logs. - When the UI asks for shared-secret auth, enter the configured token or password into Control UI settings.
Auth basics (local vs remote)
- Localhost: open
http://127.0.0.1:18789/. - Gateway TLS: with
gateway.tls.enabled: trueactive, dashboard and status links usehttps://, while Control UI WebSocket links rely onwss://. - Shared-secret token source: pull from
gateway.auth.token(orOPENCLAW_GATEWAY_TOKEN). Manual token entry stays in sessionStorage for the current tab and selected gateway URL, never localStorage. - Host-authorized browser handoff:
openclaw dashboardproduces a short-lived, single-use bootstrap rather than placing the shared Gateway token in the browser launch URL. That bootstrap ties to the browser's signed device identity and swaps for a durable administrator credential. A different browser profile cannot reuse the handoff or inherit the access it grants. - Missing-config runtime token: if startup reports a generated runtime token, treat it as ephemeral and unrecoverable. Loopback still demands auth. Execute
openclaw doctor --generate-gateway-token, restart the Gateway, then runopenclaw gateway auth-token --showin an interactive terminal and paste the result into Control UI settings. - When
gateway.auth.tokenis managed by SecretRef, the interactive dashboard handoff keeps working because it only transports the short-lived browser bootstrap; the external shared token never reaches terminal output, clipboard history, or browser-launch arguments. - Shared-secret password: use the configured
gateway.auth.password(orOPENCLAW_GATEWAY_PASSWORD). The dashboard does not retain passwords across reloads. - Identity-bearing modes: Tailscale Serve satisfies Control UI and WebSocket auth via identity headers when
gateway.auth.allowTailscale: trueis enabled; a non-loopback identity-aware reverse proxy coversgateway.auth.mode: "trusted-proxy". Neither requires a pasted shared secret for the WebSocket. - Not localhost: rely on 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 enforce shared-secret auth unless you deliberately run private-ingressgateway.auth.mode: "none"or trusted-proxy HTTP auth. Consult Web surfaces.
Open in Telegram
Telegram bots can surface the dashboard as a Telegram Mini App using /dashboard.
Prerequisites:
gateway.tailscale.mode: "serve"or"funnel"so Telegram receives 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 advise opening the command in DM and omit the button. - Docker installs: Serve and Funnel modes require the gateway to bind loopback next to
tailscaled, which bridge networking with published ports cannot satisfy. Launch the gateway container withnetwork_mode: host, mounting the hosttailscaledsocket (/var/run/tailscale) and thetailscaleCLI into the container.
The Mini App performs a bounded one-time dashboard handoff and redirects to Control UI with a short-lived bootstrap token. It never exposes a shared gateway token in the URL, nor does it receive the administrator grant reserved for handoffs issued directly by the Gateway host.
Out of scope for v1:
- Telegram Web iframe is not supported.
- Tailscale Serve/Funnel is the only supported published URL path.
If you see "unauthorized" / 1008
- To verify the gateway is accessible, use
openclaw statuslocally; for remote access, set up an SSH tunnel withssh -N -L 18789:127.0.0.1:18789 user@gateway-hostand then navigate tohttp://127.0.0.1:18789/. - When using
AUTH_TOKEN_MISMATCH, a client can attempt a single trusted retry with a cached device token if the gateway issues retry hints; this retry applies the token's cached approved scopes (explicitdeviceToken/scopescallers maintain their requested scope set). Should authentication still fail post-retry, address token drift manually. - In the case of
AUTH_SCOPE_MISMATCH, the device token was recognized but lacks the required scopes; re-pair or approve the new scope set rather than rotating the shared gateway token. - Beyond that retry mechanism, the Control UI favors a pending bootstrap token so a fresh host-issued handoff can create or upgrade the browser credential. If no bootstrap token is pending, an explicit shared token or password takes priority over the stored device token.
- On the async Tailscale Serve path, failed attempts for the same
{scope, ip}are queued sequentially before the failed-auth limiter logs them, meaning a second concurrent bad retry can already displayretry later. - For steps on fixing token drift, consult the Token drift recovery checklist.
- Obtain the shared secret from the gateway host as follows:
- Token: execute
openclaw gateway auth-token --showin an interactive terminal on the Gateway host - Password: look up the configured
gateway.auth.passwordorOPENCLAW_GATEWAY_PASSWORD - SecretRef-managed token: run
openclaw gateway auth-token --show; if that fails, fix the external secret provider and try again - Runtime token generated when no shared secret was set: run
openclaw doctor --generate-gateway-token, reboot the Gateway, then use the configured token
- Token: execute
- In the dashboard settings, insert the token or password into the auth field, then establish the connection.
- The language selector for the UI is found under Settings → Appearance → Language.