← Back to PRs

#18441: feat(gateway): add localNetworks config for subnet-scoped auto-pairing

by JayMishra-source open 2026-02-16 18:16 View on GitHub →
gateway stale size: S trusted-contributor
## Summary - Adds `gateway.localNetworks` config option that accepts CIDR ranges or exact IPs to treat as "local" for auto-pairing - By default, only loopback addresses (127.0.0.0/8, ::1) are trusted — no change in behavior for existing users - Operators running in Docker/Kubernetes opt-in to their specific bridge subnet instead of trusting all RFC1918 ranges - Adds `isLocalNetworkAddress()` helper in `net.ts` using existing CIDR matching infrastructure - Threads `localNetworks` through all `isLocalDirectRequest` and `authorizeGatewayConnect` call sites Example config: ```json { "gateway": { "localNetworks": ["172.17.0.0/16"] } } ``` This replaces the original approach (trusting all RFC1918 private ranges) after security review feedback from @HenryLoenwind — blindly treating all private addresses as "local" is dangerous in multi-tenant environments where untrusted guests share the same address space. ## Test plan - [x] Unit tests for `isLocalNetworkAddress` covering CIDR matching, exact IPs, IPv4-mapped IPv6, empty/undefined config - [ ] Verify auto-pairing works from Docker container when `localNetworks: ["172.17.0.0/16"]` is set - [ ] Verify auto-pairing is rejected from private IPs when `localNetworks` is not configured (default behavior unchanged) 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- greptile_comment --> <h3>Greptile Summary</h3> Adds a `gateway.localNetworks` config option that lets operators define specific CIDR ranges or IPs to treat as "local" for auto-pairing, replacing the earlier approach of blindly trusting all RFC1918 private ranges. This is a security-conscious design that defaults to loopback-only and requires explicit opt-in for container networking subnets (e.g., Docker bridge `172.17.0.0/16`). - New `isLocalNetworkAddress()` helper in `net.ts` reuses existing `normalizeIp()` and `ipMatchesCIDR()` infrastructure — structurally identical to `isTrustedProxyAddress()`. - `localNetworks` is consistently threaded through all `isLocalDirectRequest()` and `authorizeGatewayConnect()` call sites in `server-http.ts` and `message-handler.ts`. - Good unit test coverage for CIDR matching, exact IPs, IPv4-mapped IPv6, and edge cases. - Note: `handleToolsInvokeHttpRequest` does not pass `localNetworks` to `authorizeGatewayConnect`, but this only affects the Tailscale fallback path (not auth bypass), so the impact is minimal — worth considering for consistency in a follow-up. <h3>Confidence Score: 4/5</h3> - This PR is safe to merge — it adds an opt-in security feature with safe defaults and follows existing patterns throughout. - Score of 4 reflects a well-structured, security-conscious change that follows existing patterns (`trustedProxies`). Deducted 1 point because: (1) the `localNetworks` config is not threaded to `handleToolsInvokeHttpRequest`, creating a minor inconsistency, and (2) the manual integration test plan items are not yet verified (marked unchecked in the PR description). The code itself is correct and the default behavior is unchanged. - `src/gateway/auth.ts` deserves closest review — it contains the core security logic change where `localNetworks` broadens the definition of a "local" request for auth bypass. <sub>Last reviewed commit: 14cfad7</sub> <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs