Skip to content

fix(security): gate GitHub access behind an opt-in policy preset (#1583)#1660

Merged
cv merged 3 commits into
NVIDIA:mainfrom
ColinM-sys:fix/1583-github-policy-opt-in
Apr 9, 2026
Merged

fix(security): gate GitHub access behind an opt-in policy preset (#1583)#1660
cv merged 3 commits into
NVIDIA:mainfrom
ColinM-sys:fix/1583-github-policy-opt-in

Conversation

@ColinM-sys

@ColinM-sys ColinM-sys commented Apr 9, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Move the hardcoded github network_policies entry out of the base sandbox policy and into a new presets/github.yaml so GitHub access (github.com, api.github.com, git, gh) is only granted when the user explicitly opts in during nemoclaw onboard.
  • Add regression tests asserting (a) the base policy never re-declares a github entry or references github.com / api.github.com, and (b) the new preset file exists and parses.

Fixes #1583.

Why

The base policy hardcoded network_policies.github with access: full plus the git and gh binaries. Because the entry lived in the base policy, every sandbox received unscoped GitHub access regardless of which policy presets the user picked. The Available policy presets list during onboard never showed a github option, so the permission was neither user-discoverable nor user-controllable — agents could git clone, git push, and call the GitHub API on behalf of any sandbox without consent. This violates least-privilege and is exactly the kind of silent capability creep the preset system exists to prevent.

What changed

Test plan

  • npx vitest run test/validate-blueprint.test.ts → 29/29 passing.
  • Negative-case verification: stash the base-policy edit and re-run — the new regression test fails as expected, then passes again after pop.
  • Maintainer should sanity-check that no internal flow inside the sandbox depends on git/gh being available out of the box. If something does (e.g., a skill that clones from GitHub), it should either declare the github preset as a dependency or be reworked to use the gateway.

Summary by CodeRabbit

  • New Features

    • Added an optional GitHub preset to enable GitHub.com and GitHub API access (including git/gh) when selected.
  • Refactor

    • Removed GitHub network/binary access from default sandbox; access now enabled only via the optional preset.
  • Tests

    • Added tests ensuring GitHub access is absent by default and the GitHub preset is correctly configured and listed.

Signed-off-by: Colin McDonough cmcdonough@50words.com

The base sandbox policy hardcoded `network_policies.github` with
github.com / api.github.com endpoints (access: full) plus the git and
gh binaries. Because the entry lived in the base policy, every
sandbox received unscoped GitHub access regardless of which policy
presets the user picked during `nemoclaw onboard`. The `Available
policy presets` list never showed a `github` option, so the
permission was neither user-discoverable nor user-controllable —
agents could `git clone`, `git push`, and call the GitHub API on
behalf of any sandbox without consent.

Move the entry into a new `presets/github.yaml` so it shows up in
the onboard preset picker and is only granted when the user
explicitly opts in (or applies it later via `openshell policy set`).
The preset preserves the original semantics (access: full,
git + gh binaries) so existing flows that opt in continue to work
unchanged.

Adds two regression tests in `test/validate-blueprint.test.ts`:
- the base policy must not declare a `github` network_policies entry
  AND must not reference github.com / api.github.com under any
  endpoint key (catches a re-add under a renamed key)
- the new `presets/github.yaml` file must exist, parse, and declare a
  github preset (catches a delete-by-mistake that would leave users
  unable to opt in at all)

Refs: NVIDIA#1583
@coderabbitai

coderabbitai Bot commented Apr 9, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f6421529-e285-4324-b1cb-a1512fcf6f26

📥 Commits

Reviewing files that changed from the base of the PR and between 1f97d82 and 7fda567.

📒 Files selected for processing (3)
  • nemoclaw-blueprint/policies/openclaw-sandbox.yaml
  • test/policies.test.ts
  • test/validate-blueprint.test.ts
✅ Files skipped from review due to trivial changes (1)
  • test/policies.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • test/validate-blueprint.test.ts
  • nemoclaw-blueprint/policies/openclaw-sandbox.yaml

📝 Walkthrough

Walkthrough

GitHub network policy and binary allowances were removed from the default sandbox policy and introduced as a new optional preset named github in nemoclaw-blueprint/policies/presets/github.yaml; tests were added/updated to validate the change.

Changes

Cohort / File(s) Summary
Sandbox policy
nemoclaw-blueprint/policies/openclaw-sandbox.yaml
Removed the top-level network_policies.github entry (endpoints github.com:443, api.github.com:443, binaries /usr/bin/gh, /usr/bin/git) and replaced it with a note pointing to the preset.
GitHub preset
nemoclaw-blueprint/policies/presets/github.yaml
Added new preset.name: github defining network_policies.github with endpoints github.com:443, api.github.com:443 (access: full) and binaries /usr/bin/gh, /usr/bin/git.
Tests
test/validate-blueprint.test.ts, test/policies.test.ts
Added regression tests asserting the base sandbox policy no longer contains a top-level github entry or endpoints referencing GitHub domains; added tests to load/validate the new github preset. Updated policies.listPresets expectations to include the new github preset.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐇 I nibble on configs, tidy and neat,

GitHub now rests in a preset seat.
No default whitelists hopping about,
Users opt in — that's what I'm about.
Hooray for clearer choices, hip-hip hooray!

🚥 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 clearly and specifically describes the main security improvement: moving GitHub access behind an opt-in policy preset.
Linked Issues check ✅ Passed The PR fully addresses issue #1583: removes hardcoded github policy from base sandbox, creates opt-in github preset, adds regression tests ensuring github access is no longer default.
Out of Scope Changes check ✅ Passed All changes are directly scoped to implementing the security fix: policy files, preset creation, and corresponding test updates for validation.
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.

@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.

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

222-230: Strengthen preset regression to lock preserved semantics.

This currently verifies presence only. To protect existing opt-in flows, also assert both endpoints remain access: full and binaries include /usr/bin/git + /usr/bin/gh.

Suggested semantic assertions
   it("regression `#1583`: github preset file exists and parses", () => {
@@
     const np = parsed.network_policies as Record<string, unknown> | undefined;
     expect(np && "github" in np).toBe(true);
+
+    const gh = (np as Record<string, { endpoints?: Array<{ host?: string; access?: string }>; binaries?: Array<{ path?: string }> }>).github;
+    const hosts = new Map((gh?.endpoints ?? []).map((e) => [e.host, e.access]));
+    expect(hosts.get("github.com")).toBe("full");
+    expect(hosts.get("api.github.com")).toBe("full");
+
+    const binPaths = new Set((gh?.binaries ?? []).map((b) => b.path));
+    expect(binPaths.has("/usr/bin/git")).toBe(true);
+    expect(binPaths.has("/usr/bin/gh")).toBe(true);
   });
🤖 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 222 - 230, The regression test
"regression `#1583`: github preset file exists and parses" only checks presence;
update the test (variables: PRESET_PATH, parsed, meta, np) to also assert
preserved semantics by verifying that the github preset's endpoints
configuration contains both expected endpoints with access: "full" and that the
binaries list (under the preset or relevant service definition) includes both
"/usr/bin/git" and "/usr/bin/gh"; locate where parsed.preset and
parsed.network_policies (np) are read and add assertions that meta.name ===
"github", each relevant endpoint object's access === "full", and that the
binaries array contains the required paths.

192-210: Also assert base policy does not whitelist git/gh binaries.

Line 203+ blocks GitHub hosts, but this regression still allows accidental reintroduction of /usr/bin/git or /usr/bin/gh under a different policy key. Add a binary-level assertion to fully enforce #1583 intent.

Suggested test hardening
   it("regression `#1583`: base policy does not silently grant GitHub access", () => {
@@
     const githubHosts = findEndpoints(
       (h) => h === "github.com" || h === "api.github.com",
     );
     expect(githubHosts).toEqual([]);
+
+    // Also ensure git/gh binaries are not granted by default via any policy entry.
+    const blocked = new Set(["/usr/bin/git", "/usr/bin/gh"]);
+    const violatingBinaries: string[] = [];
+    for (const cfg of Object.values((np ?? {}) as Record<string, unknown>)) {
+      const bins = (cfg as { binaries?: Array<{ path?: string }> })?.binaries;
+      if (!Array.isArray(bins)) continue;
+      for (const bin of bins) {
+        if (bin?.path && blocked.has(bin.path)) violatingBinaries.push(bin.path);
+      }
+    }
+    expect(violatingBinaries).toEqual([]);
   });
🤖 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 - 210, Add an assertion
that the base policy does not whitelist the git/gh binaries by scanning the
policy object for any "binaries" entries that include "/usr/bin/git" or
"/usr/bin/gh"; locate the base policy via the existing policy variable (and its
network_policies field) and either reuse the test traversal pattern (similar to
findEndpoints) or add a small helper to collect all binary paths from
base-policy entries, then expect that list not to contain those two paths (i.e.,
expect([...]).toEqual([])).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@test/validate-blueprint.test.ts`:
- Around line 222-230: The regression test "regression `#1583`: github preset file
exists and parses" only checks presence; update the test (variables:
PRESET_PATH, parsed, meta, np) to also assert preserved semantics by verifying
that the github preset's endpoints configuration contains both expected
endpoints with access: "full" and that the binaries list (under the preset or
relevant service definition) includes both "/usr/bin/git" and "/usr/bin/gh";
locate where parsed.preset and parsed.network_policies (np) are read and add
assertions that meta.name === "github", each relevant endpoint object's access
=== "full", and that the binaries array contains the required paths.
- Around line 192-210: Add an assertion that the base policy does not whitelist
the git/gh binaries by scanning the policy object for any "binaries" entries
that include "/usr/bin/git" or "/usr/bin/gh"; locate the base policy via the
existing policy variable (and its network_policies field) and either reuse the
test traversal pattern (similar to findEndpoints) or add a small helper to
collect all binary paths from base-policy entries, then expect that list not to
contain those two paths (i.e., expect([...]).toEqual([])).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6646df01-424d-40a2-922f-0f4d1095c808

📥 Commits

Reviewing files that changed from the base of the PR and between e8b30a2 and 1f97d82.

📒 Files selected for processing (3)
  • nemoclaw-blueprint/policies/openclaw-sandbox.yaml
  • nemoclaw-blueprint/policies/presets/github.yaml
  • test/validate-blueprint.test.ts

ColinM-sys added a commit to ColinM-sys/NemoClaw that referenced this pull request Apr 9, 2026
The base sandbox policy hardcoded `network_policies.npm_registry`
with read-only `registry.npmjs.org` access plus the npm and node
binaries. Because the entry lived in the base policy, every sandbox
received npm registry access regardless of which policy presets the
user picked during `nemoclaw onboard`.

That created the regression in NVIDIA#1458: a sandbox onboarded with ZERO
policy presets could still successfully run `npm install`, while
`pip install` was correctly rejected because PyPI is only declared
in the `pypi` preset (`presets/pypi.yaml`). Two equivalent
package-manager paths, one silently allowed, one correctly gated.
This is the same shape as the GitHub leak fixed in NVIDIA#1583/NVIDIA#1660.

Remove the `npm_registry` entry from the base policy. Users who
need npm in the sandbox can select the existing `npm` preset
(`presets/npm.yaml`) during onboard or apply it later via
`openshell policy set`.

Adds a regression test in test/validate-blueprint.test.ts asserting:
- the base policy must not declare an `npm_registry` network_policies
  entry
- no endpoint anywhere in the base policy may reference
  registry.npmjs.org (catches a re-add under a renamed key)

Refs: NVIDIA#1458
@wscurran wscurran added security Potential vulnerability, unsafe behavior, or access risk priority: high labels Apr 9, 2026
@wscurran

wscurran commented Apr 9, 2026

Copy link
Copy Markdown
Contributor

✨ Thanks for submitting this PR, which proposes a way to improve security by restricting access to GitHub and may prevent unauthorized repository access.


Possibly related open issues:

@cv cv added the v0.0.11 label Apr 9, 2026
cv added a commit that referenced this pull request Apr 9, 2026
)

