NEMOCLAW_OLLAMA_PROXY_SKIP_BIND_PROBE has no effect when set on nemoclaw onboard, because the proxy spawn env allowlist drops it
- 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
Assessment
This issue has not been assessed yet.