Skip to content

fix: honor env proxy for provider guarded fetch#72480

Closed
mjamiv wants to merge 2 commits intoopenclaw:mainfrom
mjamiv:fix/provider-guard-env-proxy
Closed

fix: honor env proxy for provider guarded fetch#72480
mjamiv wants to merge 2 commits intoopenclaw:mainfrom
mjamiv:fix/provider-guard-env-proxy

Conversation

@mjamiv
Copy link
Copy Markdown
Contributor

@mjamiv mjamiv commented Apr 27, 2026

Summary

  • Let provider guarded fetch use trusted env-proxy mode when standard proxy env vars apply and no explicit provider dispatcher policy is configured.
  • Preserve strict guarded-fetch behavior for explicit provider dispatcher policies, including direct/TLS/explicit-proxy overrides.
  • Add focused regression coverage for both paths.

Root Cause

  • Provider model requests already flow through fetchWithSsrFGuard, but the default strict mode DNS-pins the final provider hostname before an ambient HTTP(S) proxy can resolve it.
  • Gateway startup env-proxy bootstrap covers global Undici traffic, but this provider guarded-fetch path passes through the SSRF guard seam directly.
  • In proxy-required environments with no direct DNS, that can still fail even though HTTPS_PROXY is configured.

User-visible / Behavior Changes

Provider model requests now honor standard env proxy routing in the guarded-fetch path when there is no explicit provider transport override. Explicit provider transport settings keep their current behavior.

Security Impact

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No

This only selects the existing trusted env-proxy guarded-fetch preset for provider-owned model request URLs when env proxy rules apply.

Repro + Verification

Environment

  • OS: Linux
  • Runtime/container: local repo test worktree
  • Model/provider: OpenAI-compatible provider fetch seam
  • Relevant config: HTTPS_PROXY set, no explicit provider dispatcher policy

Steps

  1. Configure HTTPS_PROXY.
  2. Build a guarded provider fetch for an HTTPS model endpoint with no explicit provider transport override.
  3. Send a request through the fetch seam.

Expected

  • The guarded fetch options use trusted env-proxy mode.
  • Explicit provider dispatcher policies are not overridden.

Actual

  • Before this patch, provider calls stayed on strict guarded-fetch mode.
  • After this patch, env proxy mode is selected only for the no-explicit-dispatcher case.

Evidence

  • pnpm test src/agents/provider-transport-fetch.test.ts
  • pnpm exec oxfmt --check --threads=1 src/agents/provider-transport-fetch.ts src/agents/provider-transport-fetch.test.ts
  • git diff --check
  • pnpm check:changed --base upstream/main

Human Verification

  • Verified the focused provider transport test passes.
  • Verified changed-lane typecheck, lint, import-cycle, and related guards pass through pnpm check:changed --base upstream/main.
  • Did not run a live provider call in a proxy-only environment from this branch.

Compatibility / Migration

  • Backward compatible? Yes
  • Config/env changes? No
  • Migration needed? No

Risks and Mitigations

  • Risk: accidentally bypassing explicit provider transport overrides.
    • Mitigation: the env-proxy preset is selected only when buildProviderRequestDispatcherPolicy() returns no dispatcher policy, with a regression test for explicit dispatcher preservation.

@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: S labels Apr 27, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 27, 2026

Greptile Summary

This PR fixes provider-guarded fetch to honor standard HTTP proxy env vars (HTTPS_PROXY, HTTP_PROXY, etc.) when no explicit provider dispatcher policy is configured, by upgrading the guarded-fetch options to trusted_env_proxy mode via withTrustedEnvProxyGuardedFetchMode. When an explicit dispatcher policy exists, the existing strict behavior is preserved. Two regression tests cover both the env-proxy upgrade path and the explicit-dispatcher preservation path.

Confidence Score: 5/5

This PR is safe to merge — the change is minimal, well-scoped, and backed by focused regression tests.

The logic correctly gates the env-proxy upgrade on two conditions (!dispatcherPolicy && shouldUseEnvHttpProxyForUrl(url)) and delegates to the existing, already-audited withTrustedEnvProxyGuardedFetchMode helper. The NO_PROXY SSRF bypass concern noted in prior review threads is fully handled by shouldUseEnvHttpProxyForUrl (which calls matchesNoProxy internally). fetch-guard.ts also re-checks shouldUseEnvHttpProxyForUrl on each redirect hop, so redirect-induced proxy bypass is not a risk. No security surface changes were introduced.

No files require special attention.

Reviews (1): Last reviewed commit: "fix: honor env proxy for provider guarde..." | Re-trigger Greptile

@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented Apr 27, 2026

Codex review: needs changes before merge.

Summary
The PR makes provider guarded model fetches use trusted env-proxy mode only when HTTP(S) proxy env routing applies and no explicit provider dispatcher policy exists, with regression tests and a changelog entry.