## Summary

The gate checker and triage scripts treated "all present checks green"
as passing, even when only 2 of ~9 checks existed. This caused premature
approvals on fork PRs where workflows hadn't been triggered yet.

### Root cause

Fork PRs from first-time contributors need a maintainer to click
"Approve and run" before `pull_request` workflows execute. Until then,
only `pull_request_target` checks (`check-pr-limit`) and external bots
(`CodeRabbit`) appear in `statusCheckRollup`. The scripts saw 2/2 green
and reported CI as passing.

A secondary bug: GitHub's `statusCheckRollup` returns two shapes —
`CheckRun` (`name`/`status`/`conclusion`) and `StatusContext`
(`context`/`state`). The scripts only read CheckRun fields, so
CodeRabbit (a StatusContext) was always treated as "pending" even when
`state` was `SUCCESS`.

### Changes

- **`check-gates.ts`**: Add `REQUIRED_CHECK_NAMES` (`checks`,
`commit-lint`, `dco-check`) validation. Add `StatusCheck` union type to
correctly handle both `CheckRun` and `StatusContext` shapes. CI gate now
fails with `"required check(s) not found — workflows may need approval"`
when expected checks are absent.
- **`triage.ts`**: Add same required-check validation so triage does not
score unapproved-workflow PRs as `review-ready`.
- **`MERGE-GATE.md`**: Add "Missing required checks" as first bullet in
Step 2 interpretation guidance.

