Skip to content

fix(policy): add protocol/enforcement/tls to GitHub endpoints#1225

Open
latenighthackathon wants to merge 1 commit intoNVIDIA:mainfrom
latenighthackathon:fix/github-policy-protocol
Open

fix(policy): add protocol/enforcement/tls to GitHub endpoints#1225
latenighthackathon wants to merge 1 commit intoNVIDIA:mainfrom
latenighthackathon:fix/github-policy-protocol

Conversation

@latenighthackathon
Copy link
Copy Markdown
Contributor

@latenighthackathon latenighthackathon commented Apr 1, 2026

Summary

  • Replace access: full on github.com and api.github.com with protocol: rest, enforcement: enforce, tls: terminate, and explicitly scoped method/path rules
  • Splits git transport (github.com) from REST API (api.github.com) so each host has the minimum method set it actually needs
  • Excludes DELETE entirely to block destructive ops (repo deletion, branch force-delete, org membership changes)

Related Issue

Closes #1111

Changes

The GitHub policy used access: full without protocol: rest, which means the proxy treats connections as L4-only — method/path rules cannot be evaluated, per-request logging is unavailable, and credential injection via SecretResolver won't work.

This fix adds the L7 inspection fields that every other REST endpoint in the policy already has, and replaces the access: full shorthand with explicit rules scoped to PR/issue/git workflows.

github.com — git transport only

  • GET /** — ref discovery (git clone, git ls-remote)
  • POST /**/git-upload-pack — clone/fetch handshake
  • POST /**/git-receive-pack — push handshake

