Skip to content

fix(policy): restrict baseline npm_registry to openclaw binary only#1700

Merged
cv merged 5 commits into
NVIDIA:mainfrom
BenediktSchackenberg:fix/none-policy-npm-bypass
Apr 14, 2026
Merged

fix(policy): restrict baseline npm_registry to openclaw binary only#1700
cv merged 5 commits into
NVIDIA:mainfrom
BenediktSchackenberg:fix/none-policy-npm-bypass

Conversation

@BenediktSchackenberg

@BenediktSchackenberg BenediktSchackenberg commented Apr 9, 2026

Copy link
Copy Markdown
Contributor

Problem

With 'none' policy selected during onboard, npm install still succeeded because the baseline policy (openclaw-sandbox.yaml) included /usr/local/bin/npm and /usr/local/bin/node in the npm_registry binaries list. This bypassed the user's intent of no external network access.

The baseline npm_registry entry exists solely for openclaw plugins install — not for agent-driven npm usage. Any sandbox with 'none' preset should block npm from the agent.

Fix

Removed /usr/local/bin/npm and /usr/local/bin/node from the baseline npm_registry binaries list. Only /usr/local/bin/openclaw retains access to registry.npmjs.org by default.

Users who need npm/node network access in the sandbox should add the npm preset during onboard or afterwards via nemoclaw policy.

Testing

  • nemoclaw onboard with no policy presets → npm install should now be blocked (403 Forbidden from proxy)
  • openclaw plugins install <plugin> should still work (uses the openclaw binary)
  • nemoclaw onboard with npm preset → npm install still works as expected

Fixes #1458

Signed-off-by: Benedikt Schackenberg 6381261+BenediktSchackenberg@users.noreply.github.com

Summary by CodeRabbit

  • New Features
    • Added network policy entries to enable controlled Telegram and Discord messaging access.
  • Chores
    • Restricted registry access so only the plugin installer retains direct registry rights; npm/node are no longer allowed by default and require a separate preset.
  • Documentation
    • Updated network policy docs to reflect stricter allowed binaries and GET-only registry requests.
  • Tests
    • Added a regression test to enforce the registry access whitelist.

Copilot AI review requested due to automatic review settings April 9, 2026 18:05
@coderabbitai

coderabbitai Bot commented Apr 9, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Restricted the npm_registry network policy to only allow /usr/local/bin/openclaw with GET requests, added new messaging network policies for telegram and discord constrained to /usr/local/bin/node (discord also allows gateway WebSocket CONNECT), and added a test validating the narrowed npm binary allowlist. Documentation was updated accordingly.

Changes

Cohort / File(s) Summary
Policy file
nemoclaw-blueprint/policies/openclaw-sandbox.yaml
Narrowed network_policies.npm_registry.binaries to only /usr/local/bin/openclaw and limited rules to GET; removed /usr/local/bin/npm and /usr/local/bin/node. Added telegram and discord messaging endpoint groups: both restrict binaries to /usr/local/bin/node; telegram allows GET/POST to api.telegram.org under bot paths; discord allows REST GET/POST to discord.com, CDN GETs, and gateway WebSocket traffic via gateway.discord.gg using access: full (CONNECT).
Documentation
docs/reference/network-policies.md, .agents/skills/nemoclaw-user-reference/references/network-policies.md
Updated docs to reflect that npm_registry only permits /usr/local/bin/openclaw (for openclaw plugins install) and limited methods (GET). Documented new telegram and discord policy entries and their intended binary constraints.
Tests
test/validate-blueprint.test.ts
Added Vitest regression test that reads policy.network_policies.npm_registry, asserts binaries exists and is an array, and enforces the exact allowlist of ["/usr/local/bin/openclaw"] for binary paths.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant User as "Sandboxed User Process"
participant Policy as "Network Policy Engine\n(openclaw-sandbox.yaml)"
participant Binary as "Binary invoked\n(openclaw / node)"
participant External as "External API\n(telegram/discord/npm)"
rect rgba(200,230,255,0.5)
User->>Binary: execute (e.g. openclaw/plugins or node script)
Binary->>Policy: request network access (method, host, path, proto)
Policy-->>Binary: allow/deny (based on binaries list & rules)
Binary->>External: network request (if allowed)
External-->>Binary: response
end

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I hop through YAML and gates so tight,
OpenClaw peeks — npm dimmed to light,
Node speaks to bots with careful tread,
Discord webs and Telegram threads,
I nibble rules and guard the night.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: restricting the baseline npm_registry policy to only the openclaw binary, which directly addresses the core fix for the regression.
Linked Issues check ✅ Passed All coding requirements from issue #1458 are met: npm/node binaries removed from baseline npm_registry [#1458], regression test added to prevent recurrence [#1458], documentation updated to reflect the restriction [#1458], and the fix ensures policy enforcement blocks npm access under 'none' preset [#1458].
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the npm_registry policy regression: policy YAML updates, documentation edits, and regression tests all address the linked issue without unrelated modifications.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the baseline OpenClaw sandbox network policy so that “none” onboarding no longer permits agent-driven npm install egress to registry.npmjs.org, while keeping plugin installation working via the openclaw CLI.