### Before / After

| PR scenario | Before | After |
|---|---|---|
| Fork PR, workflows not approved (2 checks) | "All 2 checks green" ✅ |
"3 required check(s) not found — workflows may need approval" ❌ |
| Fork PR, workflows running, dco-check failing | "1 pending"
(CodeRabbit misread) | "3 failing check(s): dco-check: FAILURE, ..." ❌ |
| Internal PR, all 12 checks green | "1 pending" (CodeRabbit misread) |
"All 12 checks green" ✅ |

### Test plan

- [x] Verified against PR #1660 (fork, workflows not approved) —
correctly reports missing checks
- [x] Verified against PR #1663 (fork, workflows approved, dco-check
failing) — correctly reports failures
- [x] Verified against PR #1683 (internal, all green) — correctly
reports all 12 green
- [x] Triage script correctly classifies #1660 as `salvage-now` with
`failing-checks` reason instead of `review-ready`

Signed-off-by: Carlos Villela <cvillela@nvidia.com>

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

* **Chores**
* Enhanced merge gate to require specific CI checks be present and
completed before a PR can be approved; missing required checks will
block approval until workflows finish and validation is re-run.
* Improved CI evaluation to better distinguish pending vs failed states
across different check types.
  * PRs missing required check contexts are now classified as not-green.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