api.github.com — REST API

  • GET /** — unrestricted reads
  • PR workflow: create PRs, update PRs, request reviewers, submit reviews, merge PRs
  • Issue workflow: create issues, update issues, comment on issues/PRs
  • Git refs/contents: branch creation, ref updates, file commits via Contents API
  • POST /repos/*/*/actions/workflows/*/dispatches — manual workflow dispatch (gh workflow run)
  • DELETE excluded entirely

Testing — workflow validation

Each common gh and git workflow was mapped against the rule set to confirm coverage. All standard agent operations are covered; destructive operations are explicitly blocked.

git transport (github.com)

Workflow HTTP call Rule Status
git clone (ref discovery) GET /{o}/{r}.git/info/refs GET /**
git clone (handshake) POST /{o}/{r}.git/git-upload-pack POST /**/git-upload-pack
git fetch / git pull GET /info/refs + POST /git-upload-pack both
git push GET /info/refs + POST /git-receive-pack both
git ls-remote GET /info/refs GET /**

gh CLI / REST API (api.github.com)

Workflow HTTP call Rule Status
gh auth status, gh api user GET /user GET /**
gh repo view GET /repos/{o}/{r} GET /**
gh issue list / view GET /repos/{o}/{r}/issues[/{n}] GET /**
gh issue create POST /repos/{o}/{r}/issues POST /repos/*/*/issues
gh issue edit / gh issue close PATCH /repos/{o}/{r}/issues/{n} PATCH /repos/*/*/issues/*
gh issue comment POST /repos/{o}/{r}/issues/{n}/comments POST /repos/*/*/issues/*/comments
gh pr list / view GET /repos/{o}/{r}/pulls[/{n}] GET /**
gh pr create (branch) POST /repos/{o}/{r}/git/refs POST /repos/*/*/git/refs
gh pr create (PR) POST /repos/{o}/{r}/pulls POST /repos/*/*/pulls
gh pr edit / gh pr close PATCH /repos/{o}/{r}/pulls/{n} PATCH /repos/*/*/pulls/*
gh pr comment POST /repos/{o}/{r}/issues/{n}/comments (shared with issues) POST /repos/*/*/issues/*/comments
gh pr review --approve/--request-changes POST /repos/{o}/{r}/pulls/{n}/reviews POST /repos/*/*/pulls/*/reviews
gh pr review --request <user> POST /repos/{o}/{r}/pulls/{n}/requested_reviewers POST /repos/*/*/pulls/*/requested_reviewers
gh pr merge PUT /repos/{o}/{r}/pulls/{n}/merge PUT /repos/*/*/pulls/*/merge
gh release list / view GET /repos/{o}/{r}/releases GET /**
gh run list / view GET /repos/{o}/{r}/actions/runs GET /**
gh workflow run POST /repos/{o}/{r}/actions/workflows/{id}/dispatches POST /repos/*/*/actions/workflows/*/dispatches
File commit via Contents API PUT /repos/{o}/{r}/contents/{path} PUT /repos/*/*/contents/**
Ref update via API PATCH /repos/{o}/{r}/git/refs/heads/{branch} PATCH /repos/*/*/git/refs/**

Intentionally blocked (destructive / out-of-scope)

Workflow API call Reason
gh repo delete DELETE /repos/{o}/{r} DELETE not allowed
gh release delete DELETE /repos/{o}/{r}/releases/{id} DELETE not allowed
Force-delete branch via API DELETE /repos/{o}/{r}/git/refs/heads/{b} DELETE not allowed
gh repo create POST /user/repos Not in allow list (avoids agent creating arbitrary repos)
Branch protection changes PUT /repos/{o}/{r}/branches/{b}/protection Admin-only, intentionally not exposed

Checklist

  • Conventional commit format
  • Scoped to issue, no unrelated changes
  • No secrets or credentials
  • gh/git workflow validation documented above

Summary by CodeRabbit

  • Security Updates
    • Tightened network access to GitHub endpoints: enforce REST-only traffic with TLS termination.
    • Restricted allowed HTTP methods to essential reads and explicitly permitted write actions.
    • Limited write operations to specific pull-request, review, issue and repository content/ref endpoints; broader or destructive methods are disallowed.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 1, 2026

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

GitHub endpoints in nemoclaw-blueprint/policies/openclaw-sandbox.yaml were changed from access: full to protocol: rest with enforcement: enforce and tls: terminate, replacing broad TCP allow with L7 rules that allow GET /** and restrict write methods to specific git and PR/issue paths.

Changes

Cohort / File(s) Summary
Network Policy Configuration
nemoclaw-blueprint/policies/openclaw-sandbox.yaml
Replaced access: full for github.com:443 and api.github.com:443 with protocol: rest, enforcement: enforce, tls: terminate. Added L7 allow rules: git.832008.xyzGET /**, POST /**/git-upload-pack, POST /**/git-receive-pack; api.github.comGET /** plus enumerated POST/PATCH/PUT paths for PRs, reviews, requested reviewers, issues, comments, and targeted git refs/contents. Unlisted methods/paths are now disallowed.

Sequence Diagram(s)

sequenceDiagram
  participant Agent as Agent
  participant Proxy as OpenShell L7 Proxy
  participant GitAPI as api.github.com:443
  participant GitHost as github.com:443

  Agent->>Proxy: HTTPS request (method + path)
  Proxy-->>Proxy: Terminate TLS & inspect (protocol: rest, enforcement: enforce)
  alt request to api.github.com and allowed by rules
    Proxy->>GitAPI: Forward request
    GitAPI-->>Proxy: Response
    Proxy->>Agent: Return response
  else request to github.com and allowed by rules
    Proxy->>GitHost: Forward request
    GitHost-->>Proxy: Response
    Proxy->>Agent: Return response
  else denied by L7 rules
    Proxy->>Agent: Reject (403)
  end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

I’m a rabbit at the policy fence,
I hop through rules with careful sense,
GETs I munch, writes trimmed to track,
Only tidy paths let data back,
Safe burrows hum beneath the stack 🐇✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding protocol/enforcement/tls fields to GitHub endpoints as documented in the PR summary.
Linked Issues check ✅ Passed The PR implements the core requirements from #1111: replacing access:full with protocol:rest, enforcement:enforce, tls:terminate, and scoped method/path rules for both github.com and api.github.com.
Out of Scope Changes check ✅ Passed The changes are scoped to the GitHub endpoints in openclaw-sandbox.yaml and directly address #1111's objectives; npm_registry was intentionally deferred as a follow-up.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ 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.

@kjw3
Copy link
Copy Markdown
Contributor

kjw3 commented Apr 1, 2026

@latenighthackathon Thanks for working on this. I agree with the core direction here: #1111 is real, and moving the GitHub endpoints off access: full toward L7-enforced REST policies is the right goal.

I’m not comfortable merging this branch as written yet.

The main issue is that this changes the default GitHub policy behavior without validating that the narrowed method set still supports the expected gh and git workflows.

  • the PR changes both github.com and api.github.com to GET/POST only, which is a real behavior
    change, not just a dormant-policy fix
  • GitHub network policy should use protocol: rest to enable scoped method/path controls #1111 argues for more specific scoping, especially separating API traffic from git transport,
    rather than applying the same broad GET/POST /** shape to both hosts
  • there’s no validation here showing that the default workflows we expect to allow still work
    under this narrowed policy

If you want to get this re-reviewable, I’d suggest one of two paths:

If you respin it with that extra validation or tighter scoping, I’d be happy to take another look.

@wscurran wscurran added security Something isn't secure priority: high Important issue that should be resolved in the next release NemoClaw CLI Use this label to identify issues with the NemoClaw command-line interface (CLI). labels Apr 1, 2026
@wscurran
Copy link
Copy Markdown
Contributor

wscurran commented Apr 1, 2026

✨ Thanks for submitting this pull request, which proposes a way to improve the security of NemoClaw by adding protocol and enforcement rules for GitHub endpoints.

Possibly related open issues:

@wscurran wscurran added Provider: GitHub Integration: GitHub Use this label to identify GitHub integration issues with NemoClaw. and removed Provider: GitHub labels Apr 1, 2026
@latenighthackathon
Copy link
Copy Markdown
Contributor Author

@kjw3 Thanks for the detailed feedback — you're right that the original GET/POST shape was too narrow for api.github.com.

I've updated the PR to split the two hosts with different method scoping:

github.com — GET/POST only

  • git clone/fetch uses POST to /git-upload-pack and GET to /info/refs
  • git push uses POST to /git-receive-pack
  • No other methods needed for git transport

api.github.com — GET/POST/PATCH/PUT (DELETE excluded)

  • GET: read repos, issues, PRs, branches
  • POST: create issues, PRs, comments, releases
  • PATCH: update PR descriptions, issue labels, branch protection
  • PUT: merge PRs (PUT /repos/{owner}/{repo}/pulls/{number}/merge), update topics
  • DELETE excluded: blocks destructive ops (repo deletion, branch force-delete, org membership changes)

The gh CLI uses all four allowed methods in standard workflows. I verified against the GitHub REST API docs that the common agent operations (gh pr create, gh pr merge, gh issue edit, git push) are covered.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@nemoclaw-blueprint/policies/openclaw-sandbox.yaml`:
- Around line 110-125: The current api.github.com policy rules permit PATCH and
PUT on "/**" (see the rules block under host: api.github.com), which is overly
broad; replace those wildcard write rules with path-scoped entries that list
only the necessary mutable endpoints (for example restrict PATCH to specific
issue/PR endpoints like /repos/*/*/issues/* and /repos/*/*/pulls/* and restrict
PUT to allowed merge endpoints such as /repos/*/*/pulls/*/merge and any needed
review submission paths), keeping GET/POST as-is and ensuring no generic
PATCH/PUT "/**" remains so the policy enforces least privilege.
🪄 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: 69cad4cd-bf51-4c1e-92b3-ad0fb120c2d3

📥 Commits

Reviewing files that changed from the base of the PR and between b5e9453 and 7f168b3.

📒 Files selected for processing (1)
  • nemoclaw-blueprint/policies/openclaw-sandbox.yaml

Comment thread nemoclaw-blueprint/policies/openclaw-sandbox.yaml Outdated
@latenighthackathon
Copy link
Copy Markdown
Contributor Author

@kjw3 @coderabbitai Addressed the over-broad write scope feedback.

Changes:

github.com — POST now scoped to git transport only:

  • POST /**/git-upload-pack (clone/fetch)
  • POST /**/git-receive-pack (push)
  • GET remains unrestricted for ref discovery

