#17605: fix: preserve scopes when disableControlUiDeviceAuth is enabled
gateway
stale
size: XS
Cluster:
Device Auth and Security Fixes
## Summary
Fixes login errors in the Control UI when `dangerouslyDisableDeviceAuth` is enabled by preserving the scopes array instead of unnecessarily clearing it.
When `disableControlUiDeviceAuth` is true, the code was incorrectly clearing the scopes, causing authentication failures in the web UI.
## Changes
- Modified `src/gateway/server/ws-connection/message-handler.ts` to check `!disableControlUiDeviceAuth` before clearing scopes
## Testing
- Build passed successfully
- Lint and format checks passed
Fixes openclaw/openclaw#17601
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
This PR fixes a bug where the Control UI would fail to authenticate when `dangerouslyDisableDeviceAuth` is enabled and the client sends non-empty scopes. The root cause: when this option is true, the code sets `device = null` (line 346), which triggers the `!device` branch that unconditionally clears scopes. Without scopes, downstream method authorization in `server-methods.ts` and event broadcasting in `server-broadcast.ts` reject scope-gated operations.
The fix correctly guards the scope-clearing logic with `!disableControlUiDeviceAuth`, preserving scopes only when the operator has explicitly opted out of device identity checks. Security is maintained because shared-secret auth (token/password) is still required, origin validation is still enforced, and scopes are still checked at the method level via `authorizeGatewayMethod`.
- The one-line change at `message-handler.ts:430` adds `&& !disableControlUiDeviceAuth` to the scope-clearing condition
- No new tests were added; the existing e2e test (`server.auth.e2e.test.ts:661`) uses empty scopes and doesn't cover this specific scenario
<h3>Confidence Score: 4/5</h3>
- This PR is safe to merge — it's a targeted one-line fix that only affects an explicitly dangerous opt-in configuration path.
- The change is logically sound and consistent with the existing bypass behavior when `dangerouslyDisableDeviceAuth` is enabled. Auth and origin checks remain enforced. Scopes are still validated at the method level. The only concern is the lack of a test covering the specific scenario (non-empty scopes with disabled device auth), which lowers confidence from 5 to 4.
- No files require special attention beyond noting that `src/gateway/server.auth.e2e.test.ts` should ideally get a test case for non-empty scopes with `dangerouslyDisableDeviceAuth`.
<sub>Last reviewed commit: 1264995</sub>
<!-- greptile_other_comments_section -->
<sub>(1/5) You can manually trigger the agent by mentioning @greptileai in a comment!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#20089: fix(gateway): preserve control-ui scopes when dangerouslyDisableDev...
by vashkartik · 2026-02-18
91.2%
#17572: fix: make dangerouslyDisableDeviceAuth bypass device identity checks
by gitwithuli · 2026-02-15
91.0%
#17753: fix: Control UI unusable over HTTP - missing scopes
by MisterGuy420 · 2026-02-16
85.1%
#17378: fix(gateway): allow dangerouslyDisableDeviceAuth with trusted-proxy...
by ar-nadeem · 2026-02-15
84.7%
#23361: Gateway: reject scope assertions without identity binding
by bmendonca3 · 2026-02-22
84.7%
#19389: Fix #2248: Allow insecure auth bypass when device signature validat...
by cedillarack · 2026-02-17
83.2%
#16827: fix: allow device tokens with empty scopes to accept requested scopes
by MisterGuy420 · 2026-02-15
82.1%
#20422: Fix/tailscale device pairing
by slagyr · 2026-02-18
81.7%
#17195: fix: Add operator.read/write scopes to Dashboard auto-pairing
by MisterGuy420 · 2026-02-15
81.4%
#23280: fix(control-ui): remove stale allowInsecureAuth suggestion from err...
by anillBhoi · 2026-02-22
80.6%