Skip to content

Commit 2c3a536

Browse files
committed
docs(gateway): clarify auth retry and token-drift recovery
1 parent ac62943 commit 2c3a536

File tree

8 files changed

+82
-8
lines changed

8 files changed

+82
-8
lines changed

docs/cli/devices.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,40 @@ Pass `--token` or `--password` explicitly. Missing explicit credentials is an er
9292
- These commands require `operator.pairing` (or `operator.admin`) scope.
9393
- `devices clear` is intentionally gated by `--yes`.
9494
- If pairing scope is unavailable on local loopback (and no explicit `--url` is passed), list/approve can use a local pairing fallback.
95+
96+
## Token drift recovery checklist
97+
98+
Use this when Control UI or other clients keep failing with `AUTH_TOKEN_MISMATCH` or `AUTH_DEVICE_TOKEN_MISMATCH`.
99+
100+
1. Confirm current gateway token source:
101+
102+
```bash
103+
openclaw config get gateway.auth.token
104+
```
105+
106+
2. List paired devices and identify the affected device id:
107+
108+
```bash
109+
openclaw devices list
110+
```
111+
112+
3. Rotate operator token for the affected device:
113+
114+
```bash
115+
openclaw devices rotate --device <deviceId> --role operator
116+
```
117+
118+
4. If rotation is not enough, remove stale pairing and approve again:
119+
120+
```bash
121+
openclaw devices remove <deviceId>
122+
openclaw devices list
123+
openclaw devices approve <requestId>
124+
```
125+
126+
5. Retry client connection with the current shared token/password.
127+
128+
Related:
129+
130+
- [Dashboard auth troubleshooting](/web/dashboard#if-you-see-unauthorized-1008)
131+
- [Gateway troubleshooting](/gateway/troubleshooting#dashboard-control-ui-connectivity)

docs/gateway/protocol.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,12 @@ The Gateway treats these as **claims** and enforces server-side allowlists.
206206
persisted by the client for future connects.
207207
- Device tokens can be rotated/revoked via `device.token.rotate` and
208208
`device.token.revoke` (requires `operator.pairing` scope).
209+
- Auth failures include `error.details.code` plus recovery hints:
210+
- `error.details.canRetryWithDeviceToken` (boolean)
211+
- `error.details.recommendedNextStep` (`retry_with_device_token`, `update_auth_configuration`, `update_auth_credentials`, `wait_then_retry`, `review_auth_configuration`)
212+
- Client behavior for `AUTH_TOKEN_MISMATCH`:
213+
- Trusted clients may attempt one bounded retry with a cached per-device token.
214+
- If that retry fails, clients should stop automatic reconnect loops and surface operator action guidance.
209215

210216
## Device identity + pairing
211217

@@ -217,8 +223,9 @@ The Gateway treats these as **claims** and enforces server-side allowlists.
217223
- **Local** connects include loopback and the gateway host’s own tailnet address
218224
(so same‑host tailnet binds can still auto‑approve).
219225
- All WS clients must include `device` identity during `connect` (operator + node).
220-
Control UI can omit it **only** when `gateway.controlUi.dangerouslyDisableDeviceAuth`
221-
is enabled for break-glass use.
226+
Control UI can omit it only in these modes:
227+
- `gateway.controlUi.allowInsecureAuth=true` for localhost-only insecure HTTP compatibility.
228+
- `gateway.controlUi.dangerouslyDisableDeviceAuth=true` (break-glass, severe security downgrade).
222229
- All connections must sign the server-provided `connect.challenge` nonce.
223230

224231
### Device auth migration diagnostics

docs/gateway/security/index.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -262,9 +262,14 @@ High-signal `checkId` values you will most likely see in real deployments (not e
262262
## Control UI over HTTP
263263

264264
The Control UI needs a **secure context** (HTTPS or localhost) to generate device
265-
identity. `gateway.controlUi.allowInsecureAuth` does **not** bypass secure-context,
266-
device-identity, or device-pairing checks. Prefer HTTPS (Tailscale Serve) or open
267-
the UI on `127.0.0.1`.
265+
identity. `gateway.controlUi.allowInsecureAuth` is a local compatibility toggle:
266+
267+
- On localhost, it allows Control UI auth without device identity when the page
268+
is loaded over non-secure HTTP.
269+
- It does not bypass pairing checks.
270+
- It does not relax remote (non-localhost) device identity requirements.
271+
272+
Prefer HTTPS (Tailscale Serve) or open the UI on `127.0.0.1`.
268273

269274
For break-glass scenarios only, `gateway.controlUi.dangerouslyDisableDeviceAuth`
270275
disables device identity checks entirely. This is a severe security downgrade;

docs/gateway/troubleshooting.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,21 @@ Common signatures:
113113
challenge-based device auth flow (`connect.challenge` + `device.nonce`).
114114
- `device signature invalid` / `device signature expired` → client signed the wrong
115115
payload (or stale timestamp) for the current handshake.
116-
- `unauthorized` / reconnect loop → token/password mismatch.
116+
- `AUTH_TOKEN_MISMATCH` with `canRetryWithDeviceToken=true` → client can do one trusted retry with cached device token.
117+
- repeated `unauthorized` after that retry → shared token/device token drift; refresh token config and re-approve/rotate device token if needed.
117118
- `gateway connect failed:` → wrong host/port/url target.
118119

120+
### Auth detail codes quick map
121+
122+
Use `error.details.code` from the failed `connect` response to pick the next action:
123+
124+
| Detail code | Meaning | Recommended action |
125+
| ---------------------------- | -------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
126+
| `AUTH_TOKEN_MISSING` | Client did not send a required shared token. | Paste/set token in the client and retry. For dashboard paths: `openclaw config get gateway.auth.token` then paste into Control UI settings. |
127+
| `AUTH_TOKEN_MISMATCH` | Shared token did not match gateway auth token. | If `canRetryWithDeviceToken=true`, allow one trusted retry. If still failing, run the [token drift recovery checklist](/cli/devices#token-drift-recovery-checklist). |
128+
| `AUTH_DEVICE_TOKEN_MISMATCH` | Cached per-device token is stale or revoked. | Rotate/re-approve device token using [devices CLI](/cli/devices), then reconnect. |
129+
| `PAIRING_REQUIRED` | Device identity is known but not approved for this role. | Approve pending request: `openclaw devices list` then `openclaw devices approve <requestId>`. |
130+
119131
Device auth v2 migration check:
120132

121133
```bash
@@ -135,6 +147,7 @@ Related:
135147
- [/web/control-ui](/web/control-ui)
136148
- [/gateway/authentication](/gateway/authentication)
137149
- [/gateway/remote](/gateway/remote)
150+
- [/cli/devices](/cli/devices)
138151

139152
## Gateway service not running
140153

docs/help/faq.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2512,6 +2512,7 @@ Your gateway is running with auth enabled (`gateway.auth.*`), but the UI is not
25122512
Facts (from code):
25132513

25142514
- The Control UI keeps the token in `sessionStorage` for the current browser tab session and selected gateway URL, so same-tab refreshes keep working without restoring long-lived localStorage token persistence.
2515+
- On `AUTH_TOKEN_MISMATCH`, trusted clients can attempt one bounded retry with a cached device token when the gateway returns retry hints (`canRetryWithDeviceToken=true`, `recommendedNextStep=retry_with_device_token`).
25152516

25162517
Fix:
25172518

@@ -2520,6 +2521,9 @@ Fix:
25202521
- If remote, tunnel first: `ssh -N -L 18789:127.0.0.1:18789 user@host` then open `http://127.0.0.1:18789/`.
25212522
- Set `gateway.auth.token` (or `OPENCLAW_GATEWAY_TOKEN`) on the gateway host.
25222523
- In the Control UI settings, paste the same token.
2524+
- If mismatch persists after the one retry, rotate/re-approve the paired device token:
2525+
- `openclaw devices list`
2526+
- `openclaw devices rotate --device <id> --role operator`
25232527
- Still stuck? Run `openclaw status --all` and follow [Troubleshooting](/gateway/troubleshooting). See [Dashboard](/web/dashboard) for auth details.
25242528

25252529
### I set gatewaybind tailnet but it can't bind nothing listens

docs/help/troubleshooting.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,8 @@ flowchart TD
136136
Common log signatures:
137137

138138
- `device identity required` → HTTP/non-secure context cannot complete device auth.
139-
- `unauthorized` / reconnect loop → wrong token/password or auth mode mismatch.
139+
- `AUTH_TOKEN_MISMATCH` with retry hints (`canRetryWithDeviceToken=true`) → one trusted device-token retry may occur automatically.
140+
- repeated `unauthorized` after that retry → wrong token/password, auth mode mismatch, or stale paired device token.
140141
- `gateway connect failed:` → UI is targeting the wrong URL/port or unreachable gateway.
141142

142143
Deep pages:

docs/web/control-ui.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,12 @@ OpenClaw **blocks** Control UI connections without device identity.
174174
}
175175
```
176176

177-
`allowInsecureAuth` does not bypass Control UI device identity or pairing checks.
177+
`allowInsecureAuth` is a local compatibility toggle only:
178+
179+
- It allows localhost Control UI sessions to proceed without device identity in
180+
non-secure HTTP contexts.
181+
- It does not bypass pairing checks.
182+
- It does not relax remote (non-localhost) device identity requirements.
178183

179184
**Break-glass only:**
180185

docs/web/dashboard.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ Prefer localhost, Tailscale Serve, or an SSH tunnel.
4545
## If you see “unauthorized” / 1008
4646

4747
- Ensure the gateway is reachable (local: `openclaw status`; remote: SSH tunnel `ssh -N -L 18789:127.0.0.1:18789 user@host` then open `http://127.0.0.1:18789/`).
48+
- For `AUTH_TOKEN_MISMATCH`, clients may do one trusted retry with a cached device token when the gateway returns retry hints. If auth still fails after that retry, resolve token drift manually.
49+
- For token drift repair steps, follow [Token drift recovery checklist](/cli/devices#token-drift-recovery-checklist).
4850
- Retrieve or supply the token from the gateway host:
4951
- Plaintext config: `openclaw config get gateway.auth.token`
5052
- SecretRef-managed config: resolve the external secret provider or export `OPENCLAW_GATEWAY_TOKEN` in this shell, then rerun `openclaw dashboard`

0 commit comments

Comments
 (0)