Reproducibility: yes. Current main calls fetchWithSsrFGuard from buildGuardedModelFetch without a trusted env-proxy mode, while fetch-guard defaults to strict DNS-pinned behavior; the PR tests cover the HTTPS_PROXY/no-dispatcher case and explicit-dispatcher preservation.

Next step before merge
Queueing is appropriate because the only actionable blocker is a narrow mechanical rebase/changelog refresh around an otherwise sound patch.

Security
Cleared: The diff changes a security-sensitive fetch-mode decision, but it reuses existing guarded-fetch/proxy-env helpers, preserves explicit dispatcher policies, and adds no dependency, workflow, script, package, secret, or third-party execution changes.

Review findings

  • [P3] Refresh the changelog hunk onto current main — CHANGELOG.md:19
Review details

Best possible solution:

Refresh the branch onto current main, keep the no-dispatcher plus shouldUseEnvHttpProxyForUrl gate and regression tests, place the changelog bullet in the current Unreleased Fixes section, then land it and update related issue #70453.

Do we have a high-confidence way to reproduce the issue?

Yes. Current main calls fetchWithSsrFGuard from buildGuardedModelFetch without a trusted env-proxy mode, while fetch-guard defaults to strict DNS-pinned behavior; the PR tests cover the HTTPS_PROXY/no-dispatcher case and explicit-dispatcher preservation.

Is this the best way to solve the issue?

Yes, functionally. Reusing withTrustedEnvProxyGuardedFetchMode behind shouldUseEnvHttpProxyForUrl and a no-dispatcherPolicy guard is the narrow maintainable fix; the remaining blocker is branch freshness, not the core approach.

Full review comments:

  • [P3] Refresh the changelog hunk onto current main — CHANGELOG.md:19
    GitHub currently reports this head as dirty/unmergeable, and the added changelog line is anchored in an older Unreleased block. Rebase or merge current main and keep this provider bullet in the current ### Fixes section so the PR applies cleanly.
    Confidence: 0.91

Overall correctness: patch is correct
Overall confidence: 0.88

Acceptance criteria:

  • pnpm test src/agents/provider-transport-fetch.test.ts --run
  • pnpm exec oxfmt --check --threads=1 src/agents/provider-transport-fetch.ts src/agents/provider-transport-fetch.test.ts CHANGELOG.md
  • git diff --check
  • pnpm check:changed --base origin/main

What I checked:

  • current_main_provider_fetch_still_strict: Current main builds provider guarded fetch options and calls fetchWithSsrFGuard directly, passing dispatcherPolicy but no trusted env-proxy mode or shouldUseEnvHttpProxyForUrl gate. (src/agents/provider-transport-fetch.ts:296, 8f20d03373f8)
  • fetch_guard_default_and_env_proxy_behavior: fetchWithSsrFGuard defaults to strict mode unless a mode is supplied, and trusted_env_proxy still re-checks shouldUseEnvHttpProxyForUrl before creating the EnvHttpProxyAgent on each URL. (src/infra/net/fetch-guard.ts:115, 8f20d03373f8)
  • proxy_gate_matches_dependency_contract: The repo helper only returns true for http/https targets when HTTP_PROXY/HTTPS_PROXY routing applies and NO_PROXY does not match; Undici v8.1.0 EnvHttpProxyAgent source confirms lower-case env precedence, HTTPS fallback, and NO_PROXY bypass behavior. (src/infra/net/proxy-env.ts:93, 8f20d03373f8)
  • pr_adds_narrow_gate: The PR wraps guardedFetchOptions with withTrustedEnvProxyGuardedFetchMode only when dispatcherPolicy is absent and shouldUseEnvHttpProxyForUrl(url) is true. (src/agents/provider-transport-fetch.ts:312, 4c6af04c4c0c)
  • pr_tests_cover_both_paths: The PR adds tests for HTTPS_PROXY with no explicit dispatcher policy and for preserving strict behavior when an explicit direct dispatcher policy exists. (src/agents/provider-transport-fetch.test.ts:139, 4c6af04c4c0c)
  • current_head_is_dirty: The GitHub PR API reports mergeable=false, rebaseable=false, mergeable_state=dirty for head 4c6af04; current main is 8f20d03 and its Unreleased section has moved since the PR's CHANGELOG hunk. (CHANGELOG.md:24, 8f20d03373f8)