@cv cv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Maintainer review — ready for merge.

Gate Status
CI ✅ green (latest runs all passing)
Conflicts ✅ mergeable
CodeRabbit major/critical ✅ none
Risky code tested ✅ regression coverage present

What I salvaged

  • Merged latest into this branch.
  • Added the missing preset-list test update in so the new preset is reflected in the expected count and names.
  • Re-ran the fork workflow approvals and waited for the full suite to finish.

Security pass

  • This correctly removes GitHub access from the baseline sandbox policy.
  • Access is preserved behind an explicit opt-in preset (), which matches least-privilege intent.
  • Regression tests cover both: GitHub is not silently granted by default, and the preset still exists.

One note: the raw still shows an older failed , but the latest rerun passes and CodeRabbit pass 0 Review completed
block edits to migrated legacy paths pass 23s https://github.com/NVIDIA/NemoClaw/actions/runs/24213460727/job/70688052314
changes pass 4s https://github.com/NVIDIA/NemoClaw/actions/runs/24213460872/job/70688052581
checks pass 1m27s https://github.com/NVIDIA/NemoClaw/actions/runs/24213460872/job/70688052603
commit-lint pass 12s https://github.com/NVIDIA/NemoClaw/actions/runs/24213521609/job/70688368795
dco-check pass 4s https://github.com/NVIDIA/NemoClaw/actions/runs/24213521358/job/70688368861
sandbox-images-and-e2e / build-sandbox-images pass 5m53s https://github.com/NVIDIA/NemoClaw/actions/runs/24213460872/job/70688255195
sandbox-images-and-e2e / build-sandbox-images-arm64 pass 1m34s https://github.com/NVIDIA/NemoClaw/actions/runs/24213460872/job/70688255217
sandbox-images-and-e2e / test-e2e-gateway-isolation pass 1m16s https://github.com/NVIDIA/NemoClaw/actions/runs/24213460872/job/70689089004
sandbox-images-and-e2e / test-e2e-sandbox pass 1m46s https://github.com/NVIDIA/NemoClaw/actions/runs/24213460872/job/70689088995 is fully green.

Ready for merge.

@cv cv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Maintainer review — ready for merge.

Gate Status
CI ✅ green (latest runs all passing)
Conflicts ✅ mergeable
CodeRabbit major/critical ✅ none
Risky code tested ✅ regression coverage present

What I salvaged

  • Merged latest main into this branch.
  • Added the missing preset-list test update in test/policies.test.ts so the new github preset is reflected in the expected count and names.
  • Re-ran the fork workflow approvals and waited for the full suite to finish.