api.github.com — writes scoped to PR/issue workflows:

  • POST /repos/*/*/pulls — create PRs
  • POST /repos/*/*/issues — create issues
  • POST /repos/*/*/issues/*/comments — comment on issues/PRs
  • POST /repos/*/*/pulls/*/reviews — submit PR reviews
  • PATCH /repos/*/*/pulls/* — update PRs
  • PATCH /repos/*/*/issues/* — update issues
  • PUT /repos/*/*/pulls/*/merge — merge PRs

DELETE remains excluded. PATCH/PUT no longer wildcard — scoped to the minimum set of mutable endpoints an AI agent needs for standard GitHub workflows.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 2, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

I'll look at the current policy file and verify the GitHub API path patterns before responding.


🏁 Script executed:

#!/bin/bash
# Look at the current YAML policy file
fd "openclaw-sandbox.yaml" --exec cat {}

Length of output: 7516


🌐 Web query:

GitHub REST API common agent workflows gh CLI endpoints method paths

💡 Result:

Below are common “agent” workflows on GitHub and the REST API method + path you typically call (plus the matching gh api shape).

Using gh api (mapping to REST)

  • gh api <path> defaults to GET, and becomes POST if you pass parameters; you can always force with --method. -f key=value sends form-style fields (JSON in request body). [1]

Example:

gh api --method POST repos/OWNER/REPO/issues -f title="Bug" -f body="Steps..."

[1]


Issues (triage, update, label, close)

  • List issues: GET /repos/{owner}/{repo}/issues [2]
  • Create issue: POST /repos/{owner}/{repo}/issues [2]
  • Get / update issue (incl. close via state=closed): GET|PATCH /repos/{owner}/{repo}/issues/{issue_number} [2]

Issue / PR conversation comments

  • Create comment: POST /repos/{owner}/{repo}/issues/{issue_number}/comments [3]
  • List comments: GET /repos/{owner}/{repo}/issues/{issue_number}/comments [3]

Pull requests (open, update, merge)

  • List PRs: GET /repos/{owner}/{repo}/pulls [4]
  • Create PR: POST /repos/{owner}/{repo}/pulls [4]
  • Get / update PR: GET|PATCH /repos/{owner}/{repo}/pulls/{pull_number} [4]
  • Merge PR: PUT /repos/{owner}/{repo}/pulls/{pull_number}/merge [4]

PR reviews (approve / request changes)

  • Create a review: POST /repos/{owner}/{repo}/pulls/{pull_number}/reviews [5]

Repository contents (read/write files for patches)

  • Get file/dir contents: GET /repos/{owner}/{repo}/contents/{path} [6]
  • Create/update file: PUT /repos/{owner}/{repo}/contents/{path} [6]

Git refs (create branches, move refs)

  • Create ref (branch/tag): POST /repos/{owner}/{repo}/git/refs [7]
  • Update ref (move branch): PATCH /repos/{owner}/{repo}/git/refs/{ref} [7]

Actions (trigger workflows, monitor runs)

  • List workflows: GET /repos/{owner}/{repo}/actions/workflows [8]
  • Run workflow (dispatch): POST /repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches [8]
  • Get run / cancel / rerun (common): GET|POST /repos/{owner}/{repo}/actions/runs/{run_id}/* (see workflow-runs endpoints) [9]

Checks / CI signals

  • Create/update check run: POST|PATCH /repos/{owner}/{repo}/check-runs [10]
  • Commit statuses (simple CI status):
    • Create status: POST /repos/{owner}/{repo}/statuses/{sha} [11]
    • Combined status: GET /repos/{owner}/{repo}/commits/{ref}/status [11]

Search (find relevant issues/PRs quickly)

  • Search issues & PRs: GET /search/issues [12]

Quick “agent loop” (typical sequence)

  1. Search or list issues/PRs → GET /search/issues / GET /repos/.../issues / GET /repos/.../pulls [12][2][4]
  2. Read context (thread + files) → GET /repos/.../issues/{n} + comments + contents [2][3][6]
  3. Push a change (file update / branch ref move) → PUT /contents/{path} and/or POST/PATCH /git/refs [6][7]
  4. Open/update PR + review/merge → pulls + reviews + merge [4][5]

Sources: GitHub CLI gh api manual [1]; GitHub REST docs for Issues [2], Issue comments [3], Pulls [4], Reviews [5], Contents [6], Git refs [7], Actions workflows [8], Workflow runs [9], Check runs [10], Commit statuses [11], Search [12].


@latenighthackathon This is a significant improvement over the original — the split between github.com and api.github.com and the scoped write rules are well-reasoned. A few points worth checking before this merges:


1. 🚨 Missing: Branch creation & file content writes

The web search confirms these are core to standard agent workflows:

Operation Required rule Currently covered?
Create feature branch POST /repos/*/*/git/refs ❌ No
Move/update a branch ref PATCH /repos/*/*/git/refs/* ❌ No
Create/update file via API PUT /repos/*/*/contents/** ❌ No

gh pr create will silently fail if it can't first create a branch via POST /repos/{owner}/{repo}/git/refs. Similarly, any agent using the contents API to commit file changes (rather than raw git push) needs the PUT /contents/** path. The double-star (**) matters here because file paths are multi-segment (e.g., /repos/owner/repo/contents/src/lib/foo.ts).

Suggested additions for api.github.com:

- allow: { method: POST, path: "/repos/*/*/git/refs" }
- allow: { method: PATCH, path: "/repos/*/*/git/refs/*" }
- allow: { method: PUT, path: "/repos/*/*/contents/**" }

