← Back to PRs

#22056: fix(gateway): use loopback for self-connections regardless of bind mode

by usedhonda open 2026-02-20 17:19 View on GitHub →
gateway size: S
## Problem Closes #22047 `bind: "lan"` causes the browser tool (and any Gateway self-connection) to fail with a `SECURITY ERROR` after the plaintext ws:// block introduced in #20803. Two commits are in conflict: - **#11448** — `localUrl` now uses the LAN IP when `bind=lan` - **#20803** — plaintext `ws://` to non-loopback addresses is rejected Result: agents running on the **same host** as the Gateway hit `SECURITY ERROR: Gateway URL "ws://192.168.x.x" uses plaintext ws:// to a non-loopback address.` ## Fix `localUrl` in `buildGatewayConnectionDetails()` always uses `ws(s)://127.0.0.1:<port>` regardless of bind mode. `bind` controls which interface the **server** listens on — it should not affect the connection URL for agents on the same host. LAN/tailnet IPs are still available in `lanIPv4` / `tailnetIPv4` for display purposes (QR codes, `urlSource` labels, onboarding hints). ## Changes - `src/gateway/call.ts`: `localUrl` simplified to `ws(s)://127.0.0.1:${localPort}` - `src/gateway/call.test.ts`: updated test names and assertions to reflect new behavior ## Tests ``` ✓ src/gateway/call.test.ts (29 tests) 167ms ``` All 29 tests passing. <!-- greptile_comment --> <h3>Greptile Summary</h3> Fixes a regression where `bind: "lan"` caused browser tools and Gateway self-connections to fail with `SECURITY ERROR` due to a conflict between two previous commits. The fix ensures agents on the same host always connect via `127.0.0.1` regardless of bind mode, since `bind` controls which interface the server listens on, not the connection URL for local agents. LAN/tailnet IPs remain available for display purposes (QR codes, onboarding hints). - Modified `buildGatewayConnectionDetails()` in `src/gateway/call.ts` to always use `ws(s)://127.0.0.1` for `localUrl`, removing the conditional logic that previously used LAN/tailnet IPs based on bind mode - Updated all related tests in `src/gateway/call.test.ts` to reflect the new behavior, converting tests that expected `SECURITY ERROR` exceptions into tests that verify loopback connections succeed - All 29 tests passing, confirming the fix resolves the security error while maintaining proper functionality <h3>Confidence Score: 5/5</h3> - This PR is safe to merge with minimal risk - The fix correctly resolves a clear regression caused by conflicting commits. The change is well-contained, maintains backward compatibility for all use cases, and actually improves security by ensuring local agents always use loopback addresses. All 29 tests pass, including updated tests that specifically verify the new behavior works correctly for all bind modes (loopback, lan, tailnet) with and without TLS. The implementation is simple, well-commented, and aligns with the security principle that ws:// to non-loopback addresses should be blocked. - No files require special attention <sub>Last reviewed commit: e97ebcf</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