Repository navigation
Description
Description
The DCode connect route probe executes a sandbox-user-created login profile before the managed probe command. The probe still fails closed, but the profile can emit output and create persistent side effects even though the managed boundary is intended to bypass user startup files.
Platform scope: Reproduced on Ubuntu 24.04 only; other platforms not tested
Regression: Unknown — earlier versions not tested
Environment
Device: Ubuntu 24.04 test server
OS: Ubuntu 24.04.4 LTS (Linux 6.8.0-124-generic)
Architecture: x86_64
Node.js: v22.23.1
npm: 10.9.8
Docker: Docker Engine 29.5.3
OpenShell CLI: openshell 0.0.85
NemoClaw: nemoclaw v0.0.104
OpenClaw: N/A (LangChain Deep Agents Code sandbox)
Steps to Reproduce
- Onboard a fresh DCode sandbox named
dcode-profile-probeand confirm thatnemoclaw dcode-profile-probe connect --probe-onlysucceeds. - As the sandbox user, create
/sandbox/.bash_profilewith a command that prints a recognizable marker, creates/sandbox/profile-ran, and exits successfully. - As the sandbox user, create
/sandbox/.curlrcwith a trace-output directive. - From the host, run
nemoclaw dcode-profile-probe connect --probe-onlyand capture the exit code and output. - Inspect the sandbox through the container administration boundary and check whether
/sandbox/profile-ranexists.
Expected Result
The managed DCode route probe uses a neutral HOME, clears shell startup environment variables, and executes without a login shell. Sandbox-user .bash_profile, .bashrc, and .curlrc files are not evaluated, no marker or curl trace file is created, and the probe result reflects only the real inference route.
Actual Result
The command exits non-zero and reports:
Probe failed: LangChain Deep Agents Code could not reach the managed inference.local route in 'dcode-profile-probe'.
Container inspection after the command confirms that the login-profile marker was created. A direct managed-exec cleanup attempt also emits startup-profile output before the requested command, confirming that the sandbox-user login profile ran first.
Logs
Baseline probe: exit 0
Probe after planting the login profile: exit 1
Probe output: Probe failed: LangChain Deep Agents Code could not reach the managed inference.local route in 'dcode-profile-probe'.
Login-profile marker after probe: present
Curl trace marker after probe: absent
Activity
Dongni-Yang commentedon Aug 10, 2026
The root cause of the login-profile execution is upstream in OpenShell, not in NemoClaw. I filed it as NVIDIA/OpenShell#2668.
openshell sandbox execnever delivers argv to the sandbox as argv. It flattens the command vector and every--envpair into a single shell string (crates/openshell-server/src/grpc/sandbox.rs:1776-1798), relays that string over the supervisor SSH transport (stream_exec_over_relay, same file,1800-1806), and the supervisor spawns it with a login shell (crates/openshell-supervisor-process/src/ssh.rs:992-996):The PTY path does the same at
833-835. Both are unconditional, so no flag or environment value changes them.That explains the exact wording in this report — the profile runs before the managed probe command — and it means two mitigations already in the tree cannot work:
dcode-managed-execlauncher cannot prevent it. The profile is sourced before the launcher's first instruction runs.--env BASH_ENV=and--env ENV=cannot prevent it. They become command-prefix assignments inside the string handed tobash -lc, so they apply only after the login shell has already sourced the profile.Two observations on the existing behavior, both of which look correct as designed:
#6192deliberately rejects contaminated probe evidence rather than parsing past it.#6191pins that argv.PR #8670 removes the one login shell I could attribute to NemoClaw in this flow:
runAgentSmokeCommandswrapped Deep Agents Code smoke commands insh -lc, nesting a second profile sourcing inside the managed boundary. It is reachable because a probe result with any stderr resolves tonullrather thanfalse(src/lib/actions/sandbox/inference-route-health.ts:53-62) and only an explicitfalseshort-circuits (src/lib/actions/sandbox/terminal-connect-probe.ts:40), so an indeterminate route falls through to smoke.That PR is
Refs, notCloses, on purpose. It is defense-in-depth. A planted/sandbox/.bash_profilewill still run and still leave its marker until the upstream change lands, so this issue's "executes without a login shell" acceptance criterion is not reachable from NemoClaw today.Caveat on my evidence: I verified the upstream behavior by reading OpenShell
mainat5e2f0d1, not by running it. This host cannot start a gateway, so I did not reproduce the sandbox-side execution directly.@mercl-lau one detail would help confirm the chain end to end: in your run, which command emitted the startup-profile output — the route probe, the smoke command, or the direct
dcode-managed-execcleanup?Signed-off-by: Dongni Yang [email protected]
test(sandbox): read the smoke command from the end of the stub argv
fix(agent): narrow smoke hardening scope
fix(sandbox): protect DCode managed login probes (#8670)
fix(connect): verify DeepAgents inference before session (#11546)