Skip to content

fix(onboard): forward host proxy env into sandbox (Fixes #4304)#4331

Merged
cv merged 5 commits into
NVIDIA:mainfrom
deepujain:fix/4304-forward-host-proxy-env
Jun 3, 2026
Merged

fix(onboard): forward host proxy env into sandbox (Fixes #4304)#4331
cv merged 5 commits into
NVIDIA:mainfrom
deepujain:fix/4304-forward-host-proxy-env

Conversation

@deepujain

@deepujain deepujain commented May 27, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #4304.

nemoclaw onboard already builds a proxy-aware environment for host subprocesses, but the sandbox startup command only forwarded a small explicit env list. That meant HTTP_PROXY, HTTPS_PROXY, and NO_PROXY never reached nemoclaw-start inside the sandbox.

Changes

  • Forward standard host proxy variables into the sandbox startup env args when a proxy is configured.
  • Reuse the existing local NO_PROXY augmentation so loopback and Docker host names are not sent through the proxy.
  • Add focused tests for the helper and the actual sandbox create -- env ... nemoclaw-start command shape.

Testing

  • npm run build:cli
  • npm run typecheck:cli
  • npx vitest run test/onboard.test.ts -t 'host proxy|DASHBOARD_PORT'
  • npx vitest run src/lib/subprocess-env.test.ts

Signed-off-by: Deepak Jain deepujain@gmail.com

Summary by CodeRabbit

  • Chores
    • Sandbox creation now reliably forwards host proxy settings (HTTP/HTTPS proxy + NO_PROXY). NO_PROXY is augmented with localhost-related defaults and proxy values are trimmed so network tooling in sandboxes works consistently.
  • Tests
    • Added and strengthened tests to validate proxy forwarding, whitespace trimming, case-insensitive NO_PROXY handling, and to harden sandbox-creation checks against inherited runner proxy settings.

@copy-pr-bot

copy-pr-bot Bot commented May 27, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented May 27, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Collects host proxy env vars (HTTP_PROXY, HTTPS_PROXY, NO_PROXY), normalizes NO_PROXY, appends formatted env assignments to sandbox startup envArgs via appendHostProxyEnvArgs, wires the helper into onboard's sandbox creation, and adds unit/integration tests to validate propagation.

Changes

Host Proxy Environment Propagation

Layer / File(s) Summary
Proxy env helper
src/lib/onboard/host-proxy-env.ts
Adds HOST_PROXY_ENV_NAMES and appendHostProxyEnvArgs(envArgs, env?) that collects non-empty proxy vars, applies NO_PROXY normalization, and appends name=value env assignments to envArgs.
Onboard wiring
src/lib/onboard.ts
Minor whitespace change near build-context imports and calls appendHostProxyEnvArgs(envArgs) when assembling nemoclaw-start envArgs for sandbox creation.
Test coverage and dashboard-port adjustments
test/onboard.test.ts
Imports appendHostProxyEnvArgs into tests, adds unit tests confirming proxy-appending behavior (including NO_PROXY expansion and trimming), and updates the dashboard-port test to strip inherited proxy env and assert HTTP_PROXY, HTTPS_PROXY, and expanded NO_PROXY appear in the spawned sandbox envArgs.

Sequence Diagram

sequenceDiagram
  participant HostEnv as Host Environment
  participant Onboard as onboard.ts
  participant Helper as appendHostProxyEnvArgs
  participant Sandbox as Sandbox startup
  HostEnv->>Onboard: process.env (contains proxy vars)
  Onboard->>Helper: appendHostProxyEnvArgs(envArgs, env)
  Helper->>Onboard: envArgs with HTTP_PROXY/HTTPS_PROXY/NO_PROXY assignments
  Onboard->>Sandbox: spawn sandbox with appended envArgs
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

area: networking

Suggested reviewers

  • cv
  • prekshivyas

Poem

I hopped through envs with whiskers twitching bright,
I gathered proxies by day and normalized by night.
NO_PROXY now knows localhost, loopback, and more,
Sandbox children inherit what the host store.
🐇📡

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: forwarding host proxy environment variables into the sandbox during onboard, directly addressing the issue #4304.
Linked Issues check ✅ Passed The PR fully addresses issue #4304 by forwarding HTTP_PROXY, HTTPS_PROXY, and NO_PROXY environment variables into the sandbox via new helper function appendHostProxyEnvArgs, with comprehensive tests validating proxy propagation behavior.
Out of Scope Changes check ✅ Passed All changes are directly scoped to addressing #4304: adding proxy forwarding logic, helper function implementation, test coverage for proxy behavior, and hardening existing dashboard-port tests against proxy env inheritance.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/lib/onboard.ts (1)

3558-3558: Run the onboarding-focused E2E subset before merge.

Given this touches core onboarding env propagation, run the listed onboarding/sandbox lifecycle E2Es to guard against regressions across full flow.

As per coding guidelines, src/lib/onboard.ts is core onboarding logic and changes here affect the full sandbox creation and configuration flow, with the recommended E2E suites provided.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/onboard.ts` at line 3558, This change touches core onboarding env
propagation at the call to appendHostProxyEnvArgs in onboard.ts—before merging,
run the onboarding-focused E2E subset (the onboarding and sandbox lifecycle
suites) to validate the full sandbox creation/configuration flow; execute the
project's E2E runner for those suites, verify all tests pass, and if any fail,
reproduce locally, capture failing test logs, and fix the propagation issue in
the appendHostProxyEnvArgs usage or related onboarding setup until the suites
are green.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/onboard.test.ts`:
- Around line 3003-3005: The NO_PROXY assertion is order-dependent and missing
host.docker.internal; change the test on createCommand.command to first extract
the NO_PROXY value with a regex (e.g. match /NO_PROXY=([^\\s]+)/ and capture
group 1), split that value on commas into an array, then assert that the array
contains each expected entry ("corp.internal", "localhost", "127.0.0.1",
"host.docker.internal") with separate contains/assertions so order won't matter
and the missing host.docker.internal is checked.

---

Nitpick comments:
In `@src/lib/onboard.ts`:
- Line 3558: This change touches core onboarding env propagation at the call to
appendHostProxyEnvArgs in onboard.ts—before merging, run the onboarding-focused
E2E subset (the onboarding and sandbox lifecycle suites) to validate the full
sandbox creation/configuration flow; execute the project's E2E runner for those
suites, verify all tests pass, and if any fail, reproduce locally, capture
failing test logs, and fix the propagation issue in the appendHostProxyEnvArgs
usage or related onboarding setup until the suites are green.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: f53d1b54-87e8-4231-98f1-6775435a8eee

📥 Commits

Reviewing files that changed from the base of the PR and between e139dbc and fda65cb.

📒 Files selected for processing (2)
  • src/lib/onboard.ts
  • test/onboard.test.ts

Comment thread test/onboard.test.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/lib/onboard.ts (1)

3522-3522: Run the onboarding E2E subset before merge.

Since this change is in src/lib/onboard.ts and directly affects sandbox startup env wiring, run the recommended onboarding E2E jobs to de-risk regressions across sandbox lifecycle and messaging/provider paths.

As per coding guidelines, src/lib/onboard.ts changes affect the full sandbox creation/configuration flow and should use the listed E2E recommendations.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/onboard.ts` at line 3522, Change to environment wiring in
src/lib/onboard.ts (the call requiring ./onboard/host-proxy-env and
appendHostProxyEnvArgs) can break sandbox startup; before merging, run the
recommended onboarding E2E subset (the onboarding/sandbox lifecycle and
messaging/provider E2E jobs referenced in the coding guidelines) and confirm
they all pass, iterate on any failures in src/lib/onboard.ts or
./onboard/host-proxy-env (e.g., appendHostProxyEnvArgs) until green, and attach
the passing job run IDs to the PR.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/lib/onboard.ts`:
- Line 3522: Change to environment wiring in src/lib/onboard.ts (the call
requiring ./onboard/host-proxy-env and appendHostProxyEnvArgs) can break sandbox
startup; before merging, run the recommended onboarding E2E subset (the
onboarding/sandbox lifecycle and messaging/provider E2E jobs referenced in the
coding guidelines) and confirm they all pass, iterate on any failures in
src/lib/onboard.ts or ./onboard/host-proxy-env (e.g., appendHostProxyEnvArgs)
until green, and attach the passing job run IDs to the PR.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: f7a443f5-f294-48ff-b5c0-4eb48c7cfc62

📥 Commits

Reviewing files that changed from the base of the PR and between ebdbe2b and c956872.

📒 Files selected for processing (2)
  • src/lib/onboard.ts
  • test/onboard.test.ts

@deepujain

Copy link
Copy Markdown
Contributor Author

Moved proxy propagation into a focused onboard helper, made the NO_PROXY assertion order-independent, and kept the top-level onboard budget green. Local checks: build:cli, typecheck:cli, lint, and full test/onboard.test.ts.

@wscurran

Copy link
Copy Markdown
Contributor

✨ Thanks for submitting this detailed PR that fixes the issue where the sandbox startup command does not forward host proxy environment variables. This proposes a fix for the issue reported in #4304 and improves the sandbox environment setup.


Related open issues:

deepujain added 3 commits May 29, 2026 18:47
Fixes NVIDIA#4304

Signed-off-by: Deepak Jain <deepujain@gmail.com>
Signed-off-by: Deepak Jain <deepujain@gmail.com>
Signed-off-by: Deepak Jain <deepujain@gmail.com>
@deepujain deepujain force-pushed the fix/4304-forward-host-proxy-env branch from c956872 to dbc9e05 Compare May 30, 2026 02:01
@deepujain

Copy link
Copy Markdown
Contributor Author

Rebased on current main and preserved the host proxy env wiring alongside the current onboarding env setup. build:cli and focused host-proxy checks pass.

@wscurran wscurran added the v0.0.58 Release target label Jun 2, 2026
@wscurran wscurran added area: cli Command line interface, flags, terminal UX, or output area: sandbox OpenShell sandbox lifecycle, runtime, config, or recovery bug-fix PR fixes a bug or regression and removed NemoClaw CLI labels Jun 3, 2026
…al-key NO_PROXY behavior

Two follow-ups from a deep review pass on NVIDIA#4331:

- host-proxy-env.ts:23 filtered on `value.trim() !== ""` but stored the
  untrimmed value. A `HTTP_PROXY="  http://x:8888  "` from a sloppy shell
  rc would forward with surrounding whitespace to the sandbox, which
  downstream consumers that don't re-trim would treat as malformed.
  Store the trimmed value.

- `withLocalNoProxy(proxyEnv)` mutates BOTH NO_PROXY and no_proxy
  regardless of which (if any) the user originally set. A user with only
  HTTP_PROXY set ends up with both cases synthesized in the sandbox.
  This is intentional — Python's requests and Node's fetch read
  different cases — but the behavior is non-obvious and easy to drop on
  a future cleanup of withLocalNoProxy. Add a pinning test so the dual-
  key synthesis is documented and locked.

Tests: 4/4 focused tests pass.

Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>

@cjagwani cjagwani left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving. Pushed one follow-up commit (7f27cd2) addressing two findings from a deep-review pass:

  1. Trim mismatchhost-proxy-env.ts:23 filtered on .trim() but stored the untrimmed value. A HTTP_PROXY=" http://x:8888 " would forward with surrounding whitespace. Now stores the trimmed value.
  2. Dual-key NO_PROXY synthesiswithLocalNoProxy(proxyEnv) mutates both NO_PROXY and no_proxy regardless of which the user originally set, so a user with only HTTP_PROXY ends up with both cases synthesized in the sandbox. This is intentional (Python and Node read different cases) but non-obvious. Added a pinning test so the dual-key synthesis is documented and locked against a future withLocalNoProxy refactor silently dropping one case.

@cjagwani cjagwani requested a review from cv June 3, 2026 21:01
@cv cv merged commit 72bdb2d into NVIDIA:main Jun 3, 2026
18 checks passed
cv added a commit that referenced this pull request Jun 7, 2026
## Summary

Follow-up to PR #4331 (`fix(onboard): forward host proxy env into
sandbox`). #4331 started forwarding the host `HTTP_PROXY` /
`HTTPS_PROXY` / `NO_PROXY` into `openshell sandbox create -- env ...` so
OpenShell-internal traffic could traverse the host proxy when one is
configured. The forwarded `NO_PROXY` seed list did not yet include the
OpenShell-managed inference hostname (`inference.local`) or the rootless
container-host alias (`host.containers.internal`). When a host
`HTTP_PROXY` is active on macOS + Colima, OpenShell's L7 proxy chains
`inference.local` through the host proxy — which cannot reach an
OpenShell-internal hostname — and streaming chat completions stall until
the 120 s idle timeout fires (#4846).

This PR seeds `inference.local` and `host.containers.internal` into the
`withLocalNoProxy()` augmentation so the regression introduced by
#4331's host-proxy forwarding stops short of the managed inference
hostname.

## Related Issue
Fixes #4846 (regression source: #4331).

## Changes

- `src/lib/subprocess-env.ts` and `nemoclaw/src/lib/subprocess-env.ts`
(mirrored): append `inference.local` and `host.containers.internal` to
the seeded `NO_PROXY` host list in `withLocalNoProxy()`; JSDoc documents
the boundary (host-side subprocesses + `openshell sandbox create -- env
...`) and the removal condition.
- `src/lib/onboard/http-proxy-preflight.ts`: warning copy now names the
managed inference hostname and includes it in the suggested `export
NO_PROXY=` line for tools running outside the sandbox. Suppression now
also requires `inference.local` so users with the previous loopback-only
guidance still see the new export advice.
- `docs/reference/troubleshooting.mdx`: document the full set of host
names NemoClaw adds to `NO_PROXY` when a host HTTP proxy is detected.
- Regression tests in `src/lib/subprocess-env.test.ts` and
`src/lib/onboard/http-proxy-preflight.test.ts`, plus
`test/host-proxy-inference-local-e2e.test.ts` (curl-driven E2E proving
`inference.local` reaches a local listener directly when `HTTP_PROXY` is
set). `subprocess-env.test.ts` also adds negative tests proving
arbitrary `*.local` / `.local` hostnames are not added to the bypass and
that a caller-provided `.local` entry does not expand the bypass
surface. CLI / plugin sync test in `test/credential-exposure.test.ts`
updated to match the new host list.

## Scope and boundaries

- **`*.local` suffix.** Deliberately narrow: only exact
`inference.local` is seeded. The reported failure path is the single
OpenShell-managed inference hostname; widening to any `*.local` would
change the bypass surface beyond the reported repro without evidence of
other affected hostnames. A negative test (`subprocess-env.test.ts`)
pins this behaviour.
- **Sandbox-runtime `NO_PROXY` is unchanged.**
`scripts/nemoclaw-start.sh` continues to set
`NO_PROXY=localhost,127.0.0.1,::1,${PROXY_HOST}` inside the sandbox and
intentionally **does not** include `inference.local` there — OpenShell's
L7 proxy resolves that hostname internally, and bypassing it would force
a direct DNS lookup that does not resolve from inside the container.
This PR does not touch that runtime layer.
- **Fix surface is host-side env propagation.** `withLocalNoProxy()`
runs through `appendHostProxyEnvArgs()` into `openshell sandbox create
-- env ...`. The `NO_PROXY` entry is consumed by OpenShell at
sandbox-create time when it decides whether to chain its L7 proxy
through the host `HTTP_PROXY` for a given hostname. With
`inference.local` in `NO_PROXY` at sandbox-create time, OpenShell stops
tunneling that hostname through the host proxy (the reported `Proxy
connection error: Broken pipe (os error 32)` path).
- **E2E coverage.** `test/host-proxy-inference-local-e2e.test.ts`
exercises the env-construction primitive end-to-end via a real `curl`
spawn driven by `buildSubprocessEnv()` against a local listener bound to
`inference.local`. The full macOS + Colima sandbox path requires a macOS
runner and is left to scenario E2E (`ubuntu-repo-cloud-openclaw` covers
the closest cloud-onboard cross-section).

## Type of Change

- [ ] Code change (feature, bug fix, or refactor)
- [x] Code change with doc updates
- [ ] Doc only (prose changes, no code sample modifications)
- [ ] Doc only (includes code sample changes)

## Verification
- [x] `npx prek run --all-files` passes
- [x] `npm test` passes
- [x] Tests added or updated for new or changed behavior
- [x] No secrets, API keys, or credentials committed
- [x] Docs updated for user-facing behavior changes
- [ ] `npm run docs` builds without warnings (doc changes only)
- [ ] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Proxy bypass now also excludes additional local hostnames
(inference.local, host.containers.internal, ::1, 0.0.0.0), preventing
local services and managed inference from being routed through user
proxies; preflight warning now requires inference.local to be present to
suppress warnings.

* **Documentation**
* Updated proxy-preflight guidance and warning text to show suggested
NO_PROXY/no_proxy exports including managed inference hosts and extra
local aliases.

* **Tests**
* Added/updated unit and e2e tests validating the expanded
NO_PROXY/no_proxy behavior and direct reachability of inference.local.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>

---------

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
Co-authored-by: Carlos Villela <cvillela@nvidia.com>
@coderabbitai coderabbitai Bot mentioned this pull request Jun 7, 2026
12 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: cli Command line interface, flags, terminal UX, or output area: sandbox OpenShell sandbox lifecycle, runtime, config, or recovery bug-fix PR fixes a bug or regression v0.0.58 Release target

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Ubuntu 24.04][Onboard] nemoclaw v0.0.52 onboard ignores HTTP_PROXY/HTTPS_PROXY env vars — corp proxy silently bypassed

4 participants