Likely related people:

  • steipete: Recent history shows repeated maintenance on provider transport, proxy-env, and guarded fetch behavior, including shared proxy-env checks and provider HTTP timeout/error helpers. (role: recent maintainer and core provider/proxy owner; confidence: high; commits: c973b053a5e2, dc859584a352, 74211128983a; files: src/agents/provider-transport-fetch.ts, src/infra/net/proxy-env.ts, src/infra/net/fetch-guard.ts)
  • MkDev11: Recent merged work touched the same provider guarded fetch and fetch timeout surface that this PR adjusts. (role: recent adjacent maintainer; confidence: medium; commits: ffd3dfa4f543; files: src/agents/provider-transport-fetch.ts, src/infra/net/fetch-guard.ts)
  • vincentkoc: Authored the media-understanding trusted env-proxy auto-upgrade pattern using shouldUseEnvHttpProxyForUrl, which this PR mirrors for model provider fetches. (role: adjacent env-proxy pattern owner; confidence: medium; commits: 6ee8e194c027, e58d50b7a848; files: src/media-understanding/shared.ts, src/infra/net/proxy-env.ts)
  • Takhoffman: Earlier merged work added env proxy bootstrap/model traffic and proxy capture plumbing that forms the broader transport context for this fix. (role: earlier proxy transport contributor; confidence: medium; commits: 87876a3e36db, 958c34e82cdb; files: src/infra/net/proxy-env.ts, src/infra/net/fetch-guard.ts)

Remaining risk / open question:

  • No live provider call in a proxy-only or fake-IP DNS environment was run during this read-only pass; the reproduction is source and regression-test based.
  • The branch is currently dirty against main, so the changelog conflict must be resolved before merge validation is meaningful.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 8f20d03373f8.

@mjamiv
Copy link
Copy Markdown
Contributor Author

mjamiv commented May 1, 2026

Added the required Unreleased changelog entry and pushed c6564dd.

Local validation passed:

  • git diff --check
  • grep -n "mjamiv\|72480\|guarded provider model fetches\|env-proxy" CHANGELOG.md

@mjamiv mjamiv force-pushed the fix/provider-guard-env-proxy branch from c6564dd to 4c6af04 Compare May 1, 2026 01:54
@mjamiv
Copy link
Copy Markdown
Contributor Author

mjamiv commented May 1, 2026

Refreshed this branch onto current upstream/main and force-with-lease pushed 4c6af04.

This keeps the provider guarded-fetch env-proxy patch plus the required changelog entry, resolving the merge conflict that appeared after the changelog-only push.

Local validation passed after the refresh:

  • pnpm test src/agents/provider-transport-fetch.test.ts --run
  • pnpm exec oxfmt --check --threads=1 src/agents/provider-transport-fetch.test.ts src/agents/provider-transport-fetch.ts CHANGELOG.md
  • git diff --check
  • grep -n "mjamiv\|72480\|guarded provider model fetches\|env-proxy" CHANGELOG.md
  • pnpm check:changed --base upstream/main

@steipete
Copy link
Copy Markdown
Contributor

steipete commented May 3, 2026

Post-#76887 status: this is still the focused fix for #70453, but GitHub now reports the branch as DIRTY / conflicting against current main. The conflict is expected because #76887 also changed src/agents/provider-transport-fetch.ts and src/agents/provider-transport-fetch.test.ts.

When rebasing, preserve #76887's scoped fake-IP host policy and the fix that keeps target host allowlists out of explicit proxy-host validation. After rebase, the useful proof is the focused provider transport test plus Testbox pnpm check:changed.

@steipete
Copy link
Copy Markdown
Contributor

steipete commented May 3, 2026

I rebased this patch locally onto current main after #76887 and the conflict is mechanical, not a design blocker. The clean merge shape is:

  • keep fix(network): scope fake-IP SSRF policy to provider hosts #76887's scoped provider-host fake-IP policy in src/agents/provider-transport-fetch.ts
  • wrap the final guarded-fetch options in withTrustedEnvProxyGuardedFetchMode(...) only when !dispatcherPolicy && shouldUseEnvHttpProxyForUrl(url)
  • preserve explicit provider dispatcher policies in strict mode
  • keep the provider-host policy attached when auto-upgrading so the scoped fake-IP behavior remains visible to the guarded-fetch seam

Maintainer rebase proof from the local patch:

  • pnpm exec oxfmt --check --threads=1 src/agents/provider-transport-fetch.ts src/agents/provider-transport-fetch.test.ts CHANGELOG.md
  • pnpm test src/agents/provider-transport-fetch.test.ts --run
  • Testbox pnpm check:changed on tbx_01kqqs7kg74ae6ha5st170ca5p passed, exit 0.

So this PR is still the right focused fix for #70453; it just needs that rebase shape applied to the branch.

@steipete
Copy link
Copy Markdown
Contributor

steipete commented May 3, 2026

Landed on main as ca620fb. Thanks @mjamiv.\n\nI rebased the patch over #76887 so provider guarded fetch now honors env proxy routing when no explicit dispatcher policy is configured, while preserving the scoped fake-IP provider-host policy and explicit transport overrides.

@steipete steipete closed this May 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants