#20422: Fix/tailscale device pairing
gateway
size: XS
Cluster:
Device Auth and Security Fixes
## Summary
Describe the problem and fix in 2–5 bullets:
- Problem: `dangerouslyDisableDeviceAuth` config only applied to Control UI, not webchat, causing "device identity required" errors when accessing webchat remotely
- Why it matters: Remote access via Tailscale VPN is blocked by device pairing chicken-and-egg problem (can't connect to pair, can't pair without connecting)
- What changed: Extended device auth bypass to webchat clients; added Tailscale auth method to skip device pairing (similar to shared auth)
- What did NOT change (scope boundary): Token authentication still required; device pairing still works normally when enabled; no changes to pairing logic itself
## Change Type (select all)
- [x] Bug fix
- [ ] Feature
- [ ] Refactor
- [ ] Docs
- [x] 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 #
- Related #
## User-visible / Behavior Changes
- When `gateway.controlUi.dangerouslyDisableDeviceAuth` is enabled, webchat clients can now connect without device pairing (previously only Control UI could)
- Tailscale-authenticated connections can skip device pairing (when Tailscale provides auth headers, currently not implemented by Tailscale)
## Security Impact (required)
- New permissions/capabilities? (`No` - only extends existing dangerouslyDisableDeviceAuth to webchat)
- Secrets/tokens handling changed? (`No`)
- New/changed network calls? (`No`)
- Command/tool execution surface changed? (`No`)
- Data access scope changed? (`No`)
- If any `Yes`, explain risk + mitigation: N/A
Note: The `dangerouslyDisableDeviceAuth` setting already exists and is marked dangerous. This PR makes it apply consistently to both Control UI and webchat. Token authentication is still required.
## Repro + Verification
### Environment
- OS: macOS (Darwin 24.6.0)
- Runtime/container: Node.js (OpenClaw gateway)
- Model/provider: Anthropic Claude Opus 4.6
- Integration/channel (if any): Webchat, Tailscale VPN
- Relevant config (redacted):
```json
{
"gateway": {
"auth": {
"mode": "token",
"allowTailscale": true
},
"controlUi": {
"dangerouslyDisableDeviceAuth": true
},
"tailscale": {
"mode": "serve"
}
}
}
```
### Steps
1. Configure gateway with `dangerouslyDisableDeviceAuth: true`
2. Access webchat from remote device via Tailscale URL (e.g., https://example.tail12345.ts.net)
3. Provide token authentication
### Expected
- Webchat connects successfully with token auth, skipping device pairing
### Actual
Before fix: "disconnected (1008): device identity required"
After fix: Connection succeeds
## Evidence
Attach at least one:
- [x] Failing test/log before + passing after
- [x] Trace/log snippets
- [ ] Screenshot/recording
- [ ] Perf numbers (if relevant)
Before fix:
```
[ws] webchat disconnected code=1008 reason=device identity required
```
After fix:
```
[ws] webchat connected conn=927fbd5d-0975-49b9-aeb9-fd96ed9705b9
```
Test updated: `src/gateway/server.auth.e2e.test.ts` now expects Tailscale auth to succeed
## Human Verification (required)
What you personally verified (not just CI), and how:
- Verified scenarios:
- Webchat access via Tailscale URL from remote device with `dangerouslyDisableDeviceAuth: true` ✓
- Token authentication still required ✓
- Gateway build and restart successful ✓
- Edge cases checked:
- Config without `dangerouslyDisableDeviceAuth` still requires pairing ✓
- Local access (127.0.0.1) works ✓
- Control UI access still works ✓
- What you did **not** verify:
- Actual Tailscale auth headers (Tailscale doesn't currently provide tailscale-user-login headers)
- Password auth mode with this setting
- Multiple concurrent webchat connections from different devices
## Compatibility / Migration
- Backward compatible? (`Yes` - only affects behavior when `dangerouslyDisableDeviceAuth` is explicitly enabled)
- Config/env changes? (`No` - uses existing config option)
- Migration needed? (`No`)
- If yes, exact upgrade steps: N/A
## Failure Recovery (if this breaks)
- How to disable/revert this change quickly: Set `gateway.controlUi.dangerouslyDisableDeviceAuth: false` in config (or remove it) and restart gateway
- Files/config to restore: Just config change, no file changes needed
- Known bad symptoms reviewers should watch for: Unexpected webchat connections without device pairing when setting is disabled
## Risks and Mitigations
- Risk: Users with `dangerouslyDisableDeviceAuth: true` now have webchat accessible without device pairing (new behavior)
- Mitigation: Token authentication is still required; setting is explicitly named "dangerous" to warn users; Tailscale serve mode restricts to VPN
- Risk: Tailscale auth implementation may not match actual Tailscale header format when/if implemented
- Mitigation: Code follows existing pattern from shared auth; will need testing when Tailscale adds auth headers
---
🤖 This PR was prepared with assistance from Claude Code
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
This PR fixes a device pairing chicken-and-egg problem for remote Tailscale VPN access by making two targeted changes to the gateway WebSocket handshake:
- **Extends `dangerouslyDisableDeviceAuth` to webchat clients**: Previously, this config flag only bypassed device auth for the Control UI. Now webchat connections also benefit, allowing remote access via Tailscale without needing to pair a device first.
- **Allows Tailscale-authenticated connections to skip device identity**: Adds `isTailscaleAuth` as an alternative to `sharedAuthOk` in the `canSkipDevice` check, so Tailscale-verified users don't need device pairing even without the dangerous flag.
- Token authentication remains required in all cases; the security boundary is maintained.
- Test updated to reflect the new expected behavior for Tailscale auth (previously expected rejection, now expects success).
- No dedicated test was added for the webchat + `dangerouslyDisableDeviceAuth` path — existing tests only cover this flag for Control UI clients.
<h3>Confidence Score: 4/5</h3>
- This PR is safe to merge — changes are minimal, logically correct, and maintain existing auth requirements.
- The two code changes are small and well-scoped. Both correctly extend existing bypass mechanisms without introducing new security surfaces. Token authentication is still required. The `dangerouslyDisableDeviceAuth` flag is already explicitly opt-in and named to warn users. The only gap is the absence of a dedicated test for the webchat + `dangerouslyDisableDeviceAuth` combination, though the control UI equivalent is tested and the code paths are shared.
- No files require special attention — `src/gateway/server/ws-connection/message-handler.ts` has a minor naming inconsistency but no logic issues.
<sub>Last reviewed commit: 577f87d</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
#17572: fix: make dangerouslyDisableDeviceAuth bypass device identity checks
by gitwithuli · 2026-02-15
83.9%
#17378: fix(gateway): allow dangerouslyDisableDeviceAuth with trusted-proxy...
by ar-nadeem · 2026-02-15
82.8%
#16310: fix(ws-connection): skip device pairing when client authenticates w...
by nawinsharma · 2026-02-14
82.7%
#17605: fix: preserve scopes when disableControlUiDeviceAuth is enabled
by MisterGuy420 · 2026-02-16
81.7%
#20089: fix(gateway): preserve control-ui scopes when dangerouslyDisableDev...
by vashkartik · 2026-02-18
80.7%
#17705: fix(gateway): allow trusted-proxy auth to bypass device-pairing gates
by dashed · 2026-02-16
79.3%
#17379: fix: restore device token priority in device-auth mode
by Limitless2023 · 2026-02-15
79.3%
#17425: fix(gateway): auto-approve scope/role upgrades for already-paired d...
by sauerdaniel · 2026-02-15
78.0%
#22712: fix(gateway): auto-approve all device pairing for localhost connect...
by NewdlDewdl · 2026-02-21
77.9%
#19937: fix(gateway): validate token/password auth modes and isolate gatewa...
by NewdlDewdl · 2026-02-18
77.7%