Files
Vincent KocandVincent Koc 2393e17f27 docs: fix one-way and absolute links across cli, tools, gateway, and channels (#143157)
* docs: fix one-way and absolute links across cli, tools, gateway, and channels

Closes the open `link`-kind audit findings filed against docs/cli/,
docs/tools/, docs/gateway/ and docs/channels/.

- Convert 21 absolute `https://docs.openclaw.ai/...` links to root-relative
  paths on protocol, clients, external-apps, embedding, protocol/transport,
  and zaloclawbot so local previews and versioned builds resolve them.
- Add the missing reverse link for one-way Related entries, using the house
  bullet or `<Card>` shape each page already uses.
- Link terms that were named but not linked: SecretRef and
  `gateway.trustedProxies` on sms, the meeting providers on transcripts,
  `openclaw models`/`openclaw agent` on infer, Talk on tts, `/tools/invoke`
  on the gateway index.
- Give distinct link text to the two "macOS platform notes" links on
  gateway/troubleshooting.
- Point the IRC workspace `.env` link at the section anchor rather than the
  Security index.
- Add Related sections to pages that had none (sms, transcripts, promos,
  progress-card, onboard, access-groups, concepts/memory, operator-scopes).
- Add the 28 zh-CN glossary sources the new list-item link labels require,
  each inserted beside a related existing term.

No anchor targets change. `pnpm check:docs` is green.

* docs: link devices and doctor inline on pairing, and trusted proxy auth from the security index

Completes two findings that were only half-applied: r3-1324 asked for the
sibling commands to be linked inline on /cli/pairing, and r3-1579 lists the
security index among the four pages that should link back to
/gateway/trusted-proxy-auth.

* docs: match each Related list's existing separator style

The added bullets used an em dash in lists whose existing entries separate
the label and gloss with a hyphen. Normalized 11 files so each list stays
internally consistent.

* docs: correct four inaccurate Related-link descriptions from review

ClawSweeper found that several glosses I wrote misdescribed their targets.
Verified each against the destination page and corrected:

- ask_user is for non-secret questions; its own reference says never to answer
  it with a credential, so the secrets-page gloss now points credential entry
  at the masked secrets tool (P1).
- OpenClaw sandbox policy does not wrap ACP harness execution
  (tools/acp-agents/delivery.md), so the ACP backlink now names the separate
  boundary instead of implying coverage (P2).
- Code Mode is a QuickJS-WASI JavaScript/TypeScript orchestration surface, not
  something built on the xAI code_execution tool documented on that page (P2).
- openclaw qr emits a mobile-node bootstrap payload, not a channel DM pairing
  code, on both the pairing and devices pages (P2).

Audited the other 100 descriptions for the same class of error and fixed six
more: OpenShell is a managed sandbox backend rather than a surface the sandbox
bounds (3 pages); a Cloud Workers gloss claimed sandbox settings apply when its
managed workspace is explicitly not an OS sandbox; openclaw promos lists and
claims promotional offers; the 1Password gloss overstated the plugin relation;
and the progress-card bullets no longer assert undocumented dashboard rendering.

* docs: correct three more link descriptions and audit every remaining gloss

Addresses the second review round, and then re-checks the whole set rather
than only the three reported.

Reported:
- openclaw attach launches Claude Code with a scoped Gateway MCP grant
  (cli/attach.md:2); it does not attach a terminal to a running session.
  Fixed on cli/mcp.md and cli/tui.md.
- Bare openclaw setup opens an interactive system-agent chat and falls
  through to guided onboarding on a fresh system (cli/setup.md:12), so
  calling it 'the non-interactive setup command' was wrong.
- Access groups have no pairing prerequisite: a group 'grants nothing by
  itself' and only matters where an allowlist references it. Dropped the
  invented sequencing claim.

Found by auditing the remaining descriptions against each target's own
summary:
- openclaw worker is explicitly 'not a general-purpose command for manual
  worker registration' (cli/worker.md:13); reworded on cloud-workers and
  protocol/handshake.
- /reference/rpc documents RPC adapters for external CLIs, not worker RPC
  method shapes; repointed to /gateway/protocol/rpc-methods.
- stable-https-url gives a tailnet-only URL via Tailscale Serve, which the
  iOS and Android glosses omitted.
- Tightened health, logs, sandbox, resume, infer, dashboard, diffs,
  prometheus, music-generation, subagents, pairing, audit, tools-invoke,
  configuration-reference, and the three goal glosses to match their pages
  instead of asserting relationships no page documents.

One glossary source added for the new label.

* docs: attribute goal reads and updates to the dedicated goal tools

The session-tool page documents session discovery, messaging, lifecycle, and
orchestration tools; goal operations use get_goal, create_goal, and
update_goal instead (docs/tools/goal.md:132-149). I corrected the other three
goal glosses last round and missed this one.

---------

Co-authored-by: Vincent Koc <vincent@openclaw.org>
2026-09-10 07:40:16 +09:00

9.8 KiB

summary, read_when, title
summary read_when title
Gateway dashboard (Control UI) access and auth
Changing dashboard authentication or exposure modes
Dashboard

The Gateway dashboard is the browser Control UI served at / by default (override with gateway.controlUi.basePath).

Quick open (local Gateway):

Key references:

Auth is enforced at the WebSocket handshake via the configured gateway auth path:

  • the configured shared secret in either connect.params.auth.token or connect.params.auth.password; gateway.auth.mode selects the configured value
  • 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.

The Control UI is an **admin surface** (chat, config, exec approvals). Do not expose it publicly. The UI strips credentials from the URL after load. After a successful token-mode connection, it keeps the shared secret in sessionStorage for the current browser tab and Gateway origin; passwords stay in memory only. Prefer localhost, Tailscale Serve, or an SSH tunnel.
  • After onboarding, the CLI auto-opens the dashboard and prints a clean link.
  • Re-open or repair a browser anytime: openclaw dashboard. It copies/opens a single-use pairing link that grants administrator access to that exact signed browser, including recovery from a previously limited credential, without granting blanket remote auto-approval.
  • If clipboard and browser delivery both fail, openclaw dashboard either gives a safe manual-token hint or tells you to run openclaw dashboard --json and open its short-lived browserUrl; it never prints the shared token value in interactive logs.
  • If the UI prompts for shared-secret auth, paste the configured token or type the password into Gateway secret on the login screen or in Settings → Gateway.

Auth basics (local vs remote)

  • Localhost: open http://127.0.0.1:18789/.
  • Gateway TLS: when gateway.tls.enabled: true, dashboard/status links use https:// and Control UI WebSocket links use wss://.
  • Shared-secret token source: gateway.auth.token (or OPENCLAW_GATEWAY_TOKEN). After a successful token-mode connection, manual entry is kept in sessionStorage for the current tab and selected Gateway URL, not localStorage.
  • Host-authorized browser handoff: openclaw dashboard issues a short-lived, single-use bootstrap instead of putting the shared Gateway token in the browser launch URL. The bootstrap is bound to that browser's signed device identity and exchanged for a durable administrator credential. A different browser profile cannot redeem the same handoff or inherit the resulting access.
  • Missing-config runtime token: if startup says it generated a runtime token, that token is ephemeral and cannot be recovered. Loopback still requires auth. Run openclaw doctor --generate-gateway-token, restart the Gateway, then run openclaw gateway auth-token --show in an interactive terminal and paste the output into Control UI settings.
  • If gateway.auth.token is SecretRef-managed, the interactive dashboard handoff still works because it carries only the short-lived browser bootstrap; the external shared token is not placed in terminal output, clipboard history, or browser-launch arguments.
  • Shared-secret password: use the configured gateway.auth.password (or OPENCLAW_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 satisfies gateway.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-ingress gateway.auth.mode: "none" or trusted-proxy HTTP auth. See Web surfaces.

Automatic browser handoff

An identity-aware HTTPS host can provide automatic login for direct dashboard links while keeping the Gateway's existing token and device authentication. After an initial connection fails because authentication is missing, the Control UI makes one same-origin request to GET /.well-known/openclaw/browser-bootstrap (under the Control UI base path, if configured). Existing credentials are tried first. Explicit credentials, remote Gateway selections, pairing failures, and rejected credentials do not trigger this recovery.

This endpoint belongs to the deployment's authenticated proxy or handoff service. OpenClaw does not expose an unauthenticated credential issuer. The service must independently verify the browser's identity and authorization before using the host's openclaw dashboard --json handoff. Return only its single-use browser credential:

{ "bootstrapToken": "<single-use-browser-bootstrap>", "bootstrapProfile": "owner" }

Use Content-Type: application/json and Cache-Control: no-store, reject cross-origin requests, and never return the shared Gateway token. The UI rejects redirects, responses larger than 8 KiB, and tokens longer than 4096 printable ASCII characters. The request has a 45-second deadline and is cancelled if the connection changes or the page stops. Successful recovery preserves the current dashboard route. If no endpoint is configured or the host declines the request, the existing login instructions remain available.

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.ownerAllowFrom or the selected account's effective channels.telegram.allowFrom.
  • Run /dashboard in 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 with network_mode: host and mount the host tailscaled socket (/var/run/tailscale) plus the tailscale CLI 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 does not expose a shared gateway token in the URL, and it does not receive the administrator grant reserved for handoffs issued directly by the Gateway host.

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 tunnel ssh -N -L 18789:127.0.0.1:18789 user@gateway-host then open http://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 (explicit deviceToken/scopes callers 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.
  • For Proxy authentication required or AUTH_IDENTITY_HEADER_REQUIRED, open the configured proxy/SSO dashboard URL and sign in there. Ask the Gateway administrator to check identity-header forwarding on WebSocket upgrades and account access. A Gateway token cannot override trusted-proxy mode; see Trusted proxy troubleshooting.
  • Outside that retry path, the Control UI prefers a pending bootstrap token so a fresh host-issued handoff can create or upgrade the browser credential. Without a pending bootstrap, explicit shared token/password take precedence over the stored device 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 show retry later.
  • For token drift repair steps, see Token drift recovery checklist.
  • For shared-secret authentication, retrieve or supply the configured secret from the gateway host:
    • Token: run openclaw gateway auth-token --show in an interactive terminal on the Gateway host
    • Password: resolve the configured gateway.auth.password or OPENCLAW_GATEWAY_PASSWORD
    • SecretRef-managed token: run openclaw gateway auth-token --show; if resolution fails, repair the external secret provider and rerun it
    • Runtime token generated because no shared secret was configured: run openclaw doctor --generate-gateway-token, restart the Gateway, then use the configured token
  • In the dashboard settings, paste the token or password into Gateway secret, then connect.
  • The UI language picker lives in Settings → Appearance → Language.