fix(dashboard): honor NEMOCLAW_DASHBOARD_BIND=0.0.0.0 for remote-deployed hosts (#3259)#3499
Conversation
…oyed hosts (#3259) Adds an operator-controlled opt-in env var (`NEMOCLAW_DASHBOARD_BIND`) that makes the dashboard port forward bind on all interfaces (`0.0.0.0:<port>`) instead of staying localhost-only. Mirrors the OpenShell gateway 8080 = 0.0.0.0 binding already in place for remote sandboxes. Wired through the pure-function `buildChain` (dashboard/contract.ts): the new `bindOverride` field on `PlatformHints` participates in the existing forwardTarget / bindAddress / shouldDisableDeviceAuth decision so the contract stays the single source of truth. Only "0.0.0.0" enables the remote bind — anything else (empty, "127.0.0.1", arbitrary IPs) is silently ignored to keep the surface narrow. The I/O boundary read lives in `onboard/dashboard-access.ts:readBindOverride`, which falls back to `process.env.NEMOCLAW_DASHBOARD_BIND` when the caller does not pass an explicit `options.env`. All existing `buildDashboardChain` callers (onboard, status, doctor) automatically benefit. When remote bind is opted in, `shouldDisableDeviceAuth` flips true so the dashboard auth flow accepts non-loopback origins (mirrors the existing WSL / non-loopback chatUiUrl behavior). Validates the regression test merged in #3410 (`test/e2e/test-dashboard-remote-bind.sh`), which was deliberately red-on-main until this fix lands. Closes #3259. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Enterprise Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAdds an operator opt-in via ChangesDashboard Remote Bind Opt-In
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Warning Review ran into problems🔥 ProblemsGit: Failed to clone repository. Please run the Comment |
E2E Advisor RecommendationRequired E2E: Dispatch hint: Full advisor summaryE2E Recommendation AdvisorBase: Required E2E
Optional E2E
New E2E recommendations
Dispatch hint
|
…ge on #3499) CodeRabbit's docstring-coverage pre-merge check flagged the buildDashboardChain export (modified to read NEMOCLAW_DASHBOARD_BIND) as undocumented. Adds a JSDoc explaining its role as the I/O-boundary wrapper around the pure buildChain, so the contract stays a pure function and tests can drive buildChain directly without env mocks. Surgical change — only the function I touched in this PR gets the new JSDoc. Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
Summary
NEMOCLAW_DASHBOARD_BIND. When set to0.0.0.0, the dashboard port forward binds on all interfaces (0.0.0.0:<port>) instead of staying localhost-only.NEMOCLAW_GATEWAY_BIND_ADDRESSpattern already in place for the OpenShell gateway on port 8080.test/e2e/test-dashboard-remote-bind.sh).Closes #3259.
Acceptance criteria mapping
src/lib/onboard/dashboard-access.ts:readBindOverridereadsNEMOCLAW_DASHBOARD_BIND; threads intobuildChainvia the newPlatformHints.bindOverridefielddashboard/contract.ts:buildChain—shouldDisableDeviceAuthflipstruewhenbindOverride === "0.0.0.0"0.0.0.0:<port>forward-target shape; reusesforwardTarget.includes(":")⇒bindAddress = "0.0.0.0"ruletest/e2e/test-dashboard-remote-bind.shflips RED→GREENNEMOCLAW_DASHBOARD_BIND=0.0.0.0and assertsopenshell forward listshows0.0.0.0:18789— fix produces exactly that0.0.0.0enables remote bind (don't allow arbitrary IPs)contract.test.tsconfirms10.0.0.5falls through to default loopbackBehavior matrix
NEMOCLAW_DASHBOARD_BINDchatUiUrlforwardTargetbindAddressshouldDisableDeviceAuth\"18789\"127.0.0.1false\"0.0.0.0:18789\"0.0.0.0true\"0.0.0.0:18789\"0.0.0.0true0.0.0.0\"0.0.0.0:18789\"0.0.0.0true127.0.0.1\"18789\"127.0.0.1false10.0.0.5(arbitrary)\"18789\"127.0.0.1falseTest plan
npm run typecheck:clicleannpx vitest run --project cli src/lib/dashboard/contract.test.ts— 20 tests pass (4 new for [macOS][Brev][CLI&UX] Dashboard port 18789 hard-bound to 127.0.0.1 — no flag/env to bind 0.0.0.0 for remote-SSH-deployed hosts #3259)npx vitest run --project cli src/lib/onboard/— 274 tests pass (no regression in adjacent suites)test-dashboard-remote-bindregression workflow (manual dispatch fromregression-e2e.yaml) should now pass — please trigger after CI greenManual verification on a remote SSH host:
```bash
NEMOCLAW_DASHBOARD_BIND=0.0.0.0 nemoclaw connect
openshell forward list # should show 0.0.0.0:18789 for
```
Notes for reviewers
buildChainstays the single source of truth — the env var is read once at the I/O boundary (dashboard-access.ts) and threaded as a hint. Doctor / status / onboard call sites pick it up automatically throughbuildDashboardChain.\"0.0.0.0\"is honored. Anything else (empty, `127.0.0.1`, arbitrary IPs) is silently ignored — keeps the surface narrow and matches the `NEMOCLAW_GATEWAY_BIND_ADDRESS` pattern.🤖 Generated with Claude Code
Summary by CodeRabbit
Documentation
New Features
Tests