From 8a6da9d488b5bfd3c1121c446c0d3bc8f2a8bd86 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 4 Apr 2026 16:09:42 +0100 Subject: [PATCH] docs: refresh gateway auth handshake refs --- docs/concepts/architecture.md | 10 ++++++++-- docs/concepts/typebox.md | 4 ++-- docs/gateway/protocol.md | 10 ++++++++-- docs/help/faq.md | 6 +++--- docs/web/index.md | 5 ++++- 5 files changed, 25 insertions(+), 10 deletions(-) diff --git a/docs/concepts/architecture.md b/docs/concepts/architecture.md index f2311b725b1..4fb5ad511d9 100644 --- a/docs/concepts/architecture.md +++ b/docs/concepts/architecture.md @@ -82,8 +82,14 @@ sequenceDiagram - After handshake: - Requests: `{type:"req", id, method, params}` → `{type:"res", id, ok, payload|error}` - Events: `{type:"event", event, payload, seq?, stateVersion?}` -- If `OPENCLAW_GATEWAY_TOKEN` (or `--token`) is set, `connect.params.auth.token` - must match or the socket closes. +- Shared-secret auth uses `connect.params.auth.token` or + `connect.params.auth.password`, depending on the configured gateway auth mode. +- Identity-bearing modes such as Tailscale Serve + (`gateway.auth.allowTailscale: true`) or non-loopback + `gateway.auth.mode: "trusted-proxy"` satisfy auth from request headers + instead of `connect.params.auth.*`. +- Private-ingress `gateway.auth.mode: "none"` disables shared-secret auth + entirely; keep that mode off public/untrusted ingress. - Idempotency keys are required for side‑effecting methods (`send`, `agent`) to safely retry; the server keeps a short‑lived dedupe cache. - Nodes must include `role: "node"` plus caps/commands/permissions in `connect`. diff --git a/docs/concepts/typebox.md b/docs/concepts/typebox.md index c85bbad3ed5..909b09cdc51 100644 --- a/docs/concepts/typebox.md +++ b/docs/concepts/typebox.md @@ -45,8 +45,8 @@ Common methods + events: | Category | Examples | Notes | | --------- | --------------------------------------------------------- | ---------------------------------- | | Core | `connect`, `health`, `status` | `connect` must be first | -| Messaging | `send`, `poll`, `agent`, `agent.wait` | side-effects need `idempotencyKey` | -| Chat | `chat.history`, `chat.send`, `chat.abort`, `chat.inject` | WebChat uses these | +| Messaging | `send`, `agent`, `agent.wait`, `system-event` | side-effects need `idempotencyKey` | +| Chat | `chat.history`, `chat.send`, `chat.abort` | WebChat uses these | | Sessions | `sessions.list`, `sessions.patch`, `sessions.delete` | session admin | | Nodes | `node.list`, `node.invoke`, `node.pair.*` | Gateway WS + node actions | | Events | `tick`, `presence`, `agent`, `chat`, `health`, `shutdown` | server push | diff --git a/docs/gateway/protocol.md b/docs/gateway/protocol.md index 809d95f5b44..92571e27054 100644 --- a/docs/gateway/protocol.md +++ b/docs/gateway/protocol.md @@ -420,8 +420,14 @@ Gateway exposes today. ## Auth -- If `OPENCLAW_GATEWAY_TOKEN` (or `--token`) is set, `connect.params.auth.token` - must match or the socket is closed. +- Shared-secret gateway auth uses `connect.params.auth.token` or + `connect.params.auth.password`, depending on the configured auth mode. +- Identity-bearing modes such as Tailscale Serve + (`gateway.auth.allowTailscale: true`) or non-loopback + `gateway.auth.mode: "trusted-proxy"` satisfy the connect auth check from + request headers instead of `connect.params.auth.*`. +- Private-ingress `gateway.auth.mode: "none"` skips shared-secret connect auth + entirely; do not expose that mode on public/untrusted ingress. - After pairing, the Gateway issues a **device token** scoped to the connection role + scopes. It is returned in `hello-ok.auth.deviceToken` and should be persisted by the client for future connects. diff --git a/docs/help/faq.md b/docs/help/faq.md index afac4147c26..5a8313ae25b 100644 --- a/docs/help/faq.md +++ b/docs/help/faq.md @@ -1455,14 +1455,14 @@ for usage/billing and raise limits as needed. - `gateway.remote.token` / `.password` do **not** enable local gateway auth by themselves. - Local call paths can use `gateway.remote.*` as fallback only when `gateway.auth.*` is unset. - If `gateway.auth.token` / `gateway.auth.password` is explicitly configured via SecretRef and unresolved, resolution fails closed (no remote fallback masking). - - The Control UI authenticates via `connect.params.auth.token` (stored in app/UI settings). Avoid putting tokens in URLs. + - Shared-secret Control UI setups authenticate via `connect.params.auth.token` or `connect.params.auth.password` (stored in app/UI settings). Identity-bearing modes such as Tailscale Serve or `trusted-proxy` use request headers instead. Avoid putting shared secrets in URLs. - OpenClaw enforces token auth by default, including loopback. If no token is configured, gateway startup auto-generates one and saves it to `gateway.auth.token`, so **local WS clients must authenticate**. This blocks other local processes from calling the Gateway. + OpenClaw enforces gateway auth by default, including loopback. In the normal default path that means token auth: if no explicit auth path is configured, gateway startup resolves to token mode and auto-generates one, saving it to `gateway.auth.token`, so **local WS clients must authenticate**. This blocks other local processes from calling the Gateway. - If you **really** want open loopback, set `gateway.auth.mode: "none"` explicitly in your config. Doctor can generate a token for you any time: `openclaw doctor --generate-gateway-token`. + If you prefer a different auth path, you can explicitly choose password mode (or, for non-loopback identity-aware reverse proxies, `trusted-proxy`). If you **really** want open loopback, set `gateway.auth.mode: "none"` explicitly in your config. Doctor can generate a token for you any time: `openclaw doctor --generate-gateway-token`. diff --git a/docs/web/index.md b/docs/web/index.md index d365a74a418..c59c4093130 100644 --- a/docs/web/index.md +++ b/docs/web/index.md @@ -98,7 +98,10 @@ Open: - 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 generates a gateway token by default (even on loopback). -- The UI sends `connect.params.auth.token` or `connect.params.auth.password`. +- In shared-secret mode, the UI sends `connect.params.auth.token` or + `connect.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.allowedOrigins` explicitly (full origins). Without it, gateway startup is refused by default. - `gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true` enables