Skip to content

fix(gateway): allow trusted-proxy auth to bypass device-pairing gates#17705

Closed
dashed wants to merge 4 commits intoopenclaw:mainfrom
dashed:fix/trusted-proxy-device-pairing
Closed

fix(gateway): allow trusted-proxy auth to bypass device-pairing gates#17705
dashed wants to merge 4 commits intoopenclaw:mainfrom
dashed:fix/trusted-proxy-device-pairing

Conversation

@dashed
Copy link
Copy Markdown
Contributor

@dashed dashed commented Feb 16, 2026

Summary

  • Trusted-proxy auth connections were rejected with "device identity required" (code 1008) because the device-pairing layer only recognized token and password auth methods
  • Two gates in message-handler.ts now also accept authOk && authMethod === "trusted-proxy"
  • Added 4 e2e tests covering both gates and negative cases

Root Cause

sharedAuthOk (used by both canSkipDevice and skipPairing gates) only checks for "token" or "password" methods. Trusted-proxy auth correctly sets authOk = true and authMethod = "trusted-proxy" via the primary authorizeGatewayConnect() call, but this was never consulted by the device-pairing layer.

Changes

Two lines changed in src/gateway/server/ws-connection/message-handler.ts:

Gate 1 (canSkipDevice, line 434):

- const canSkipDevice = sharedAuthOk;
+ const canSkipDevice = sharedAuthOk || (authOk && authMethod === "trusted-proxy");

Gate 2 (skipPairing, line 652):

- const skipPairing = allowControlUiBypass && sharedAuthOk;
+ const skipPairing =
+   (allowControlUiBypass && sharedAuthOk) || (authOk && authMethod === "trusted-proxy");

Comparison with PR #17378

This fix is more complete than #17378:

Aspect This PR PR #17378
Gate 1 (canSkipDevice) Fixed Fixed
Gate 2 (skipPairing) Fixed Not fixed
Requires dangerouslyDisableDeviceAuth? No Yes
Scope Trusted-proxy inherently skips device pairing Only skips when operator sets config flag

Trusted-proxy inherently proves user identity via the reverse proxy — requiring an additional dangerouslyDisableDeviceAuth flag is redundant and creates unnecessary operator friction.

Test Plan

4 new e2e tests in server.auth.e2e.test.ts:

  • Trusted-proxy connection without device identity succeeds (Gate 1)
  • Trusted-proxy control-ui with device identity skips pairing (Gate 2)
  • Connection from untrusted IP is rejected
  • Connection with missing user header is rejected
  • All 26 existing auth e2e tests pass (no regressions)
  • Lint, format, and type checks pass

Closes #8529
Related: #7384, #4833
Supersedes #17378

Greptile Summary

Fixed trusted-proxy auth connections that were incorrectly rejected with "device identity required" errors. The device-pairing layer now recognizes trusted-proxy auth method alongside token and password methods in two critical gates (canSkipDevice and skipPairing).

  • Two conditional checks in message-handler.ts now accept authOk && authMethod === "trusted-proxy" to allow trusted-proxy connections to bypass device pairing
  • Added comprehensive e2e test coverage for both bypass gates plus negative cases (untrusted IP, missing header)
  • Memory test file changes are formatting-only (oxfmt auto-formatting)
  • Fix is more complete than fix(gateway): allow dangerouslyDisableDeviceAuth with trusted-proxy auth mode #17378 by addressing both gates and not requiring additional config flags

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The fix is minimal, well-tested, and addresses a clear bug. The two-line logic change correctly extends the existing device-pairing bypass mechanism to include trusted-proxy auth. Comprehensive e2e tests cover both success and failure scenarios. The only other changes are formatting-only updates from oxfmt.
  • No files require special attention

Last reviewed commit: 8f5d07b

dashed and others added 4 commits February 27, 2026 01:11
The device-pairing layer only recognized "token" and "password" auth
methods via sharedAuthOk, causing trusted-proxy connections to be
incorrectly rejected at both the canSkipDevice and skipPairing gates.
Add authOk && authMethod === "trusted-proxy" checks to both gates.

resolve trusted-proxy-device-pairing root conflicts
Add 4 tests covering trusted-proxy auth interaction with device-pairing:
- connection without device identity succeeds (canSkipDevice gate)
- control-ui with device identity skips pairing (skipPairing gate)
- connection from untrusted IP is rejected
- connection with missing user header is rejected

resolve

resolve e2e test
@dashed dashed force-pushed the fix/trusted-proxy-device-pairing branch from cfae5d8 to 7cd4a14 Compare February 27, 2026 07:29
@dashed
Copy link
Copy Markdown
Contributor Author

dashed commented Feb 27, 2026

Closing: this fix has been absorbed upstream via the connect-policy.ts refactoring.

The current main branch now has:

  • isTrustedProxyControlUiOperatorAuth() — dedicated helper for trusted-proxy control-ui operator connections
  • evaluateMissingDeviceIdentity() — accepts trustedProxyAuthOk param, returns allow when true (Gate 1 bypass)
  • shouldSkipControlUiPairing() — accepts trustedProxyAuthOk param, returns true when true (Gate 2 bypass)

Both call sites in message-handler.ts now compute trustedProxyAuthOk and pass it through, achieving the same effect as this PR's changes.

The related auth-fallback PR #17746 (shared-secret fallback for when proxy auth fails) remains open and has been rebased directly onto main.

@dashed dashed closed this Feb 27, 2026
@dashed dashed deleted the fix/trusted-proxy-device-pairing branch February 27, 2026 11:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gateway Gateway runtime size: XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: disconnected (1008): device identity required

2 participants