Changes:

  • Removed /usr/local/bin/npm and /usr/local/bin/node from the baseline npm_registry policy’s allowed binaries.
  • Clarified inline policy comments to document that npm_registry is intended for openclaw plugins install only and references issue #1458.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +194 to 199
# npm registry — needed for `openclaw plugins install` only.
# Restricted to the openclaw binary so agents cannot use npm directly.
# Users who need npm/node access should add the npm policy preset during onboard.
# Ref: https://github.com/NVIDIA/NemoClaw/issues/1458
npm_registry:
name: npm_registry

Copilot AI Apr 9, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation tables still describe the baseline npm_registry policy as allowing /usr/local/bin/npm and /usr/local/bin/node (and even “All methods”), but the baseline policy is now restricted to /usr/local/bin/openclaw with GET-only. Please update docs/reference/network-policies.md and .agents/skills/nemoclaw-user-reference/references/network-policies.md to match this policy change so users aren’t misled.

Copilot uses AI. Check for mistakes.
Comment on lines 198 to 209
@@ -205,8 +207,6 @@ network_policies:
- allow: { method: GET, path: "/**" }
binaries:
- { path: /usr/local/bin/openclaw }

Copilot AI Apr 9, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given this is a security regression fix (#1458), consider adding a small regression test that asserts the baseline npm_registry binaries list does not include npm/node (e.g., in test/validate-blueprint.test.ts). That will prevent accidental reintroduction of agent npm egress in future edits.

Copilot uses AI. Check for mistakes.
BenediktSchackenberg added a commit to BenediktSchackenberg/NemoClaw that referenced this pull request Apr 9, 2026
- Update docs/reference/network-policies.md: npm_registry now shows
  openclaw-only binary and GET-only access (not npm/node + all methods)
- Update .agents/skills/nemoclaw-user-reference/references/network-policies.md
  with the same correction
- Add regression test in validate-blueprint.test.ts (NVIDIA#1458): asserts
  that /usr/local/bin/npm and /usr/local/bin/node are not in the baseline
  npm_registry binaries list to prevent reintroduction of agent npm egress

Per Copilot review on NVIDIA#1700.

Signed-off-by: Benedikt Schackenberg <6381261+BenediktSchackenberg@users.noreply.github.com>
@BenediktSchackenberg

Copy link
Copy Markdown
Contributor Author

Addressed both review points:

  1. Docs updateddocs/reference/network-policies.md and .agents/skills/nemoclaw-user-reference/references/network-policies.md now show openclaw only + GET-only for npm_registry
  2. Regression test addedtest/validate-blueprint.test.ts now asserts that /usr/local/bin/npm and /usr/local/bin/node are absent from the baseline npm_registry binaries list (28 tests pass)

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
test/validate-blueprint.test.ts (1)

192-204: Strengthen the regression test to enforce an exact allowlist.

Current assertions still pass if another unexpected binary gets added. Consider asserting the final list is exactly openclaw.

Suggested test hardening
-    const paths = (binaries ?? []).map((b) => b.path);
+    const paths = (binaries ?? []).map((b) => b.path).sort();
@@
-    expect(paths).not.toContain("/usr/local/bin/npm");
-    expect(paths).not.toContain("/usr/local/bin/node");
-    expect(paths).toContain("/usr/local/bin/openclaw");
+    expect(paths).toEqual(["/usr/local/bin/openclaw"]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/validate-blueprint.test.ts` around lines 192 - 204, The test "regression
`#1458`: baseline npm_registry must not include npm or node binaries" currently
checks only that npm/node are absent and openclaw is present; change it to
enforce an exact allowlist by asserting that the computed paths (from np,
npm_registry, binaries, paths) equal exactly ['/usr/local/bin/openclaw'] (use a
strict equality assertion such as toEqual/toStrictEqual) so no other unexpected
binaries are allowed; replace or augment the existing expect(...) checks with a
single exact-match assertion on paths.
docs/reference/network-policies.md (1)

93-94: Format the CLI command as inline code in the table cell.

In Line 93, openclaw plugins install is a CLI command in prose; wrap it in inline code.

Suggested doc fix
-  - `/usr/local/bin/openclaw` only (openclaw plugins install)
+  - `/usr/local/bin/openclaw` only (`openclaw plugins install`)

As per coding guidelines, “CLI commands, file paths, flags, parameter names, and values must use inline code formatting,” and word-list casing checks are exempt inside code spans.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/reference/network-policies.md` around lines 93 - 94, Wrap the inline CLI
command and any file paths in code formatting: replace the plain text "openclaw
plugins install" and "/usr/local/bin/openclaw" in the table cell with inline
code spans (e.g., `openclaw plugins install` and `/usr/local/bin/openclaw`) so
they follow the guideline that CLI commands, file paths, flags, parameter names,
and values use inline code formatting.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.agents/skills/nemoclaw-user-reference/references/network-policies.md:
- Around line 71-72: This change edited an autogenerated skill doc under the
.agents/skills/nemoclaw-user-* tree; revert the direct edit and instead make the
content change in the source docs (docs/), then regenerate the skill markdown
using the generator script so the update is not lost: update the relevant file
in docs/, run python3 scripts/docs-to-skills.py docs/ .agents/skills/ --prefix
nemoclaw-user to produce refreshed .agents/skills/nemoclaw-user-*.md files, and
commit the regenerated artifacts (do not edit .agents/skills/nemoclaw-user-*.md
by hand).

---

Nitpick comments:
In `@docs/reference/network-policies.md`:
- Around line 93-94: Wrap the inline CLI command and any file paths in code
formatting: replace the plain text "openclaw plugins install" and
"/usr/local/bin/openclaw" in the table cell with inline code spans (e.g.,
`openclaw plugins install` and `/usr/local/bin/openclaw`) so they follow the
guideline that CLI commands, file paths, flags, parameter names, and values use
inline code formatting.

In `@test/validate-blueprint.test.ts`:
- Around line 192-204: The test "regression `#1458`: baseline npm_registry must
not include npm or node binaries" currently checks only that npm/node are absent
and openclaw is present; change it to enforce an exact allowlist by asserting
that the computed paths (from np, npm_registry, binaries, paths) equal exactly
['/usr/local/bin/openclaw'] (use a strict equality assertion such as
toEqual/toStrictEqual) so no other unexpected binaries are allowed; replace or
augment the existing expect(...) checks with a single exact-match assertion on
paths.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1e544d00-127e-442d-b1e2-a4ac6efe093b

📥 Commits

Reviewing files that changed from the base of the PR and between d8b13c0 and aa599c2.

📒 Files selected for processing (3)
  • .agents/skills/nemoclaw-user-reference/references/network-policies.md
  • docs/reference/network-policies.md
  • test/validate-blueprint.test.ts

BenediktSchackenberg added a commit to BenediktSchackenberg/NemoClaw that referenced this pull request Apr 9, 2026
- Revert direct edit of .agents/skills/ and regenerate via
  scripts/docs-to-skills.py as required by coding guidelines
- Tighten regression test: use exact allowlist (toEqual) instead of
  not.toContain to catch any future unexpected binary additions

Per CodeRabbit review on NVIDIA#1700.

Signed-off-by: Benedikt Schackenberg <6381261+BenediktSchackenberg@users.noreply.github.com>
@BenediktSchackenberg

Copy link
Copy Markdown
Contributor Author

Addressed both CodeRabbit points:

  1. Skills docs: reverted the direct edit, ran python3 scripts/docs-to-skills.py docs/ .agents/skills/ --prefix nemoclaw-user to regenerate — fix is now in sync
  2. Regression test: switched to exact allowlist (toEqual(["/usr/local/bin/openclaw"])) — any unexpected binary addition will now fail the test

@wscurran wscurran added security Potential vulnerability, unsafe behavior, or access risk priority: high labels Apr 10, 2026
@wscurran

Copy link
Copy Markdown
Contributor

✨ Thanks for submitting this PR, which proposes a fix for an issue with the baseline npm registry policy and may improve the overall security of the system.


Possibly related open issues:

@BenediktSchackenberg BenediktSchackenberg force-pushed the fix/none-policy-npm-bypass branch from a66ba34 to c5cdb39 Compare April 10, 2026 17:41
BenediktSchackenberg added a commit to BenediktSchackenberg/NemoClaw that referenced this pull request Apr 10, 2026
- Update docs/reference/network-policies.md: npm_registry now shows
  openclaw-only binary and GET-only access (not npm/node + all methods)
- Update .agents/skills/nemoclaw-user-reference/references/network-policies.md
  with the same correction
- Add regression test in validate-blueprint.test.ts (NVIDIA#1458): asserts
  that /usr/local/bin/npm and /usr/local/bin/node are not in the baseline
  npm_registry binaries list to prevent reintroduction of agent npm egress

Per Copilot review on NVIDIA#1700.

Signed-off-by: Benedikt Schackenberg <6381261+BenediktSchackenberg@users.noreply.github.com>
The baseline policy allowed /usr/local/bin/npm and /usr/local/bin/node
to reach registry.npmjs.org. This meant npm install worked even with
'none' policy preset selected during onboard — violating user intent.

The npm_registry entry in the baseline exists for 'openclaw plugins install'
only, not for agent-driven npm usage. Removing npm/node from the binaries
list so only the openclaw CLI binary can reach the npm registry by default.

Users who need npm/node access in the sandbox should add the 'npm' preset
during onboard or via nemoclaw policy.

Fixes NVIDIA#1458

Signed-off-by: Benedikt Schackenberg <6381261+BenediktSchackenberg@users.noreply.github.com>
- Update docs/reference/network-policies.md: npm_registry now shows
  openclaw-only binary and GET-only access (not npm/node + all methods)
- Update .agents/skills/nemoclaw-user-reference/references/network-policies.md
  with the same correction
- Add regression test in validate-blueprint.test.ts (NVIDIA#1458): asserts
  that /usr/local/bin/npm and /usr/local/bin/node are not in the baseline
  npm_registry binaries list to prevent reintroduction of agent npm egress

Per Copilot review on NVIDIA#1700.

Signed-off-by: Benedikt Schackenberg <6381261+BenediktSchackenberg@users.noreply.github.com>
@BenediktSchackenberg BenediktSchackenberg force-pushed the fix/none-policy-npm-bypass branch from c5cdb39 to 429ae49 Compare April 13, 2026 18:24
@cv cv added the v0.0.16 label Apr 14, 2026
@cv cv merged commit 855924f into NVIDIA:main Apr 14, 2026
14 checks passed
latenighthackathon added a commit to latenighthackathon/NemoClaw that referenced this pull request Apr 30, 2026
…NVIDIA#2180)

After a fresh `nemoclaw onboard` with Balanced tier defaults, where the
user explicitly skipped messaging channels in step [5/8] and did not
tick Discord in step [8/8], `nemoclaw <name> policy-list` reports:

    ● discord — Discord API, gateway, and CDN access
      (active on gateway, missing from local state)

The sandbox can reach `discord.com`, `gateway.discord.gg`, and
`cdn.discordapp.com` without the user having opted in — the base
sandbox policy's own header says "deny by default, allow only what's
needed for core functionality," which messaging to third-party IM
platforms is not. Same story for `api.telegram.org`.

This is a regression, not a new bug:

- NVIDIA#1705 (2026-04-09, 77051cc) removed pre-allowed `telegram` and
  `discord` from `nemoclaw-blueprint/policies/openclaw-sandbox.yaml`
  for exactly this reason.
- NVIDIA#1700 (2026-04-14, 855924f), an unrelated npm_registry PR, was
  rebased on a branch that predated NVIDIA#1705 and re-added both entries
  during conflict resolution. The CodeRabbit release notes on NVIDIA#1700
  even called this out as "Added network policy entries to enable
  controlled Telegram and Discord messaging access" — it landed along
  with the legitimate npm_registry tightening and has been in the
  baseline since.

Once a key like `discord` exists in the gateway's loaded policy,
`policies.getGatewayPresets()` detects the Discord preset as active
(it matches on key presence), and `policy-list` then renders the
misleading "active on gateway, missing from local state" line.

- Re-remove `telegram` and `discord` entries from
  `nemoclaw-blueprint/policies/openclaw-sandbox.yaml`. Messaging
  endpoints are only reachable if the user selects the matching
  channel in step [5/8] and the corresponding preset is applied on
  top of the baseline in step [8/8]. Leave a comment block at the
  removed location referencing NVIDIA#1705, NVIDIA#2180, and the preset path so
  the next merge-conflict resolution does not casually re-add them.
- Add three regression tests in `test/validate-blueprint.test.ts`
  mirroring the existing `NVIDIA#1583` GitHub pattern:
  - `regression NVIDIA#2180: base policy does not silently grant Telegram access`
  - `regression NVIDIA#2180: base policy does not silently grant Discord access`
  - `regression NVIDIA#2180: base policy does not silently grant Slack access`
    (guard against the same merge pattern re-adding Slack even though
    it was never in the baseline historically)
  Each asserts both the key absence in `network_policies` and the
  absence of any host-matching endpoint anywhere in the base policy,
  so a rename can't smuggle the grant back in.

- `npx vitest run test/validate-blueprint.test.ts test/policies.test.ts`
  — 124 tests pass including the 3 new regressions.
- `npx vitest run test/validate-configs-dangerous-hosts.test.ts test/onboard.test.ts`
  — 160 tests pass, no onboard flow regressions.

Touches only the base policy YAML and the blueprint validator. Does
not modify any preset (presets/telegram.yaml, presets/discord.yaml,
presets/slack.yaml) — users who enabled messaging via onboard still
get the same preset applied on top of baseline and retain the same
endpoint access. The permissive variant
(openclaw-sandbox-permissive.yaml), used for
`--dangerously-skip-permissions`, is intentionally unchanged.

Fixes NVIDIA#2180.

Signed-off-by: latenighthackathon <latenighthackathon@users.noreply.github.com>
latenighthackathon added a commit to latenighthackathon/NemoClaw that referenced this pull request May 5, 2026
…NVIDIA#2180)

After a fresh `nemoclaw onboard` with Balanced tier defaults, where the
user explicitly skipped messaging channels in step [5/8] and did not
tick Discord in step [8/8], `nemoclaw <name> policy-list` reports:

    ● discord — Discord API, gateway, and CDN access
      (active on gateway, missing from local state)

The sandbox can reach `discord.com`, `gateway.discord.gg`, and
`cdn.discordapp.com` without the user having opted in — the base
sandbox policy's own header says "deny by default, allow only what's
needed for core functionality," which messaging to third-party IM
platforms is not. Same story for `api.telegram.org`.

This is a regression, not a new bug:

- NVIDIA#1705 (2026-04-09, 77051cc) removed pre-allowed `telegram` and
  `discord` from `nemoclaw-blueprint/policies/openclaw-sandbox.yaml`
  for exactly this reason.
- NVIDIA#1700 (2026-04-14, 855924f), an unrelated npm_registry PR, was
  rebased on a branch that predated NVIDIA#1705 and re-added both entries
  during conflict resolution. The CodeRabbit release notes on NVIDIA#1700
  even called this out as "Added network policy entries to enable
  controlled Telegram and Discord messaging access" — it landed along
  with the legitimate npm_registry tightening and has been in the
  baseline since.

Once a key like `discord` exists in the gateway's loaded policy,
`policies.getGatewayPresets()` detects the Discord preset as active
(it matches on key presence), and `policy-list` then renders the
misleading "active on gateway, missing from local state" line.

- Re-remove `telegram` and `discord` entries from
  `nemoclaw-blueprint/policies/openclaw-sandbox.yaml`. Messaging
  endpoints are only reachable if the user selects the matching
  channel in step [5/8] and the corresponding preset is applied on
  top of the baseline in step [8/8]. Leave a comment block at the
  removed location referencing NVIDIA#1705, NVIDIA#2180, and the preset path so
  the next merge-conflict resolution does not casually re-add them.
- Add three regression tests in `test/validate-blueprint.test.ts`
  mirroring the existing `NVIDIA#1583` GitHub pattern:
  - `regression NVIDIA#2180: base policy does not silently grant Telegram access`
  - `regression NVIDIA#2180: base policy does not silently grant Discord access`
  - `regression NVIDIA#2180: base policy does not silently grant Slack access`
    (guard against the same merge pattern re-adding Slack even though
    it was never in the baseline historically)
  Each asserts both the key absence in `network_policies` and the
  absence of any host-matching endpoint anywhere in the base policy,
  so a rename can't smuggle the grant back in.

- `npx vitest run test/validate-blueprint.test.ts test/policies.test.ts`
  — 124 tests pass including the 3 new regressions.
- `npx vitest run test/validate-configs-dangerous-hosts.test.ts test/onboard.test.ts`
  — 160 tests pass, no onboard flow regressions.

Touches only the base policy YAML and the blueprint validator. Does
not modify any preset (presets/telegram.yaml, presets/discord.yaml,
presets/slack.yaml) — users who enabled messaging via onboard still
get the same preset applied on top of baseline and retain the same
endpoint access. The permissive variant
(openclaw-sandbox-permissive.yaml), used for
`--dangerously-skip-permissions`, is intentionally unchanged.

Fixes NVIDIA#2180.

Signed-off-by: latenighthackathon <latenighthackathon@users.noreply.github.com>
jyaunches pushed a commit to latenighthackathon/NemoClaw that referenced this pull request May 6, 2026
…NVIDIA#2180)

After a fresh `nemoclaw onboard` with Balanced tier defaults, where the
user explicitly skipped messaging channels in step [5/8] and did not
tick Discord in step [8/8], `nemoclaw <name> policy-list` reports:

    ● discord — Discord API, gateway, and CDN access
      (active on gateway, missing from local state)

The sandbox can reach `discord.com`, `gateway.discord.gg`, and
`cdn.discordapp.com` without the user having opted in — the base
sandbox policy's own header says "deny by default, allow only what's
needed for core functionality," which messaging to third-party IM
platforms is not. Same story for `api.telegram.org`.

This is a regression, not a new bug:

- NVIDIA#1705 (2026-04-09, 77051cc) removed pre-allowed `telegram` and
  `discord` from `nemoclaw-blueprint/policies/openclaw-sandbox.yaml`
  for exactly this reason.
- NVIDIA#1700 (2026-04-14, 855924f), an unrelated npm_registry PR, was
  rebased on a branch that predated NVIDIA#1705 and re-added both entries
  during conflict resolution. The CodeRabbit release notes on NVIDIA#1700
  even called this out as "Added network policy entries to enable
  controlled Telegram and Discord messaging access" — it landed along
  with the legitimate npm_registry tightening and has been in the
  baseline since.

Once a key like `discord` exists in the gateway's loaded policy,
`policies.getGatewayPresets()` detects the Discord preset as active
(it matches on key presence), and `policy-list` then renders the
misleading "active on gateway, missing from local state" line.

- Re-remove `telegram` and `discord` entries from
  `nemoclaw-blueprint/policies/openclaw-sandbox.yaml`. Messaging
  endpoints are only reachable if the user selects the matching
  channel in step [5/8] and the corresponding preset is applied on
  top of the baseline in step [8/8]. Leave a comment block at the
  removed location referencing NVIDIA#1705, NVIDIA#2180, and the preset path so
  the next merge-conflict resolution does not casually re-add them.
- Add three regression tests in `test/validate-blueprint.test.ts`
  mirroring the existing `NVIDIA#1583` GitHub pattern:
  - `regression NVIDIA#2180: base policy does not silently grant Telegram access`
  - `regression NVIDIA#2180: base policy does not silently grant Discord access`
  - `regression NVIDIA#2180: base policy does not silently grant Slack access`
    (guard against the same merge pattern re-adding Slack even though
    it was never in the baseline historically)
  Each asserts both the key absence in `network_policies` and the
  absence of any host-matching endpoint anywhere in the base policy,
  so a rename can't smuggle the grant back in.

- `npx vitest run test/validate-blueprint.test.ts test/policies.test.ts`
  — 124 tests pass including the 3 new regressions.
- `npx vitest run test/validate-configs-dangerous-hosts.test.ts test/onboard.test.ts`
  — 160 tests pass, no onboard flow regressions.

Touches only the base policy YAML and the blueprint validator. Does
not modify any preset (presets/telegram.yaml, presets/discord.yaml,
presets/slack.yaml) — users who enabled messaging via onboard still
get the same preset applied on top of baseline and retain the same
endpoint access. The permissive variant
(openclaw-sandbox-permissive.yaml), used for
`--dangerously-skip-permissions`, is intentionally unchanged.

Fixes NVIDIA#2180.

Signed-off-by: latenighthackathon <latenighthackathon@users.noreply.github.com>
jyaunches added a commit that referenced this pull request May 7, 2026
## Summary

The base sandbox policy
(`nemoclaw-blueprint/policies/openclaw-sandbox.yaml`) was silently
granting every sandbox egress to `api.telegram.org`, `discord.com`,
`gateway.discord.gg`, and `cdn.discordapp.com` — regardless of whether
the user enabled the telegram/discord messaging channel in step [5/8] or
ticked the preset in step [8/8] of onboard. This is a regression of a
previously-fixed behavior.

After a fresh onboard that explicitly skipped messaging channels and did
not tick Discord in the Balanced-tier preset picker, `nemoclaw <name>
policy-list` reports:

```
● discord — Discord API, gateway, and CDN access (active on gateway, missing from local state)
```

## Problem

Regression history:

- [#1705](#1705) (2026-04-09,
[`77051cc8`](77051cc8)) —
removed `telegram` and `discord` from baseline "for exactly this
reason." Explicitly called it a data exfiltration vector.
- [#1700](#1700) (2026-04-14,
[`855924fd`](855924fd)) — an
unrelated npm_registry PR that was rebased on a branch predating #1705.
The CodeRabbit release notes on #1700 even flagged it: *"Added network
policy entries to enable controlled Telegram and Discord messaging
access."* The messaging entries came back as part of that PR's
conflict-resolution and have been in the baseline since.

Once `discord` exists as a key in the gateway's loaded policy,
`policies.getGatewayPresets()` detects the Discord preset as active (it
matches on key presence). `nemoclaw policy-list` then renders the
misleading "active on gateway, missing from local state" line for a
preset the user never selected — and the egress is actually enforced, so
it's a real capability grant, not just a display bug.

## Test plan

- [x] `npx vitest run test/validate-blueprint.test.ts
test/policies.test.ts` — 124 tests pass, including the three new
regression tests that guard against this specific re-add pattern for
telegram, discord, and slack.
- [x] `npx vitest run test/validate-configs-dangerous-hosts.test.ts
test/onboard.test.ts` — 160 tests pass. No onboard-flow regressions.
- [x] Manually verified that users who enable a messaging channel in
step [5/8] and apply the corresponding preset in step [8/8] still get
identical endpoint access via `presets/{telegram,discord}.yaml` (no
preset YAML changes in this PR).
- [x] `openclaw-sandbox-permissive.yaml` (used for
`--dangerously-skip-permissions`) unchanged — permissive users still get
pre-allowed messaging as before.

Fixes #2180.

Signed-off-by: latenighthackathon
<latenighthackathon@users.noreply.github.com>

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Removed default network permissions for Telegram and Discord from the
sandbox baseline; messaging endpoints (Telegram, Discord, Slack) are no
longer enabled by default and must be added via opt-in presets during
onboarding.

* **Tests**
* Added regression tests to ensure messaging provider access (Telegram,
Discord, Slack) remains restricted in the baseline policy and cannot be
reintroduced inadvertently.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: latenighthackathon <latenighthackathon@users.noreply.github.com>
Co-authored-by: latenighthackathon <latenighthackathon@users.noreply.github.com>
Co-authored-by: J. Yaunches <jyaunches@nvidia.com>
@wscurran wscurran added bug-fix PR fixes a bug or regression and removed priority: high labels Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug-fix PR fixes a bug or regression security Potential vulnerability, unsafe behavior, or access risk

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[All platforms][Regression] None policy added but NPM install is able to execute

4 participants