Security pass

  • This correctly removes GitHub access from the baseline sandbox policy.
  • Access is preserved behind an explicit opt-in preset (presets/github.yaml), which matches least-privilege intent.
  • Regression tests cover both: GitHub is not silently granted by default, and the preset still exists.

One note: the raw statusCheckRollup still shows an older failed dco-check, but the latest rerun passes and gh pr checks is fully green.

Ready for merge.

@cv cv merged commit 55ba539 into NVIDIA:main Apr 9, 2026
13 of 14 checks passed
miyoungc added a commit that referenced this pull request Apr 10, 2026
…1719)

## Summary
- Remove `github` and `github_rest_api` from baseline network policy
docs (now opt-in preset, #1660)
- Add `github` preset to presets tables in customize-network-policy.md
and best-practices.md
- Add `brave` and `brew` presets to best-practices.md
- Update `huggingface` description (download-only + inference router,
#1663)
- Update `npm` and `pypi` descriptions (GET-only, publishing blocked,
#1672)
- Fix binary-scoping example to reference `github` as a preset, not
baseline
- Add `docs/.docs-skip` exclusion file for suppressing docs on
experimental/unreleased features
- Update `nemoclaw-contributor-update-docs` skill with skip-features,
skip-terms, and agent matrix filtering rules
- Regenerate `nemoclaw-user-*` skills from updated docs

## Test plan
- [x] `make docs` builds without warnings
- [x] All pre-commit and pre-push hooks pass
- [x] Skip-term scan passes (zero violations in branch diff)
- [ ] Verify rendered pages in docs site preview

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

## Summary by CodeRabbit

* **New Features**
* Introduced skip-list configuration for controlling documentation
generation based on commit patterns and excluded terminology.

* **Documentation**
* Updated network policy presets with new `github`, `brave`, and `brew`
options.
* Refined preset descriptions for `huggingface`, `npm`, and `pypi` to
clarify access scopes.
* Clarified that GitHub access is no longer baseline and requires
applying the `github` preset during onboarding.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
swarupsengupta2007 pushed a commit to swarupsengupta2007/NemoClaw that referenced this pull request Apr 12, 2026
The base sandbox policy hardcoded `network_policies.npm_registry`
with read-only `registry.npmjs.org` access plus the npm and node
binaries. Because the entry lived in the base policy, every sandbox
received npm registry access regardless of which policy presets the
user picked during `nemoclaw onboard`.

That created the regression in NVIDIA#1458: a sandbox onboarded with ZERO
policy presets could still successfully run `npm install`, while
`pip install` was correctly rejected because PyPI is only declared
in the `pypi` preset (`presets/pypi.yaml`). Two equivalent
package-manager paths, one silently allowed, one correctly gated.
This is the same shape as the GitHub leak fixed in NVIDIA#1583/NVIDIA#1660.

Remove the `npm_registry` entry from the base policy. Users who
need npm in the sandbox can select the existing `npm` preset
(`presets/npm.yaml`) during onboard or apply it later via
`openshell policy set`.

Adds a regression test in test/validate-blueprint.test.ts asserting:
- the base policy must not declare an `npm_registry` network_policies
  entry
- no endpoint anywhere in the base policy may reference
  registry.npmjs.org (catches a re-add under a renamed key)

Refs: NVIDIA#1458
ericksoa pushed a commit to cheese-head/NemoClaw that referenced this pull request Apr 14, 2026
…IDIA#1707)

## Summary

The gate checker and triage scripts treated "all present checks green"
as passing, even when only 2 of ~9 checks existed. This caused premature
approvals on fork PRs where workflows hadn't been triggered yet.

### Root cause

Fork PRs from first-time contributors need a maintainer to click
"Approve and run" before `pull_request` workflows execute. Until then,
only `pull_request_target` checks (`check-pr-limit`) and external bots
(`CodeRabbit`) appear in `statusCheckRollup`. The scripts saw 2/2 green
and reported CI as passing.

A secondary bug: GitHub's `statusCheckRollup` returns two shapes —
`CheckRun` (`name`/`status`/`conclusion`) and `StatusContext`
(`context`/`state`). The scripts only read CheckRun fields, so
CodeRabbit (a StatusContext) was always treated as "pending" even when
`state` was `SUCCESS`.

### Changes

- **`check-gates.ts`**: Add `REQUIRED_CHECK_NAMES` (`checks`,
`commit-lint`, `dco-check`) validation. Add `StatusCheck` union type to
correctly handle both `CheckRun` and `StatusContext` shapes. CI gate now
fails with `"required check(s) not found — workflows may need approval"`
when expected checks are absent.
- **`triage.ts`**: Add same required-check validation so triage does not
score unapproved-workflow PRs as `review-ready`.
- **`MERGE-GATE.md`**: Add "Missing required checks" as first bullet in
Step 2 interpretation guidance.

### Before / After

| PR scenario | Before | After |
|---|---|---|
| Fork PR, workflows not approved (2 checks) | "All 2 checks green" ✅ |
"3 required check(s) not found — workflows may need approval" ❌ |
| Fork PR, workflows running, dco-check failing | "1 pending"
(CodeRabbit misread) | "3 failing check(s): dco-check: FAILURE, ..." ❌ |
| Internal PR, all 12 checks green | "1 pending" (CodeRabbit misread) |
"All 12 checks green" ✅ |

### Test plan

- [x] Verified against PR NVIDIA#1660 (fork, workflows not approved) —
correctly reports missing checks
- [x] Verified against PR NVIDIA#1663 (fork, workflows approved, dco-check
failing) — correctly reports failures
- [x] Verified against PR NVIDIA#1683 (internal, all green) — correctly
reports all 12 green
- [x] Triage script correctly classifies NVIDIA#1660 as `salvage-now` with
`failing-checks` reason instead of `review-ready`

Signed-off-by: Carlos Villela <cvillela@nvidia.com>

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

* **Chores**
* Enhanced merge gate to require specific CI checks be present and
completed before a PR can be approved; missing required checks will
block approval until workflows finish and validation is re-run.
* Improved CI evaluation to better distinguish pending vs failed states
across different check types.
  * PRs missing required check contexts are now classified as not-green.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ericksoa pushed a commit to cheese-head/NemoClaw that referenced this pull request Apr 14, 2026
…DIA#1583) (NVIDIA#1660)

## Summary
- Move the hardcoded `github` network_policies entry out of the base
sandbox policy and into a new `presets/github.yaml` so GitHub access
(github.com, api.github.com, `git`, `gh`) is only granted when the user
explicitly opts in during `nemoclaw onboard`.
- Add regression tests asserting (a) the base policy never re-declares a
`github` entry or references github.com / api.github.com, and (b) the
new preset file exists and parses.

Fixes NVIDIA#1583.

## Why
The base policy hardcoded `network_policies.github` with `access: full`
plus the `git` and `gh` binaries. Because the entry lived in the base
policy, every sandbox received unscoped GitHub access regardless of
which policy presets the user picked. The `Available policy presets`
list during onboard never showed a `github` option, so the permission
was neither user-discoverable nor user-controllable — agents could `git
clone`, `git push`, and call the GitHub API on behalf of any sandbox
without consent. This violates least-privilege and is exactly the kind
of silent capability creep the preset system exists to prevent.

## What changed
- `nemoclaw-blueprint/policies/openclaw-sandbox.yaml` — remove the
`github` entry, leave a comment pointing at the new preset and NVIDIA#1583.
- `nemoclaw-blueprint/policies/presets/github.yaml` — new file. Same
shape as `presets/brew.yaml`. Preserves the original `access: full`
semantics so users who opt in keep the existing capability set.
- `test/validate-blueprint.test.ts` — two new regression tests under
`NVIDIA#1583`.

## Test plan
- [x] `npx vitest run test/validate-blueprint.test.ts` → 29/29 passing.
- [x] Negative-case verification: stash the base-policy edit and re-run
— the new regression test fails as expected, then passes again after
pop.
- [ ] Maintainer should sanity-check that no internal flow inside the
sandbox depends on `git`/`gh` being available out of the box. If
something does (e.g., a skill that clones from GitHub), it should either
declare the github preset as a dependency or be reworked to use the
gateway.

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

* **New Features**
* Added an optional GitHub preset to enable GitHub.com and GitHub API
access (including git/gh) when selected.

* **Refactor**
* Removed GitHub network/binary access from default sandbox; access now
enabled only via the optional preset.

* **Tests**
* Added tests ensuring GitHub access is absent by default and the GitHub
preset is correctly configured and listed.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: Colin McDonough <cmcdonough@50words.com>

---------

Co-authored-by: Carlos Villela <cvillela@nvidia.com>
ericksoa pushed a commit to cheese-head/NemoClaw that referenced this pull request Apr 14, 2026
…VIDIA#1719)

## Summary
- Remove `github` and `github_rest_api` from baseline network policy
docs (now opt-in preset, NVIDIA#1660)
- Add `github` preset to presets tables in customize-network-policy.md
and best-practices.md
- Add `brave` and `brew` presets to best-practices.md
- Update `huggingface` description (download-only + inference router,
NVIDIA#1663)
- Update `npm` and `pypi` descriptions (GET-only, publishing blocked,
NVIDIA#1672)
- Fix binary-scoping example to reference `github` as a preset, not
baseline
- Add `docs/.docs-skip` exclusion file for suppressing docs on
experimental/unreleased features
- Update `nemoclaw-contributor-update-docs` skill with skip-features,
skip-terms, and agent matrix filtering rules
- Regenerate `nemoclaw-user-*` skills from updated docs

## Test plan
- [x] `make docs` builds without warnings
- [x] All pre-commit and pre-push hooks pass
- [x] Skip-term scan passes (zero violations in branch diff)
- [ ] Verify rendered pages in docs site preview

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

## Summary by CodeRabbit

* **New Features**
* Introduced skip-list configuration for controlling documentation
generation based on commit patterns and excluded terminology.

* **Documentation**
* Updated network policy presets with new `github`, `brave`, and `brew`
options.
* Refined preset descriptions for `huggingface`, `npm`, and `pypi` to
clarify access scopes.
* Clarified that GitHub access is no longer baseline and requires
applying the `github` preset during onboarding.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
gemini2026 pushed a commit to gemini2026/NemoClaw that referenced this pull request Apr 14, 2026
…IDIA#1707)

## Summary

The gate checker and triage scripts treated "all present checks green"
as passing, even when only 2 of ~9 checks existed. This caused premature
approvals on fork PRs where workflows hadn't been triggered yet.

### Root cause

Fork PRs from first-time contributors need a maintainer to click
"Approve and run" before `pull_request` workflows execute. Until then,
only `pull_request_target` checks (`check-pr-limit`) and external bots
(`CodeRabbit`) appear in `statusCheckRollup`. The scripts saw 2/2 green
and reported CI as passing.

A secondary bug: GitHub's `statusCheckRollup` returns two shapes —
`CheckRun` (`name`/`status`/`conclusion`) and `StatusContext`
(`context`/`state`). The scripts only read CheckRun fields, so
CodeRabbit (a StatusContext) was always treated as "pending" even when
`state` was `SUCCESS`.

### Changes

- **`check-gates.ts`**: Add `REQUIRED_CHECK_NAMES` (`checks`,
`commit-lint`, `dco-check`) validation. Add `StatusCheck` union type to
correctly handle both `CheckRun` and `StatusContext` shapes. CI gate now
fails with `"required check(s) not found — workflows may need approval"`
when expected checks are absent.
- **`triage.ts`**: Add same required-check validation so triage does not
score unapproved-workflow PRs as `review-ready`.
- **`MERGE-GATE.md`**: Add "Missing required checks" as first bullet in
Step 2 interpretation guidance.

### Before / After

| PR scenario | Before | After |
|---|---|---|
| Fork PR, workflows not approved (2 checks) | "All 2 checks green" ✅ |
"3 required check(s) not found — workflows may need approval" ❌ |
| Fork PR, workflows running, dco-check failing | "1 pending"
(CodeRabbit misread) | "3 failing check(s): dco-check: FAILURE, ..." ❌ |
| Internal PR, all 12 checks green | "1 pending" (CodeRabbit misread) |
"All 12 checks green" ✅ |

### Test plan

- [x] Verified against PR NVIDIA#1660 (fork, workflows not approved) —
correctly reports missing checks
- [x] Verified against PR NVIDIA#1663 (fork, workflows approved, dco-check
failing) — correctly reports failures
- [x] Verified against PR NVIDIA#1683 (internal, all green) — correctly
reports all 12 green
- [x] Triage script correctly classifies NVIDIA#1660 as `salvage-now` with
`failing-checks` reason instead of `review-ready`

Signed-off-by: Carlos Villela <cvillela@nvidia.com>

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

* **Chores**
* Enhanced merge gate to require specific CI checks be present and
completed before a PR can be approved; missing required checks will
block approval until workflows finish and validation is re-run.
* Improved CI evaluation to better distinguish pending vs failed states
across different check types.
  * PRs missing required check contexts are now classified as not-green.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
gemini2026 pushed a commit to gemini2026/NemoClaw that referenced this pull request Apr 14, 2026
…DIA#1583) (NVIDIA#1660)

## Summary
- Move the hardcoded `github` network_policies entry out of the base
sandbox policy and into a new `presets/github.yaml` so GitHub access
(github.com, api.github.com, `git`, `gh`) is only granted when the user
explicitly opts in during `nemoclaw onboard`.
- Add regression tests asserting (a) the base policy never re-declares a
`github` entry or references github.com / api.github.com, and (b) the
new preset file exists and parses.

Fixes NVIDIA#1583.

## Why
The base policy hardcoded `network_policies.github` with `access: full`
plus the `git` and `gh` binaries. Because the entry lived in the base
policy, every sandbox received unscoped GitHub access regardless of
which policy presets the user picked. The `Available policy presets`
list during onboard never showed a `github` option, so the permission
was neither user-discoverable nor user-controllable — agents could `git
clone`, `git push`, and call the GitHub API on behalf of any sandbox
without consent. This violates least-privilege and is exactly the kind
of silent capability creep the preset system exists to prevent.

## What changed
- `nemoclaw-blueprint/policies/openclaw-sandbox.yaml` — remove the
`github` entry, leave a comment pointing at the new preset and NVIDIA#1583.
- `nemoclaw-blueprint/policies/presets/github.yaml` — new file. Same
shape as `presets/brew.yaml`. Preserves the original `access: full`
semantics so users who opt in keep the existing capability set.
- `test/validate-blueprint.test.ts` — two new regression tests under
`NVIDIA#1583`.

## Test plan
- [x] `npx vitest run test/validate-blueprint.test.ts` → 29/29 passing.
- [x] Negative-case verification: stash the base-policy edit and re-run
— the new regression test fails as expected, then passes again after
pop.
- [ ] Maintainer should sanity-check that no internal flow inside the
sandbox depends on `git`/`gh` being available out of the box. If
something does (e.g., a skill that clones from GitHub), it should either
declare the github preset as a dependency or be reworked to use the
gateway.

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

* **New Features**
* Added an optional GitHub preset to enable GitHub.com and GitHub API
access (including git/gh) when selected.

* **Refactor**
* Removed GitHub network/binary access from default sandbox; access now
enabled only via the optional preset.

* **Tests**
* Added tests ensuring GitHub access is absent by default and the GitHub
preset is correctly configured and listed.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: Colin McDonough <cmcdonough@50words.com>

---------

Co-authored-by: Carlos Villela <cvillela@nvidia.com>
gemini2026 pushed a commit to gemini2026/NemoClaw that referenced this pull request Apr 14, 2026
…VIDIA#1719)

## Summary
- Remove `github` and `github_rest_api` from baseline network policy
docs (now opt-in preset, NVIDIA#1660)
- Add `github` preset to presets tables in customize-network-policy.md
and best-practices.md
- Add `brave` and `brew` presets to best-practices.md
- Update `huggingface` description (download-only + inference router,
NVIDIA#1663)
- Update `npm` and `pypi` descriptions (GET-only, publishing blocked,
NVIDIA#1672)
- Fix binary-scoping example to reference `github` as a preset, not
baseline
- Add `docs/.docs-skip` exclusion file for suppressing docs on
experimental/unreleased features
- Update `nemoclaw-contributor-update-docs` skill with skip-features,
skip-terms, and agent matrix filtering rules
- Regenerate `nemoclaw-user-*` skills from updated docs

## Test plan
- [x] `make docs` builds without warnings
- [x] All pre-commit and pre-push hooks pass
- [x] Skip-term scan passes (zero violations in branch diff)
- [ ] Verify rendered pages in docs site preview

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

## Summary by CodeRabbit

* **New Features**
* Introduced skip-list configuration for controlling documentation
generation based on commit patterns and excluded terminology.

* **Documentation**
* Updated network policy presets with new `github`, `brave`, and `brew`
options.
* Refined preset descriptions for `huggingface`, `npm`, and `pypi` to
clarify access scopes.
* Clarified that GitHub access is no longer baseline and requires
applying the `github` preset during onboarding.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@wscurran wscurran added area: integrations Third-party service integration behavior bug-fix PR fixes a bug or regression labels Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: integrations Third-party service integration behavior 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 Platform] GitHub policy + binary is injected into sandbox runtime policy without user opt-in

3 participants