fix(tunnel): register tunnel origin in gateway allowedOrigins on start - #6235
Conversation
`nemoclaw tunnel start` printed the cloudflared public URL but never added its origin to `gateway.controlUi.allowedOrigins`, so every Web UI WebSocket arriving through the tunnel was rejected with "origin not allowed" and the Web UI was unusable out of the box. After the tunnel URL is captured, register its exact origin in the in-sandbox OpenClaw config: prune stale *.trycloudflare.com origins, preserve all other origins, recompute the config hash, and restart the gateway so the change takes effect. Registration is best-effort (a failure warns and never breaks tunnel start), idempotent (no write or gateway restart when the origin list is unchanged), and skipped for non-OpenClaw agents. Fixes NVIDIA#6212 Signed-off-by: Tony Luo <xialuo@nvidia.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually. Contributors can view more details about this message here. |
|
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 tunnel-origin computation and best-effort registration into gateway allowedOrigins after tunnel URL discovery, with OpenClaw-only gating, config reloads when the allowlist changes, tests, and CLI documentation. ChangesTunnel origin registration
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
The codebase-growth-guardrails check requires changed test files not to add if statements. Replace manual env save/restore in the NVIDIA#6212 registration suite with vi.stubEnv/vi.unstubAllEnvs and make the cloudflared pid cleanup branch-free, restoring the file to its baseline if-statement count. Signed-off-by: Tony Luo <xialuo@nvidia.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
🧹 Nitpick comments (2)
src/lib/tunnel/allowed-origins.ts (1)
161-168: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low valueMinor contract gap:
resolveDepsruns outside the try/catch.The doc comment states any failure is swallowed so a working tunnel start is never turned into a hard error, but
resolveDeps(Line 164) executes before thetry(Line 168). If it throws (e.g., a module resolution failure via therequireabove), the error escapes this function despite the "best-effort" contract. Moving it inside thetrymakes the contract hold locally without relying on the caller's wrapper.🤖 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/tunnel/allowed-origins.ts` around lines 161 - 168, The best-effort contract in the tunnel origin handling is broken because `resolveDeps` is called before the `try` in `allowed-origins.ts`, so a resolution failure can still escape and fail startup. Move the `resolveDeps(deps)` call, along with the `info` and `warn` extraction, inside the existing `try` block in the `tunnelUrlToOrigin`/allowed-origins flow so any module resolution error is swallowed locally as intended.src/lib/tunnel/services.ts (1)
679-696: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winExtract the sandbox-name selection into a helper
resolveDefaultSandboxNamealready centralizes the env precedence forstart/stop, but this tunnel-origin path still repeats the same safe-name filtering inline. A small helper for the tunnel-origin sandbox name would keep the precedence and validation rules in one place without dragging in the registry fallback. The outertry/catchonly adds protection for dependency-loading failures beforeregisterTunnelOrigin’s own best-effort handling.🤖 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/tunnel/services.ts` around lines 679 - 696, The tunnel-origin path in services.ts is duplicating sandbox-name selection and validation inline instead of using a helper. Extract that logic into a small helper near resolveDefaultSandboxName that applies the same env precedence and SAFE_NAME_RE/“..” checks for tunnel-origin use, but does not include the registry fallback. Then update the tunnelUrl block to call the helper and keep the outer try/catch around registerTunnelOrigin for dependency-loading failures only.
🤖 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/tunnel/allowed-origins.ts`:
- Around line 161-168: The best-effort contract in the tunnel origin handling is
broken because `resolveDeps` is called before the `try` in `allowed-origins.ts`,
so a resolution failure can still escape and fail startup. Move the
`resolveDeps(deps)` call, along with the `info` and `warn` extraction, inside
the existing `try` block in the `tunnelUrlToOrigin`/allowed-origins flow so any
module resolution error is swallowed locally as intended.
In `@src/lib/tunnel/services.ts`:
- Around line 679-696: The tunnel-origin path in services.ts is duplicating
sandbox-name selection and validation inline instead of using a helper. Extract
that logic into a small helper near resolveDefaultSandboxName that applies the
same env precedence and SAFE_NAME_RE/“..” checks for tunnel-origin use, but does
not include the registry fallback. Then update the tunnelUrl block to call the
helper and keep the outer try/catch around registerTunnelOrigin for
dependency-loading failures only.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 14175b3f-83fe-47d7-9228-0b7da3c158b3
📒 Files selected for processing (5)
docs/reference/commands.mdxsrc/lib/tunnel/allowed-origins.test.tssrc/lib/tunnel/allowed-origins.tssrc/lib/tunnel/services.test.tssrc/lib/tunnel/services.ts
Move resolveDeps inside registerTunnelOrigin's try block so a dependency resolution failure is swallowed by the best-effort contract instead of relying on the caller's guard, and extract the sandbox-name selection in startAll into resolveTunnelOriginSandboxName so the env precedence and safe-name rules live in one place. Signed-off-by: Tony Luo <xialuo@nvidia.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Tony Luo <xialuo@nvidia.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
<!-- markdownlint-disable MD041 --> ## Summary This PR prepares the user-facing documentation for v0.0.74 before the release plan is frozen. It expands the release notes across the 56-commit train and closes durable documentation gaps found during the pre-tag commit scan. ## Changes - Expand the `v0.0.74` release notes to cover OpenShell 0.0.72, managed MCP, progressive tool disclosure, LangChain Deep Agents Code, onboarding, local inference, messaging, recovery, and contributor workflows. - Correct the `destroy` contract for retained per-name volumes, gateway-unreachable `--force` cleanup, managed MCP ownership, and same-name recovery. - Document separate remediation for an unreachable container DNS resolver versus one that answers with `NXDOMAIN` or `REFUSED`. - Document the Windows on Arm N1X automatic Ollama safeguard and its remaining large-model limitations. - State that messaging conflicts abort rebuild before backup or deletion, leaving the original sandbox intact. - Link the agent-runnable value benchmark from the contributor task index. - Synchronize generated agent command variants. - Validate with `npm run docs:sync-agent-variants` and `npm run docs`; Fern completed with 0 errors and 2 existing warnings. - Source summary: - [#6020](#6020) and [#5876](#5876) -> `docs/about/release-notes.mdx`: Consolidate the OpenShell 0.0.72 policy boundary and managed MCP lifecycle. - [#6251](#6251) and [#5989](#5989) -> `docs/about/release-notes.mdx`: Summarize progressive tool disclosure and sandbox-first inference controls. - [#6232](#6232), [#6082](#6082), [#6219](#6219), [#6214](#6214), [#6215](#6215), [#6230](#6230), and [#6260](#6260) -> `docs/about/release-notes.mdx`: Summarize the experimental LangChain Deep Agents Code status, secret, version, rebuild, snapshot, and MCP boundaries. - [#6166](#6166), [#6254](#6254), [#6265](#6265), [#6164](#6164), and [#6017](#6017) -> `docs/about/release-notes.mdx`: Summarize BuildKit prebuild, validated image reuse, bounded readiness, and preflight improvements. - [#6150](#6150) -> `docs/about/release-notes.mdx` and `docs/reference/troubleshooting.mdx`: Separate unreachable-resolver remediation from reachable-but-rejected DNS responses. - [#6234](#6234) -> `docs/about/release-notes.mdx`, `docs/inference/use-local-inference.mdx`, and `docs/get-started/windows-preparation.mdx`: Document N1X automatic 9B selection and the remaining explicit-large-model boundary. - [#6129](#6129), [#5987](#5987), [#5955](#5955), and [#6220](#6220) -> `docs/about/release-notes.mdx`, `docs/manage-sandboxes/messaging-channels.mdx`, `docs/reference/commands.mdx`, and `docs/reference/commands-nemohermes.mdx`: Document messaging policy persistence, status, and the pre-destructive conflict check. - [#5963](#5963), [#6050](#6050), [#6094](#6094), [#6238](#6238), [#5988](#5988), [#6235](#6235), [#6181](#6181), and [#5986](#5986) -> `docs/about/release-notes.mdx`, `docs/reference/commands.mdx`, and `docs/reference/commands-nemohermes.mdx`: Summarize day-two recovery and clarify retained-volume and local-only destroy semantics. - [#6200](#6200), [#6248](#6248), [#6168](#6168), [#6270](#6270), and [#5649](#5649) -> `docs/about/release-notes.mdx` and `CONTRIBUTING.md`: Summarize contributor setup and verification improvements and expose the advisory value benchmark. ## Type of Change - [ ] Code change (feature, bug fix, or refactor) - [ ] Code change with doc updates - [ ] Doc only (prose changes, no code sample modifications) - [x] Doc only (includes code sample changes) ## Quality Gates <!-- Check exactly one tests line and one docs line. Check other lines when applicable. Add every requested justification or approval reference. --> - [ ] Tests added or updated for changed behavior - [ ] Existing tests cover changed behavior — justification: - [x] Tests not applicable — justification: documentation-only release preparation; generated-variant synchronization and the Fern docs build validate the changed pages and routes. - [x] Docs updated for user-facing behavior changes - [ ] Docs not applicable — justification: - [ ] Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging) - [ ] Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: - [ ] Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue: ## Verification <!-- Check each applicable item only when supported by the requested evidence. Run targeted tests once per relevant change set and rerun after later edits or hook autofixes that can affect the tested behavior. Do not rerun hook-covered checks. --> - [x] PR description includes the DCO sign-off declaration and every commit appears as `Verified` in GitHub - [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or `npm run check:diff` passed when hooks were skipped or unavailable - [x] Targeted behavior tests pass for the current change set, or tests are marked not applicable above — command/result or justification: tests are not applicable to this documentation-only change; `npm run docs` validates the source and generated routes. - [ ] Applicable broad gate passed — `npm test` for broad runtime/test-harness changes; `npm run check` for repo-wide validation/coverage changes — command/result: - [x] Quality Gates section completed with required justifications or waivers - [x] No secrets, API keys, or credentials committed - [ ] `npm run docs` builds without warnings (doc changes only) - [x] 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) --- <!-- DCO sign-off is required in this PR description, and every commit must appear as Verified in GitHub. Run: git config user.name && git config user.email --> Signed-off-by: Aaron Erickson <aerickson@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Expanded setup guidance for Windows on Arm devices with safer default local model selection. * Clarified local inference and sandbox messaging behavior, including conflict checks before rebuilds and safer recovery steps. * Updated destroy/rebuild/reference docs with more detailed warnings, failure handling, and volume-retention guidance. * Improved troubleshooting instructions for Docker DNS issues with clearer paths for unreachable vs. blocked resolvers. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
NVIDIA#6235) ## Summary `nemoclaw tunnel start` starts cloudflared and prints the public `*.trycloudflare.com` URL, but never registers that origin in `gateway.controlUi.allowedOrigins`, so every Web UI WebSocket arriving through the tunnel is rejected with "origin not allowed". This PR auto-registers the tunnel's exact origin in the in-sandbox gateway config and restarts the gateway so the Web UI works through the tunnel with no manual configuration. ## Related Issue Fixes NVIDIA#6212 ## Changes - New `src/lib/tunnel/allowed-origins.ts`: - `tunnelUrlToOrigin` / `isTryCloudflareOrigin` / `computeTunnelAllowedOrigins` — pure origin-list logic: converts the captured tunnel URL to an exact origin (never a wildcard), prunes stale `*.trycloudflare.com` origins so the list stays bounded across quick-tunnel restarts, and preserves all other origins (loopback, `NEMOCLAW_CORS_ORIGIN`, custom domains). - `registerTunnelOrigin` — reads the in-sandbox OpenClaw config via the existing `sandbox/config.ts` primitives (`readSandboxConfig`/`writeSandboxConfig`/`recomputeSandboxConfigHash`), applies the updated list, and restarts the gateway. Best-effort (a failure warns and never breaks `tunnel start`), idempotent (no write or restart when the list is unchanged), and skipped for non-OpenClaw agents. - `src/lib/tunnel/services.ts` — `startAll` calls `registerTunnelOrigin` after the tunnel URL is captured, guarded by the existing `SAFE_NAME_RE` sandbox-name validation, with a clear warning when no sandbox name is available. - Tests: 20 unit tests in `src/lib/tunnel/allowed-origins.test.ts` (origin conversion, prune/preserve, idempotency, agent gating, failure swallowing, sibling-key preservation) and 4 `startAll` integration tests in `src/lib/tunnel/services.test.ts` using the existing fake-cloudflared pattern. - Docs: `docs/reference/commands.mdx` — documents the automatic origin registration under `tunnel start` (OpenClaw-only block; agent variants verified in sync). Design notes: - Exact origin instead of a `*.trycloudflare.com` wildcard: a wildcard would accept any trycloudflare tenant's origin (CSWSH exposure); only the URL the user just created is registered. - Deviation from the internal design doc: the gateway reload uses the managed `restartSandboxGateway` (mutation-locked, health-probed, hash-verified) rather than a raw `kill -HUP 1` container reap — less disruptive and safer. - Issue NVIDIA#1422 was closed by the stale bot, not by a fix; the recovery infrastructure it references was never merged, so this is a first-time gap in the tunnel-start flow rather than a regression. ## Type of Change - [x] Code change with doc updates ## Quality Gates - [x] Tests added or updated for changed behavior - [x] Docs updated for user-facing behavior changes - [x] Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging) - [ ] Sensitive-path review completed or maintainer-approved waiver recorded — internal 9-category security review passed (injection, CORS/CSWSH widening, secrets, SSRF, path traversal, parsing, privilege escalation, DoS, supply chain); requesting maintainer review as the merge gate. ## Verification - [x] PR description includes the DCO sign-off declaration and every commit appears as `Verified` in GitHub - [ ] Git hooks passed during commit and push, or `npx prek run --from-ref main --to-ref HEAD` passes — pre-commit vitest hook hung under coverage (known flake); Biome check run manually on all changed TS files, typecheck:cli clean - [x] Targeted tests pass for changed behavior (`npx vitest run src/lib/tunnel/ test/cli/tunnel-command.test.ts` — 5 files, 88+ tests pass) - [x] Quality Gates section completed with required justifications or waivers - [x] No secrets, API keys, or credentials committed - [x] `npm run docs` builds without warnings (doc changes only) — 0 errors; 2 pre-existing environment warnings (Fern auth + theme contrast), none introduced by this change Remaining manual verification: end-to-end run on a root-mode sandbox (immutable/hashed config) to confirm the write + hash recompute + gateway restart sequence on real hardware — the reporter's DGX Station environment. All logic is unit/integration tested and reuses the shipped `config set` write path. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Signed-off-by: Tony Luo <xialuo@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Public tunnel startup now automatically registers the tunnel origin with the sandbox gateway when possible (OpenClaw-only). * Allowed origins updates now preserve existing non-trycloudflare entries while removing stale quick-tunnel origins. * **Bug Fixes** * Registration is skipped for unsafe/missing sandbox names and fails gracefully with warnings; tunnel startup output remains resilient. * **Documentation** * Updated tunnel command reference with clearer behavior around origin injection, pruning, and gateway restarts. * **Tests** * Added coverage for tunnel origin parsing, allowlist computation, and registration wiring. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Tony Luo <xialuo@nvidia.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
<!-- markdownlint-disable MD041 --> ## Summary This PR prepares the user-facing documentation for v0.0.74 before the release plan is frozen. It expands the release notes across the 56-commit train and closes durable documentation gaps found during the pre-tag commit scan. ## Changes - Expand the `v0.0.74` release notes to cover OpenShell 0.0.72, managed MCP, progressive tool disclosure, LangChain Deep Agents Code, onboarding, local inference, messaging, recovery, and contributor workflows. - Correct the `destroy` contract for retained per-name volumes, gateway-unreachable `--force` cleanup, managed MCP ownership, and same-name recovery. - Document separate remediation for an unreachable container DNS resolver versus one that answers with `NXDOMAIN` or `REFUSED`. - Document the Windows on Arm N1X automatic Ollama safeguard and its remaining large-model limitations. - State that messaging conflicts abort rebuild before backup or deletion, leaving the original sandbox intact. - Link the agent-runnable value benchmark from the contributor task index. - Synchronize generated agent command variants. - Validate with `npm run docs:sync-agent-variants` and `npm run docs`; Fern completed with 0 errors and 2 existing warnings. - Source summary: - [NVIDIA#6020](NVIDIA#6020) and [NVIDIA#5876](NVIDIA#5876) -> `docs/about/release-notes.mdx`: Consolidate the OpenShell 0.0.72 policy boundary and managed MCP lifecycle. - [NVIDIA#6251](NVIDIA#6251) and [NVIDIA#5989](NVIDIA#5989) -> `docs/about/release-notes.mdx`: Summarize progressive tool disclosure and sandbox-first inference controls. - [NVIDIA#6232](NVIDIA#6232), [NVIDIA#6082](NVIDIA#6082), [NVIDIA#6219](NVIDIA#6219), [NVIDIA#6214](NVIDIA#6214), [NVIDIA#6215](NVIDIA#6215), [NVIDIA#6230](NVIDIA#6230), and [NVIDIA#6260](NVIDIA#6260) -> `docs/about/release-notes.mdx`: Summarize the experimental LangChain Deep Agents Code status, secret, version, rebuild, snapshot, and MCP boundaries. - [NVIDIA#6166](NVIDIA#6166), [NVIDIA#6254](NVIDIA#6254), [NVIDIA#6265](NVIDIA#6265), [NVIDIA#6164](NVIDIA#6164), and [NVIDIA#6017](NVIDIA#6017) -> `docs/about/release-notes.mdx`: Summarize BuildKit prebuild, validated image reuse, bounded readiness, and preflight improvements. - [NVIDIA#6150](NVIDIA#6150) -> `docs/about/release-notes.mdx` and `docs/reference/troubleshooting.mdx`: Separate unreachable-resolver remediation from reachable-but-rejected DNS responses. - [NVIDIA#6234](NVIDIA#6234) -> `docs/about/release-notes.mdx`, `docs/inference/use-local-inference.mdx`, and `docs/get-started/windows-preparation.mdx`: Document N1X automatic 9B selection and the remaining explicit-large-model boundary. - [NVIDIA#6129](NVIDIA#6129), [NVIDIA#5987](NVIDIA#5987), [NVIDIA#5955](NVIDIA#5955), and [NVIDIA#6220](NVIDIA#6220) -> `docs/about/release-notes.mdx`, `docs/manage-sandboxes/messaging-channels.mdx`, `docs/reference/commands.mdx`, and `docs/reference/commands-nemohermes.mdx`: Document messaging policy persistence, status, and the pre-destructive conflict check. - [NVIDIA#5963](NVIDIA#5963), [NVIDIA#6050](NVIDIA#6050), [NVIDIA#6094](NVIDIA#6094), [NVIDIA#6238](NVIDIA#6238), [NVIDIA#5988](NVIDIA#5988), [NVIDIA#6235](NVIDIA#6235), [NVIDIA#6181](NVIDIA#6181), and [NVIDIA#5986](NVIDIA#5986) -> `docs/about/release-notes.mdx`, `docs/reference/commands.mdx`, and `docs/reference/commands-nemohermes.mdx`: Summarize day-two recovery and clarify retained-volume and local-only destroy semantics. - [NVIDIA#6200](NVIDIA#6200), [NVIDIA#6248](NVIDIA#6248), [NVIDIA#6168](NVIDIA#6168), [NVIDIA#6270](NVIDIA#6270), and [NVIDIA#5649](NVIDIA#5649) -> `docs/about/release-notes.mdx` and `CONTRIBUTING.md`: Summarize contributor setup and verification improvements and expose the advisory value benchmark. ## Type of Change - [ ] Code change (feature, bug fix, or refactor) - [ ] Code change with doc updates - [ ] Doc only (prose changes, no code sample modifications) - [x] Doc only (includes code sample changes) ## Quality Gates <!-- Check exactly one tests line and one docs line. Check other lines when applicable. Add every requested justification or approval reference. --> - [ ] Tests added or updated for changed behavior - [ ] Existing tests cover changed behavior — justification: - [x] Tests not applicable — justification: documentation-only release preparation; generated-variant synchronization and the Fern docs build validate the changed pages and routes. - [x] Docs updated for user-facing behavior changes - [ ] Docs not applicable — justification: - [ ] Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging) - [ ] Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: - [ ] Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue: ## Verification <!-- Check each applicable item only when supported by the requested evidence. Run targeted tests once per relevant change set and rerun after later edits or hook autofixes that can affect the tested behavior. Do not rerun hook-covered checks. --> - [x] PR description includes the DCO sign-off declaration and every commit appears as `Verified` in GitHub - [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or `npm run check:diff` passed when hooks were skipped or unavailable - [x] Targeted behavior tests pass for the current change set, or tests are marked not applicable above — command/result or justification: tests are not applicable to this documentation-only change; `npm run docs` validates the source and generated routes. - [ ] Applicable broad gate passed — `npm test` for broad runtime/test-harness changes; `npm run check` for repo-wide validation/coverage changes — command/result: - [x] Quality Gates section completed with required justifications or waivers - [x] No secrets, API keys, or credentials committed - [ ] `npm run docs` builds without warnings (doc changes only) - [x] 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) --- <!-- DCO sign-off is required in this PR description, and every commit must appear as Verified in GitHub. Run: git config user.name && git config user.email --> Signed-off-by: Aaron Erickson <aerickson@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Expanded setup guidance for Windows on Arm devices with safer default local model selection. * Clarified local inference and sandbox messaging behavior, including conflict checks before rebuilds and safer recovery steps. * Updated destroy/rebuild/reference docs with more detailed warnings, failure handling, and volume-retention guidance. * Improved troubleshooting instructions for Docker DNS issues with clearer paths for unreachable vs. blocked resolvers. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Summary
nemoclaw tunnel startstarts cloudflared and prints the public*.trycloudflare.comURL, but never registers that origin ingateway.controlUi.allowedOrigins, so every Web UI WebSocket arriving through the tunnel is rejected with "origin not allowed". This PR auto-registers the tunnel's exact origin in the in-sandbox gateway config and restarts the gateway so the Web UI works through the tunnel with no manual configuration.Related Issue
Fixes #6212
Changes
src/lib/tunnel/allowed-origins.ts:tunnelUrlToOrigin/isTryCloudflareOrigin/computeTunnelAllowedOrigins— pure origin-list logic: converts the captured tunnel URL to an exact origin (never a wildcard), prunes stale*.trycloudflare.comorigins so the list stays bounded across quick-tunnel restarts, and preserves all other origins (loopback,NEMOCLAW_CORS_ORIGIN, custom domains).registerTunnelOrigin— reads the in-sandbox OpenClaw config via the existingsandbox/config.tsprimitives (readSandboxConfig/writeSandboxConfig/recomputeSandboxConfigHash), applies the updated list, and restarts the gateway. Best-effort (a failure warns and never breakstunnel start), idempotent (no write or restart when the list is unchanged), and skipped for non-OpenClaw agents.src/lib/tunnel/services.ts—startAllcallsregisterTunnelOriginafter the tunnel URL is captured, guarded by the existingSAFE_NAME_REsandbox-name validation, with a clear warning when no sandbox name is available.src/lib/tunnel/allowed-origins.test.ts(origin conversion, prune/preserve, idempotency, agent gating, failure swallowing, sibling-key preservation) and 4startAllintegration tests insrc/lib/tunnel/services.test.tsusing the existing fake-cloudflared pattern.docs/reference/commands.mdx— documents the automatic origin registration undertunnel start(OpenClaw-only block; agent variants verified in sync).Design notes:
*.trycloudflare.comwildcard: a wildcard would accept any trycloudflare tenant's origin (CSWSH exposure); only the URL the user just created is registered.restartSandboxGateway(mutation-locked, health-probed, hash-verified) rather than a rawkill -HUP 1container reap — less disruptive and safer.Type of Change
Quality Gates
Verification
Verifiedin GitHubnpx prek run --from-ref main --to-ref HEADpasses — pre-commit vitest hook hung under coverage (known flake); Biome check run manually on all changed TS files, typecheck:cli cleannpx vitest run src/lib/tunnel/ test/cli/tunnel-command.test.ts— 5 files, 88+ tests pass)npm run docsbuilds without warnings (doc changes only) — 0 errors; 2 pre-existing environment warnings (Fern auth + theme contrast), none introduced by this changeRemaining manual verification: end-to-end run on a root-mode sandbox (immutable/hashed config) to confirm the write + hash recompute + gateway restart sequence on real hardware — the reporter's DGX Station environment. All logic is unit/integration tested and reuses the shipped
config setwrite path.🤖 Generated with Claude Code
Signed-off-by: Tony Luo xialuo@nvidia.com
Summary by CodeRabbit