Skip to content

fix(resilience): include RFC1918, CGNAT, and mDNS hosts in isLocalProvider (#11091) - #11122

Merged
diegosouzapw merged 2 commits into
cheaper-inference:release/v3.8.50from
rqzbeh:fix/is-local-provider-private-hosts
Aug 22, 2026
Merged

diegosouzapw merged 2 commits into
cheaper-inference:release/v3.8.50from
rqzbeh:fix/is-local-provider-private-hosts

Conversation

@rqzbeh

@rqzbeh rqzbeh commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Fixes #11091.

Root Cause

isLocalProvider(baseUrl) in open-sse/config/providerRegistry.ts matched only localhost, 127.0.0.1, 172.16.0.0/12, and LOCAL_HOSTNAMES. It missed 192.168.0.0/16, 10.0.0.0/8, 100.64.0.0/10 (Tailscale/CGNAT), 169.254.0.0/16, and .local / .internal hostnames. As a result, 404 responses from self-hosted LAN/Tailscale LLMs misclassified the host as non-local and triggered a whole-connection cooldown instead of a model-only lockout.

Fix

Updated isLocalProvider(baseUrl) to delegate hostname evaluation to isPrivateHost(hostname) from @/shared/network/outboundUrlGuard, which already covers all RFC1918, CGNAT/Tailscale, link-local, and mDNS private domain suffixes.

Test Coverage

Added unit test tests/unit/is-local-provider-11091.test.ts asserting that LAN (192.168.1.50, 10.0.0.5), Tailscale (100.64.1.2), link-local (169.254.1.1), mDNS (studio.local, mybox.internal), and Docker (172.18.0.2) hosts resolve to true, while public hosts (api.openai.com, 8.8.8.8) resolve to false.

@rqzbeh
rqzbeh requested a review from diegosouzapw as a code owner August 22, 2026 11:21
@mergify

mergify Bot commented Aug 22, 2026

Copy link
Copy Markdown

⚠️ The sha of the head commit of this PR conflicts with #11119. Mergify cannot evaluate rules on this PR. Once #11119 is merged or closed, Mergify will resume processing this PR. ⚠️

@rqzbeh
rqzbeh force-pushed the fix/is-local-provider-private-hosts branch from 9a483c5 to c26f886 Compare August 22, 2026 12:22
@mergify

mergify Bot commented Aug 22, 2026

Copy link
Copy Markdown

⚠️ The sha of the head commit of this PR conflicts with #11119. Mergify cannot evaluate rules on this PR. Once #11119 is merged or closed, Mergify will resume processing this PR. ⚠️

@yourspraveen

Copy link
Copy Markdown
Contributor

Heads-up on overlap: #11093 has been open against release/v3.8.50 since 05:31 UTC today
fixing this same issue, and is linked from #11091. Flagging it so the maintainers can pick
one rather than review both — no criticism intended, and I don't think this is duplicated
work in the avoidable sense: #11091 names isPrivateHost() and its file/line explicitly and
its "Suggested Fix" section prescribes the delegation, so any two implementations were always
going to converge on the same one-liner.

One behavioral difference worth carrying into whichever PR lands:

isPrivateHost() fails closed — an empty hostname returns true — because it guards
outbound egress. isLocalProvider() needs the opposite: its sole caller is the 404
model-lockout branch at src/sse/services/auth.ts:2955, which gates no request, so an
unparseable or hostname-less base URL should stay non-local. #11093 adds an explicit
if (!hostname) return false; ahead of the delegation for that reason. The version here
inherits the fail-closed behavior, so a file:-scheme or otherwise hostname-less baseUrl
would classify as local. Narrow, but it is a real divergence and it is deliberate in #11093.

On diff scope: this PR currently carries ~2,180 lines across 55 files — src/i18n/messages/*,
package.json, stryker.conf.json, and the quality baselines — against 2 files in #11093.
I think that is a rebase artifact rather than intent; some of it (skills/omni-webhooks/SKILL.md)
is the stale generated file that is currently failing check:agent-skills-sync on the base
tip via #9985, so it may be picking up base repairs.

Happy either way — @diegosouzapw, whichever you prefer to take.

@mergify

mergify Bot commented Aug 22, 2026

Copy link
Copy Markdown

⚠️ The sha of the head commit of this PR conflicts with #11119. Mergify cannot evaluate rules on this PR. Once #11119 is merged or closed, Mergify will resume processing this PR. ⚠️

@rqzbeh
rqzbeh force-pushed the fix/is-local-provider-private-hosts branch from 762611b to 35a4510 Compare August 22, 2026 14:48
@rqzbeh

rqzbeh commented Aug 22, 2026

Copy link
Copy Markdown
Contributor Author

Thank you @yourspraveen for the review!

Updated this PR with if (!hostname) return false; ahead of isPrivateHost so unparseable or hostname-less URLs fail open (stay non-local) as recommended, along with additional unit assertions.

@diegosouzapw
diegosouzapw force-pushed the fix/is-local-provider-private-hosts branch from cd7cf23 to 8237d4f Compare August 22, 2026 19:07
@diegosouzapw
diegosouzapw merged commit 4220c81 into cheaper-inference:release/v3.8.50 Aug 22, 2026
4 of 7 checks passed
diegosouzapw pushed a commit to yourspraveen/OmniRoute that referenced this pull request Aug 22, 2026
diegosouzapw pushed a commit that referenced this pull request Aug 22, 2026
…11154)

Validated on a worktree over the current tip: the red it fixes reproduced exactly as described (media-page-client-browser-bundle red since #11122 — providerRegistry became reachable from the dashboard client bundle via node:net). Post-fix: bundle test 2/2 green, new ip-parity suite + is-local-provider 7/7, all 7 outboundUrlGuard consumer suites 76/76 (the moved normalizeHost/isPrivateHost keep their re-exports; routing behavior untouched). Thank you @yourspraveen — clean surgical extraction with a pure-JS ipVersion mirroring Node's own regexes.
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…vider (cheaper-inference#11091) (cheaper-inference#11122)

Cherry-picked both value commits (a1fa49a8 + a91f6e93, incl. the fail-open guard for unparseable hostnames) onto the current tip, dropping the stale base-red sync commits. Focused tests: is-local-provider-11091 + the isLocalProvider consumer suites (provider-validation-specialty, ollama-local-provider) 127/127; mutation coverage no-drift. Fixes cheaper-inference#11091 — RFC1918/CGNAT/link-local/mDNS hosts now classify as local via the existing isPrivateHost. Thank you @rqzbeh!
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…nference#11122) (cheaper-inference#11154)

Validated on a worktree over the current tip: the red it fixes reproduced exactly as described (media-page-client-browser-bundle red since cheaper-inference#11122 — providerRegistry became reachable from the dashboard client bundle via node:net). Post-fix: bundle test 2/2 green, new ip-parity suite + is-local-provider 7/7, all 7 outboundUrlGuard consumer suites 76/76 (the moved normalizeHost/isPrivateHost keep their re-exports; routing behavior untouched). Thank you @yourspraveen — clean surgical extraction with a pure-JS ipVersion mirroring Node's own regexes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(resilience): isLocalProvider() misses RFC1918 / .local hosts — LAN-hosted backends lose per-model 404 lockout

3 participants