NVIDIA / NVIDIA/NemoClaw

NEMOCLAW_OLLAMA_PROXY_SKIP_BIND_PROBE has no effect when set on nemoclaw onboard, because the proxy spawn env allowlist drops it

Open
#10,240 0 comments 0 reactions 1 assignee Claimed by @jason-ma-nv View on GitHub
area: local-models area: onboarding area: sandbox platform: ubuntu
Dominant language
TypeScript
Stars
22.5k
Forks
3.1k
Avg merge
1d 1h
Merged PRs (30d)
715

Description

### Summary

The Ollama auth proxy refuses to start when the backend is reachable on a non-loopback interface, and **its own error message tells the operator to set `NEMOCLAW_OLLAMA_PROXY_SKIP_BIND_PROBE=1` to override**.

Setting that variable on the `nemoclaw onboard` command has **no effect**: onboarding still fails closed with the same non-loopback error, and the documented `SECURITY PROBE SKIPPED` audit warning is never emitted.

The override is only read inside the **spawned proxy process**, but the proxy is spawned with an explicit allowlisted environment that does not include this variable — so the value never reaches the code that checks it. The operator has no working recourse through the interface the product itself points them at.

### Environment

| | |
|---|---|
| OS | Ubuntu 24.04.4 LTS, x86_64 |
| GPU | NVIDIA A100-SXM4-40GB |
| NemoClaw | v0.0.114 |
| OpenShell | 0.0.106 |
| Docker | 29.7.2 |
| Ollama | 0.32.13 |

Platform scope: reproduced on Ubuntu 24.04 x86_64 only; the spawn/allowlist code is not platform-specific.
Regression: unknown — earlier versions not tested.

### Steps to reproduce

1. Bind Ollama to a non-loopback address so the probe refuses:
```bash
sudo systemctl stop ollama
OLLAMA_HOST=0.0.0.0:11434 ollama serve &
ss -tln | grep 11434 # confirm wildcard bind
```
2. Confirm the refusal and read the product's remediation text:
```bash
NEMOCLAW_PROVIDER=ollama NEMOCLAW_YES=1 nemoclaw onboard --name probe-test2 --non-interactive --fresh
```
3. Follow that remediation **exactly** — set the documented override on the onboard command:
```bash
NEMOCLAW_OLLAMA_PROXY_SKIP_BIND_PROBE=1 NEMOCLAW_PROVIDER=ollama NEMOCLAW_YES=1 \
nemoclaw onboard --name probe-test3 --non-interactive --fresh
```
4. Capture the exit code and search stderr for `SECURITY PROBE SKIPPED`.
5. Restore Ollama to loopback.

### Expected

Step 3 proceeds past the bind probe and onboarding completes (exit 0), with the `SECURITY PROBE SKIPPED` audit warning naming the knob that disabled enforcement.

### Actual

Step 3 fails **exactly like step 2** — exit code 1:

```
Error: Ollama auth proxy refused to start.
Ollama is reachable on a non-loopback interface on the host (...:11434), which would bypass the proxy's
token check entirely.
Remediation: bind Ollama to loopback only. ...
```

and **zero** occurrences of `SECURITY PROBE SKIPPED`. The override the product recommends has no observable effect.

### Root cause (from the shipped code)

The override is read only inside the proxy process — `scripts/ollama-auth-proxy.mts`, `assertBackendBoundToLoopback()`:

```js
if (process.env.NEMOCLAW_OLLAMA_PROXY_SKIP_BIND_PROBE === "1") {
console.warn("... SECURITY PROBE SKIPPED ...");
return;
}
```

But the proxy is spawned with an explicit env object that omits it — `dist/lib/inference/ollama/proxy.js`, `spawnOllamaAuthProxy()`:

```js
env: {
OLLAMA_PROXY_TOKEN, OLLAMA_PROXY_PORT, OLLAMA_BACKEND_PORT,
[PROXY_STATUS_ENV], ...(url ? { OLLAMA_BACKEND_URL: url } : {}),
},
buildEnv: buildSubprocessEnv
```

And the inherited-environment path is an allowlist that does not cover it — `dist/lib/subprocess-env.js`:

```
SUBPROCESS_ENV_ALLOWED_NAMES = SYSTEM + TEMP + LOCALE + PROXY + TLS + TOOLCHAIN (no NEMOCLAW_* entries)
SUBPROCESS_ENV_ALLOWED_PREFIXES = ["LC_", "XDG_", "OPENSHELL_", "GRPC_"] (no "NEMOCLAW_")
grep -c SKIP_BIND_PROBE dist/lib/subprocess-env.js -> 0
```

### Controls

- The variable name is correct — it appears in the shipped source **and** in the product's own error text.
- The same onboarding succeeds when Ollama is bound to loopback, so the rest of the flow is healthy.

### Related, deliberately checked — not a duplicate

**#9846** (open) asks for a durable audit record because the proxy's `console.warn` is discarded by `stdio: "ignore"`. That assumes the override *takes effect* and only its trace is lost. This report is that the override **never reaches the proxy at all** when set the way the product's error message instructs — so it never takes effect and no warning is produced in the first place.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.