2. ⚠️ Single-segment * doesn't cover sub-paths

PATCH /repos/*/*/pulls/* matches /repos/owner/repo/pulls/123 correctly, but not sub-paths like /repos/owner/repo/pulls/123/requested_reviewers. Requesting reviewers is a POST to that sub-path — which falls under your existing POST /repos/*/*/pulls/*/reviews... actually no, reviewer requests go to POST /repos/*/*/pulls/*/requested_reviewers, which is not listed. If reviewer assignment is needed, add:

- allow: { method: POST, path: "/repos/*/*/pulls/*/requested_reviewers" }

3. ℹ️ npm_registry still uses access: full

Issue #1111 specifically called out converting npm_registry to protocol: rest with GET-only. It's still using access: full in the current file — worth a follow-up issue or a small companion change here.


4. ✅ What looks good

  • github.com git transport scoping is correct — /**/git-upload-pack and /**/git-receive-pack handle repo-namespaced paths cleanly.
  • DELETE exclusion by omission is the right approach.
  • GET /** on api.github.com provides unrestricted reads without needing to enumerate every GET path.
  • The tls: terminate + enforcement: enforce combination aligns with all other REST endpoints in this file.

The branch/ref and contents gaps are the ones most likely to break a standard gh pr create → push → merge loop in practice. Everything else is a refinement.

@latenighthackathon
Copy link
Copy Markdown
Contributor Author

@coderabbitai Good catches — pushed a follow-up addressing all three gaps:

Added:

  • POST /repos/*/*/git/refs — branch creation (required for gh pr create)
  • PATCH /repos/*/*/git/refs/* — branch ref updates
  • PUT /repos/*/*/contents/** — file commits via contents API (double-star for multi-segment paths)
  • POST /repos/*/*/pulls/*/requested_reviewers — reviewer assignment

Also organized rules by workflow category (PR, issues, git ops) for readability.

Re: npm_registry still using access: full — agree that should be converted, will file a follow-up issue to keep this PR scoped.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 2, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

Let me verify the current state of the policy file before responding.


🏁 Script executed:

#!/bin/bash
fd "openclaw-sandbox.yaml" --exec cat {}

Length of output: 7935


@latenighthackathon Great updates overall — everything from the previous review is addressed. One small bug to fix before this is ready:


🚨 PATCH /repos/*/*/git/refs/* won't match any valid ref update

The GitHub API path for updating a ref is PATCH /repos/{owner}/{repo}/git/refs/{ref}, where {ref} is always multi-segment — e.g. heads/main, heads/feature/my-branch. A single * only matches one path segment, so:

  • /repos/owner/repo/git/refs/heads — ✅ matches (but not a valid API call)
  • /repos/owner/repo/git/refs/heads/main — ❌ does not match (this is the real call)

The fix is the same pattern used for PUT /repos/*/*/contents/**:

# Before
- allow: { method: PATCH, path: "/repos/*/*/git/refs/*" }

# After
- allow: { method: PATCH, path: "/repos/*/*/git/refs/**" }

This is consistent with how ** is already used elsewhere in this file (GET /**, /bot*/**, PUT /repos/*/*/contents/**).


Everything else looks solid:

  • POST /repos/*/*/git/refs — correct, posts to the collection endpoint
  • PUT /repos/*/*/contents/** — double-star correctly handles multi-segment file paths
  • POST /repos/*/*/pulls/*/requested_reviewers — correctly scoped
  • ✅ Workflow category comments improve readability

Re: the npm_registry follow-up — would you like me to open a GitHub issue for that now to track it? I can file it against the repo referencing this PR.

@latenighthackathon
Copy link
Copy Markdown
Contributor Author

@coderabbitai Good catch — pushed fix. PATCH /repos/*/*/git/refs/*/** to match multi-segment refs like heads/main and heads/feature/my-branch.

Re: npm_registry follow-up — yes, please go ahead and file the issue. Thanks!

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 2, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
gh issue create \
  --repo NVIDIA/NemoClaw \
  --title "fix(policy): convert npm_registry endpoint from access: full to protocol: rest (GET-only)" \
  --assignee latenighthackathon \
  --body "## Summary

The \`npm_registry\` endpoint in \`nemoclaw-blueprint/policies/openclaw-sandbox.yaml\` currently uses \`access: full\`, which causes the proxy to treat connections as L4-only. This prevents per-request rule evaluation, per-request logging, and SecretResolver credential injection.

## Proposed Change

Convert the \`npm_registry\` endpoint to use:
- \`protocol: rest\`
- \`enforcement: enforce\`
- \`tls: terminate\`
- Method restricted to \`GET /**\` only (npm registry reads are GET-only; no writes are expected from NemoClaw agents)

This aligns \`npm_registry\` with the pattern established for other external REST endpoints in the policy file (e.g., \`github.com\`, \`api.github.com\` after PR `#1225`).

## Motivation

- Issue `#1111` explicitly called out converting \`npm_registry\` as a related change alongside the GitHub endpoints.
- This was discussed and agreed upon during review of PR `#1225` but deferred to keep that PR scoped.

## References

- Raised during review of: https://github.com/NVIDIA/NemoClaw/pull/1225
- Related issue: https://github.com/NVIDIA/NemoClaw/issues/1111
- Requested by: `@latenighthackathon`"

Length of output: 53


🏁 Script executed:

#!/bin/bash
gh issue create \
  --repo NVIDIA/NemoClaw \
  --title "fix(policy): convert npm_registry endpoint from access: full to protocol: rest (GET-only)" \
  --body "## Summary

The \`npm_registry\` endpoint in \`nemoclaw-blueprint/policies/openclaw-sandbox.yaml\` currently uses \`access: full\`, which causes the proxy to treat connections as L4-only. This prevents per-request rule evaluation, per-request logging, and SecretResolver credential injection.

## Proposed Change

Convert the \`npm_registry\` endpoint to use:
- \`protocol: rest\`
- \`enforcement: enforce\`
- \`tls: terminate\`
- Method restricted to \`GET /**\` only (npm registry reads are GET-only; no writes are expected from NemoClaw agents)

This aligns \`npm_registry\` with the pattern established for other external REST endpoints in the policy file (e.g., \`github.com\`, \`api.github.com\` after PR `#1225`).

## Motivation

- Issue `#1111` explicitly called out converting \`npm_registry\` as a related change alongside the GitHub endpoints.
- This was discussed and agreed upon during review of PR `#1225` but deferred to keep that PR scoped.

## References

- Raised during review of: https://github.com/NVIDIA/NemoClaw/pull/1225
- Related issue: https://github.com/NVIDIA/NemoClaw/issues/1111
- Requested by: `@latenighthackathon`"

Length of output: 46


@latenighthackathon Confirmed — the PATCH /repos/*/*/git/refs/** fix is exactly right. That's now the last open item from this review thread resolved.

Filed the npm_registry follow-up: #1355 — tracked against this PR and #1111 for context.

With that, all the items raised in this review are addressed:

  • PATCH /repos/*/*/git/refs/** — wildcard fixed for multi-segment refs
  • POST /repos/*/*/git/refs — branch creation
  • PUT /repos/*/*/contents/** — file commits via contents API
  • POST /repos/*/*/pulls/*/requested_reviewers — reviewer assignment
  • npm_registry follow-up tracked in #1355

This should be in good shape for @kjw3 to take another look. 🐇

@latenighthackathon
Copy link
Copy Markdown
Contributor Author

@kjw3 Thanks for the patience on this one — I've taken another pass addressing both of your asks.

1. Scoping (per #1111): Split github.com from api.github.com so each host gets the minimum method set it needs:

  • github.com — git transport only (POST scoped to /git-upload-pack and /git-receive-pack, no broad POST)
  • api.github.com — REST writes scoped to specific PR/issue/refs/contents endpoints; no PATCH /** or PUT /** anywhere
  • DELETE excluded from both, blocking destructive ops (repo deletion, force-delete, org changes)

2. Workflow validation: Updated the PR body with a full mapping table — each common gh and git workflow → API endpoint → which rule covers it. Covers git clone/fetch/push/ls-remote, plus the gh CLI surface for repos/issues/PRs/reviews/releases/runs/workflow dispatch. Also added POST /repos/*/*/actions/workflows/*/dispatches for gh workflow run which I caught while building the table.

Also rebased onto current main while I was in there — clean linear history now. Happy to take another round if you see anything missed.

ericksoa pushed a commit that referenced this pull request Apr 7, 2026
…1358)

## Summary

- Replace L4 pass-through (`access: full`) on `npm_registry` endpoint
with L7-enforced REST policy restricted to `GET /**`
- Agents only fetch packages from the npm registry and never publish, so
write methods are not needed
- Enables per-request rule evaluation, per-request logging, and
SecretResolver credential injection

## Motivation

- Issue #1111 called out converting `npm_registry` alongside the GitHub
endpoints
- Discussed and agreed upon during review of PR #1225 but deferred to
keep that PR scoped
- CodeRabbit filed #1355 to track this follow-up

## Test plan

- [ ] Verify `openclaw plugins install` succeeds with GET-only policy
- [ ] Verify `npm install` inside sandbox completes normally
- [ ] Confirm write attempts (e.g. `npm publish`) are blocked by the
policy

Closes #1355

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

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

* **Security**
* Registry access is now read-only (HTTP GET only) and TLS termination
is enforced for registry connections, tightening network access and
transport security for package registry interactions.
<!-- 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>
@latenighthackathon latenighthackathon force-pushed the fix/github-policy-protocol branch from 3106014 to 334be03 Compare April 10, 2026 03:18
gemini2026 pushed a commit to gemini2026/NemoClaw that referenced this pull request Apr 14, 2026
…VIDIA#1358)

## Summary

- Replace L4 pass-through (`access: full`) on `npm_registry` endpoint
with L7-enforced REST policy restricted to `GET /**`
- Agents only fetch packages from the npm registry and never publish, so
write methods are not needed
- Enables per-request rule evaluation, per-request logging, and
SecretResolver credential injection

## Motivation

- Issue NVIDIA#1111 called out converting `npm_registry` alongside the GitHub
endpoints
- Discussed and agreed upon during review of PR NVIDIA#1225 but deferred to
keep that PR scoped
- CodeRabbit filed NVIDIA#1355 to track this follow-up

## Test plan

- [ ] Verify `openclaw plugins install` succeeds with GET-only policy
- [ ] Verify `npm install` inside sandbox completes normally
- [ ] Confirm write attempts (e.g. `npm publish`) are blocked by the
policy

Closes NVIDIA#1355

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

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

* **Security**
* Registry access is now read-only (HTTP GET only) and TLS termination
is enforced for registry connections, tightening network access and
transport security for package registry interactions.
<!-- 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>
@cv cv added the v0.0.16 Release target label Apr 14, 2026
@wscurran wscurran added status: rebase PR needs to be rebased against main before review can continue enhancement: integration PRs or issues proposing integration of a third-party product or service into NemoClaw. labels Apr 14, 2026
Replace access: full with scoped L7 rules in the github preset (moved
from base policy to presets/github.yaml by NVIDIA#1583).  github.com gets
GET + POST scoped to git-upload-pack / git-receive-pack.  api.github.com
gets GET + PR/issue/refs/contents writes; DELETE excluded to block
destructive ops.

Closes NVIDIA#1111

Signed-off-by: latenighthackathon <latenighthackathon@users.noreply.github.com>
@latenighthackathon latenighthackathon force-pushed the fix/github-policy-protocol branch from 05f1abc to cc197a7 Compare April 14, 2026 22:51
@latenighthackathon
Copy link
Copy Markdown
Contributor Author

@wscurran Thanks for the kind words on the hardening approach. Rebased onto latest origin/main — single clean commit (cc197a7b) against the current presets/github.yaml location. Ready for another look whenever you have a moment.

Cheers!

@ericksoa
Copy link
Copy Markdown
Contributor

Great work on this — the move from access: full to scoped L7 rules is exactly the right direction, and the workflow validation table is thorough.

One thing I've been thinking about: what happens when an agent inside the sandbox needs to create a release, fork a repo, or manage labels? Those are pretty common in day-to-day workflows, and they'd silently fail under the current allowlist since only GET covers them.

Could you take a look at adding scoped rules for these? The same pattern you're already using works perfectly:

# Releases
- allow: { method: POST, path: "/repos/*/*/releases" }
- allow: { method: PATCH, path: "/repos/*/*/releases/*" }
# Forks
- allow: { method: POST, path: "/repos/*/*/forks" }
# Labels
- allow: { method: POST, path: "/repos/*/*/labels" }
- allow: { method: PATCH, path: "/repos/*/*/labels/*" }
# Milestones
- allow: { method: POST, path: "/repos/*/*/milestones" }
- allow: { method: PATCH, path: "/repos/*/*/milestones/*" }
# PR update-branch
- allow: { method: PUT, path: "/repos/*/*/pulls/*/update-branch" }

The nice thing is this doesn't change the security posture you've built — still L7, still no DELETE, still path-scoped. It just makes the allowlist complete enough that agents won't hit unexpected denials during normal work.

What do you think — does that feel right, or did you intentionally leave some of these out?

@wscurran wscurran removed the status: rebase PR needs to be rebased against main before review can continue label Apr 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement: integration PRs or issues proposing integration of a third-party product or service into NemoClaw. Integration: GitHub Use this label to identify GitHub integration issues with NemoClaw. NemoClaw CLI Use this label to identify issues with the NemoClaw command-line interface (CLI). priority: high Important issue that should be resolved in the next release security Something isn't secure v0.0.16 Release target

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GitHub network policy should use protocol: rest to enable scoped method/path controls

5 participants