#16310: fix(ws-connection): skip device pairing when client authenticates with token
gateway
size: XS
Cluster:
Device Pairing and Gateway Fixes
## Summary
- **Problem:** With gateway bound to LAN and token auth, CLI commands (`openclaw gateway status`, `openclaw browser ...`, `openclaw devices list`) fail with "pairing required" even when `gateway.auth.token` is set. The web UI at `http://<host>:18789/#token=xxx` works fine.
- **Why it matters:** Users who run the gateway on a LAN host and use the token from config expect the CLI to work without opening the browser or pairing the CLI as a device first.
- **What changed:** The gateway now skips the device-pairing check whenever the client proves it has the gateway token/password. Before, only the control UI (in certain configs) could skip pairing with a token; now any client (CLI included) with a valid token can.
- **What did NOT change:** Control UI rules (HTTPS/localhost, allowInsecureAuth, etc.), URL building for LAN bind, token/password validation, or the “no device + token” path. Only the condition for skipping the pairing step was relaxed.
---
## Change Type (select all)
- [x] Bug fix
- [ ] Feature
- [ ] Refactor
- [ ] Docs
- [ ] Security hardening
- [ ] Chore/infra
---
## Scope (select all touched areas)
- [x] Gateway / orchestration
- [ ] Skills / tool execution
- [x] Auth / tokens
- [ ] Memory / storage
- [ ] Integrations
- [ ] API / contracts
- [ ] UI / DX
- [ ] CI/CD / infra
---
## Linked Issue/PR
- Closes #16305
---
## User-visible / Behavior Changes
- **Before:** CLI connecting with a valid gateway token but with an unpaired device (e.g. first time from that machine or after config change) got "pairing required" and could not run gateway/device commands.
- **After:** CLI with the same valid token can run those commands without pairing the device.
- No config or default changes. Behavior for already-paired devices and for the control UI is unchanged.
---
## Security Impact (required)
- New permissions/capabilities? **No** — we only treat “valid gateway token” as enough to skip pairing for all clients, not just the control UI.
- Secrets/tokens handling changed? **No** — same token in config, same validation; we don’t read or store tokens differently.
- New/changed network calls? **No** — same WebSocket connect flow.
- Command/tool execution surface changed? **No** — same RPCs; we only allow more clients that already had the token to complete the connect handshake.
- Data access scope changed? **No** — token already meant “operator” access; we didn’t add new scopes or data access.
**If any Yes, explain risk + mitigation:** N/A (all No).
---
## Repro + Verification
### Environment
- OS: e.g. CentOS Stream 10 (or any OS where gateway runs with LAN bind).
- Runtime/container: Node 22+ (or project’s supported runtime).
- Model/provider: N/A.
- Integration/channel: N/A.
- Relevant config (redacted):
- `gateway.bind: "lan"`, `gateway.port: 18789`, `gateway.mode: "local"`, `gateway.auth.mode: "token"`, `gateway.auth.token` set.
### Steps
1. Set gateway to LAN bind and set `gateway.auth.token` in config.
2. Ensure the CLI’s device is **not** in the gateway’s paired list (e.g. fresh install or different machine).
3. Run `openclaw gateway status` or `openclaw devices list` from the same host or another host on the LAN (using the LAN URL).
### Expected
- Commands succeed and show gateway/device info (no “pairing required”).
### Actual
- **Before this fix:** "gateway connect failed: Error: pairing required".
- **After this fix:** Commands succeed.
---
## Evidence
- [x] Failing behavior before (reported in issue / manual repro) and passing after (manual run of same commands).
- [ ] Trace/log snippets *(optional: add connect handshake or gateway log line showing token auth + no pairing block)*
- [ ] Screenshot/recording *(optional)*
- [ ] Perf numbers *(N/A)*
---
## Human Verification (required)
- **Verified scenarios:**
- Gateway server tests and `src/gateway/call.test.ts` (and related gateway tests) still pass.
- Logic review: only the `skipPairing` condition was changed; token validation and control-UI rules unchanged.
- **Edge cases checked:**
- Token still required for auth; no new “auth bypass.”
- Pairing still required when the client does *not* send a valid token/password.
- **What you did not verify:**
- Live run on a real LAN-bound gateway and CLI from another machine (recommended before merge if possible).
---
## Compatibility / Migration
- Backward compatible? **Yes** — we only allow more connections (token + unpaired device); previously working connections (paired device and/or control UI) behave the same.
- Config/env changes? **No.**
- Migration needed? **No.**
- If yes, exact upgrade steps: N/A.
---
## Failure Recovery (if this breaks)
- **How to revert:** Revert the single change in `src/gateway/server/ws-connection/message-handler.ts` (restore `skipPairing = allowControlUiBypass && sharedAuthOk`).
- **Files to restore:** That file only.
- **Symptoms to watch for:** If someone relied on “CLI must have device paired even with token,” they would see CLI connecting without pairing again; that’s the intended fix, not a regression.
---
## Risks and Mitigations
- **Risk:** Someone might interpret “token only” as “weaker” than “token + paired device.”
**Mitigation:** Token is the designed shared secret for the gateway; pairing is for devices that don’t have the token. We didn’t add a new auth bypass; we made token consistently sufficient for all clients.
- **Risk:** None identified for token handling, new network surface, or new capabilities.
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Changed device pairing logic to skip pairing for any client that authenticates with the gateway's shared secret (token or password), not just the control UI. Previously, CLI clients with a valid gateway token still triggered "pairing required" errors when their device wasn't paired, even though they had already proven possession of the gateway's shared secret. The fix removes the `allowControlUiBypass` condition from line 664, making token authentication consistently sufficient across all client types.
The change is minimal and well-targeted:
- Single-line logic change in `src/gateway/server/ws-connection/message-handler.ts:665`
- `sharedAuthOk` already validates token/password through `authorizeGatewayConnect` with rate limiting
- Device signature validation, nonce checking, and other security checks remain unchanged
- Only affects the pairing requirement, not authentication itself
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with minimal risk
- The change is a single-line logic simplification that makes authentication behavior consistent across client types. Token validation (`sharedAuthOk`) already goes through rate-limited authentication with the same security checks. The fix only relaxes when device pairing is required, not when authentication is required. All device signature validation, nonce checking, and other security checks remain in place. The change aligns with the stated security model where the gateway token is the shared secret that grants operator access.
- No files require special attention
<sub>Last reviewed commit: 2668d9a</sub>
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#22712: fix(gateway): auto-approve all device pairing for localhost connect...
by NewdlDewdl · 2026-02-21
84.8%
#21651: fix(gateway): token fallback + operator.admin scope superset in pai...
by lan17 · 2026-02-20
84.8%
#17379: fix: restore device token priority in device-auth mode
by Limitless2023 · 2026-02-15
83.9%
#15722: fix: prefer explicit token over stored device token for remote gate...
by 0xPotatoofdoom · 2026-02-13
83.8%
#23503: fix: preserve pairing state on device token mismatch + migrate lega...
by dorukardahan · 2026-02-22
83.0%
#17425: fix(gateway): auto-approve scope/role upgrades for already-paired d...
by sauerdaniel · 2026-02-15
82.9%
#20422: Fix/tailscale device pairing
by slagyr · 2026-02-18
82.7%
#19088: fix(gateway): allow startup with unset mode and fix pairing for local…
by mdanassaif · 2026-02-17
82.3%
#17378: fix(gateway): allow dangerouslyDisableDeviceAuth with trusted-proxy...
by ar-nadeem · 2026-02-15
82.0%
#17279: fix: restore device token priority over config token
by MisterGuy420 · 2026-02-15
81.7%