Skip to content

fix(state): keep the confidentiality root traversable by the sandbox group - #7603

Merged
apurvvkumaria merged 18 commits into
mainfrom
fix/7545-confidentiality-dir-traversal
Aug 5, 2026
Merged

fix(state): keep the confidentiality root traversable by the sandbox group#7603
apurvvkumaria merged 18 commits into
mainfrom
fix/7545-confidentiality-dir-traversal

Conversation

@Dongni-Yang

@Dongni-Yang Dongni-Yang commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Summary

With shields up, the state-dir guard locked the confidentiality directories (credentials, identity, pairing) to root:root 700, so OpenClaw's startup lstat of the optional legacy credentials/oauth.json failed with EACCES instead of ENOENT — the gateway restart then failed with GATEWAY_HEALTH_TIMEOUT and Telegram dispatch kept retrying (#7545). Lock now sets only the confidentiality root to root:sandbox 710 (group execute, no read): a probe for a missing top-level name resolves as missing, while the directory stays unlistable and nested directories and every file keep the sealed root:root posture with no group or world bits.

Related Issue

Closes #7545 — together with #7602 (the sessions-carveout half, Refs), this resolves both filed symptoms. If this PR merges first, #7602 still tracks the remaining EACCES: mkdir agents/main/sessions symptom on the issue's thread.

Changes

  • scripts/state-dir-guard.py: an is_confidentiality_root flag threads through _expected_ids, _expected_dir_mode, _set_dir_metadata, _verify_metadata, and _verify_dir. During lock, the mutation pass and the independent verification pass both expect root:sandbox 710 on the confidentiality root and the unchanged root:root 700 on nested confidentiality directories. Confidentiality file modes and ownership are untouched (old_mode & 0o700, root:root), so the live E2E contract for locked credential files (uid 0, gid 0, 0600 in test/e2e/live/state-dir-guard-metadata.test.ts) holds without modification. Scoping the group-execute bit to the root keeps the widened surface to one directory level of known-name metadata — resolving the oauth.json probe needs search permission on credentials/ alone.
  • test/state-dir-guard.test.ts: the distinct-modes test now pins the root at 0o710 and a nested credentials/providers/ directory at 0o700; a new driver runs the guard with a distinct sandbox gid (a supplementary group of the current user, skipped when none exists) and asserts the group ownership lands only on the confidentiality root, not on nested directories or files. Both fail on the pre-change guard.
  • test/e2e/live/state-dir-guard-metadata.test.ts: the real container probe asserts a distinct sandbox-group member gets ENOENT for a missing direct child while root listing, nested traversal, and secret reads all remain EACCES.
  • docs/security/best-practices.mdx: the secret-bearing-directories paragraph now states the root/nested split, the known-name metadata visibility, and the missing-probe behavior.

Type of Change

  • Code change (feature, bug fix, or refactor)
  • Code change with doc updates
  • Doc only (prose changes, no code sample modifications)
  • Doc only (includes code sample changes)

Quality Gates

  • Tests added or updated for changed behavior
  • Existing tests cover changed behavior — justification:
  • Tests not applicable — justification:
  • Docs updated for user-facing behavior changes
  • Docs not applicable — justification:
  • Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging)
  • Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: nine-category security review passed for commit 2dd194dd5; the current-main merge did not change the effective PR diff. No secrets, dependency, authentication, cryptography, network, or logging surface was added. The root-only 0710 scope is mirrored by independent verification and negative traversal and read tests.
  • Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue:

Documentation Writer Review

  • Documentation writer subagent reviewed the completed changes
  • Result: docs-updated
  • Evidence: docs/security/best-practices.mdx accurately documents the confidentiality-root behavior for OpenClaw and Hermes. The independent review covered commit 2dd194dd5, passed the docs build with 0 errors, verified the generated OpenClaw and Hermes variants, confirmed the guidance is absent from the Deep Agents variant, and passed git diff --check.
  • Agent: Codex Desktop documentation writer subagent

DGX Station Hardware Evidence

  • Tested on DGX Station
  • Tested commit:
  • Station profile/scenario:
  • Result:
  • Supporting evidence:

Verification

  • PR description includes a Signed-off-by: line and every commit appears as Verified in GitHub
  • Normal pre-commit, commit-msg, and pre-push hooks passed, or npm run validate:pr passed after refreshing origin/main when hooks were skipped or unavailable
  • Targeted behavior tests pass for the current change set, or tests are marked not applicable above — command/result or justification: npx vitest run --project integration test/state-dir-guard.test.ts → 31 passed / 1 host-capability skip; disposable Linux DAC probe confirmed root root:sandbox 0710, nested directory root:root 0700, secret root:root 0600, direct-child ENOENT, and listing/nested/read EACCES; npm run typecheck:cli, npm run docs, and npx prek run --from-ref origin/main --to-ref HEAD passed
  • Applicable broad gate passed — npm test for broad runtime/test-harness changes; npm run check for repo-wide validation/coverage changes — command/result:
  • Quality Gates section completed with required justifications or waivers
  • No secrets, API keys, or credentials committed
  • npm run docs builds without warnings (doc changes only)
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Signed-off-by: Dongni Yang dongniy@nvidia.com

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Security
    • Updated lockdown behavior for secret-bearing confidentiality directories: the confidentiality root is now set to root:sandbox with restricted directory permissions, while nested directories and files are locked to root:root with no group/world access.
    • Probes now report missing immediate entries as “missing” rather than permission failures.
  • Bug Fixes
    • Improved metadata verification to treat the confidentiality root differently from nested confidentiality entries.
  • Tests
    • Expanded unit and e2e coverage, including nested permission checks and new confidentiality-root access evidence.
  • Documentation
    • Refreshed security best practices to match the updated lockdown rules.

…group

With shields up, the state-dir guard locked the confidentiality
directories (credentials, identity, pairing) to root:root 700. OpenClaw
probes the optional legacy credentials/oauth.json at startup; with a
non-traversable parent the lstat fails with EACCES instead of ENOENT,
the gateway restart fails with GATEWAY_HEALTH_TIMEOUT, and Telegram
dispatch keeps retrying the queued update.

Lock now sets the confidentiality root to root:sandbox 710. Group
execute without read lets a sandbox probe for a missing name directly
under the root resolve as missing while the directory stays unlistable.
Nested directories and every file keep the sealed root:root posture
with no group or world permission bits. Contents and the subtree shape
stay unreadable; the widened surface is one directory level of
known-name metadata. The live E2E contract for locked credential files
(uid 0, gid 0, 0600) is unchanged.

Refs #7545

Signed-off-by: Dongni Yang <dongniy@nvidia.com>
@Dongni-Yang Dongni-Yang added the area: security Security controls, permissions, secrets, or hardening label Jul 27, 2026
@Dongni-Yang Dongni-Yang self-assigned this Jul 27, 2026
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

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

The confidentiality lock workflow now assigns distinct metadata to protected root directories and nested secret content, propagates root context during verification, adds group-ID and access-contract tests, and updates lockdown documentation.

Changes

Confidentiality root locking

Layer / File(s) Summary
Confidentiality metadata contract and mutation
scripts/state-dir-guard.py
Expected ownership and directory modes now distinguish confidentiality roots, and lock mutations pass the root-specific context.
Root-aware metadata verification
scripts/state-dir-guard.py
Verification propagates root context through directory traversal and validates the special confidentiality-root mode.
Behavior validation and access contract
test/state-dir-guard.test.ts, test/e2e/live/state-dir-guard-metadata.test.ts, docs/security/best-practices.mdx
Tests cover nested secret entries, distinct group ownership, denied access, missing-entry behavior, and the updated lockdown permissions documented for confidentiality roots.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant StateDirGuard
  participant LockedCredentials
  participant ConfidentialityProbe
  StateDirGuard->>LockedCredentials: apply root and nested metadata
  ConfidentialityProbe->>LockedCredentials: probe missing child, listing, traversal, and secret read
  LockedCredentials-->>ConfidentialityProbe: return ENOENT or EACCES evidence
  ConfidentialityProbe-->>StateDirGuard: report UID, GID, mode, and errno evidence
Loading

Suggested labels: bug-fix, area: e2e, platform: container

Suggested reviewers: cv

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the primary change: allowing the sandbox group to traverse confidentiality root directories.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/7545-confidentiality-dir-traversal

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

@github-code-quality

github-code-quality Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in commit 2dd194d in the fix/7545-confidentia... branch remains at 96%, unchanged from commit 962f1c3 in the main branch.

TypeScript / code-coverage/cli

The overall coverage in commit 2dd194d in the fix/7545-confidentia... branch remains at 81%, unchanged from commit 962f1c3 in the main branch.


Updated August 05, 2026 05:30 UTC

@github-actions

Copy link
Copy Markdown
Contributor

@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

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/security/best-practices.mdx`:
- Around line 300-303: Rewrite the four sentences in the secret-directory
behavior description using direct second-person wording and active present
tense, addressing the reader as “you” while preserving the existing permissions,
visibility, metadata, and missing-path behavior.
🪄 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: Enterprise

Run ID: e708883c-dc92-4c87-ac2c-d51c3c6278d6

📥 Commits

Reviewing files that changed from the base of the PR and between fdf14f5 and 1b2495e.

📒 Files selected for processing (3)
  • docs/security/best-practices.mdx
  • scripts/state-dir-guard.py
  • test/state-dir-guard.test.ts

Comment thread docs/security/best-practices.mdx Outdated
@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — No blocking findings reported

Advisor assessment: No blocking advisor findings reported
Next action: No advisor follow-up needed.
Findings: 0 blockers · 0 warnings · 0 suggestions

Model lanes

  • GPT-5.6 Terra (primary): Completed · high confidence · 0 blockers · 0 warnings · 0 suggestions
  • Nemotron 3 Ultra (second opinion): Completed · high confidence · 0 blockers · 3 warnings · 3 suggestions
  • Model comparison: normalized findings differ; normalized terminology decisions differ; normalized E2E selections match; Nemotron reported the same number of blockers, 3 more warnings, 3 more suggestions.
4 terminology differences from the second opinion

Advisory only. These are normalized differences from the primary terminology receipt.

  • confidentiality root at docs/security/best-practices.mdx:301: primary classified it as established; the second opinion classified it as define.
  • known-name at docs/security/best-practices.mdx:355: selected only by the second-opinion lane as justified.
  • traversable at docs/security/best-practices.mdx:354: selected only by the second-opinion lane as justified.
  • unlistable at docs/security/best-practices.mdx:354: selected only by the second-opinion lane as define.

Second-opinion terminology and E2E selections are advisory. They do not change the primary assessment or E2E / PR Gate.

3 semantic terminology decisions

Terminology decisions are advisory. They affect the assessment only when a separate finding identifies concrete semantic impact.

  • established — confidentiality root at docs/security/best-practices.mdx:301: Keep `confidentiality root` for the direct protected root and distinguish it from nested confidentiality entries.
  • justified — known-name probe at docs/security/best-practices.mdx:355: Keep `known-name probe` with the stated direct-child contrast and errno outcomes.
  • established — sealed posture at scripts/state-dir-guard.py:905: Keep `sealed posture` for the existing restrictive descendant metadata contract.

E2E guidance

Advisory only. E2E / PR Gate selects and runs jobs independently.

Recommended E2E: cloud-inference, cloud-onboard, managed-image-multiarch-startup, security-posture

Workflow run details

This automated review informs maintainers. Warnings and suggestions do not require a response. A maintainer decides whether to merge.

@Dongni-Yang

Copy link
Copy Markdown
Contributor Author

On advisor warning PRA-1 (non-owner access probes): the unit harness cannot model a second UID — its stub identity maps root and sandbox to the current user, which is why the changed tests pin the posture (modes and the gid split via a supplementary group) rather than access behavior. The observable access contract is partially covered in the live lane already: test/e2e/live/state-dir-guard-metadata.test.ts probes read/write denial of a locked credentials file as a named non-owner user (expectNamedUserAccessState, locked → credentials: { read: false, write: false }). The delta the warning asks for — lstat of an absent credentials/oauth.json → ENOENT, readdir(credentials) → EACCES, nested traversal → EACCES, as a sandbox-group member — belongs in that live target next to the existing probes. I did not extend it in this PR because the e2e-live lane cannot be exercised locally and I did not want to land unverified assertions in the pre-tag lane; happy to add the probes here if a maintainer prefers them in this change, or as a follow-up.

Signed-off-by: Dongni Yang dongniy@nvidia.com

@apurvvkumaria apurvvkumaria self-assigned this Jul 27, 2026
apurvvkumaria and others added 3 commits July 26, 2026 20:28
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
@copy-pr-bot

copy-pr-bot Bot commented Jul 27, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@prekshivyas

Copy link
Copy Markdown
Collaborator

/ok to test 4bbfa71

Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
@cv

cv commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Maintainer gate snapshot for v0.0.96:

  • exact head: b946e51157da6b1b32dfa7286eee359c55a9e4a4
  • recorded base: 77e6e388c350a27d81f811c6ff67b8e4c1bb18bd
  • current main: 921e1b0fff778343cfbe3c1daae91bb56c0bfa14
  • current-main merge tree: clean
  • DCO / commit verification: all 7 commits verified
  • CodeRabbit: no unresolved actionable thread

The canonical merge gate blocks approval while the branch is behind, and this PR does not allow maintainer edits. Please merge current main into the branch normally (no rebase or force-push), refresh the exact-head docs/security/test receipts, and let the fresh required CI/E2E complete. I will resume the security and merge review on that new head.

Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
cv pushed a commit that referenced this pull request Jul 28, 2026
<!-- markdownlint-disable MD041 -->
## Summary
<!-- 1-3 plain sentences: what changes and why. Describe
before-and-after behavior when it applies. Follow the NemoClaw Writing
Guide: https://github.com/NVIDIA/NemoClaw/blob/main/WRITING.md. Do not
add unrelated prose cleanup. -->
Replace the mutable NodeSource bootstrap in both WSL workflows with
checksum-verified official Node.js 22.23.1 archives. This removes the
shared installer failure affecting current PR lanes while keeping the
runtime on the supported, security-current Node 22 LTS line.

## Changes
<!-- List concrete changes. If this adds an abstraction, configuration,
fallback, migration, or compatibility path, name its current requirement
and consumer, explain why a direct change is insufficient, and identify
the test that protects it. -->
- Install official Node.js 22.23.1 archives for `x64` and `arm64`, with
exact SHA-256 pins, HTTPS-only bounded downloads, temporary-directory
cleanup, and fail-closed architecture handling.
- Verify each archive before extraction and assert the installed runtime
version.
- Protect both workflow consumers with
`test/platform-vitest-main-workflow.test.ts`, including
architecture-to-digest bindings and the repository's approved security
source-shape contract.
- Address the same WSL bootstrap failure observed on
[#7590](https://github.com/NVIDIA/NemoClaw/actions/runs/30312091098/job/90131121904),
[#7629](https://github.com/NVIDIA/NemoClaw/actions/runs/30311922489/job/90131122471),
[#7603](https://github.com/NVIDIA/NemoClaw/actions/runs/30311696352/job/90131123359),
and
[#7626](https://github.com/NVIDIA/NemoClaw/actions/runs/30312801807/job/90132378380).

## Type of Change

- [x] Code change (feature, bug fix, or refactor)
- [ ] Code change with doc updates
- [ ] Doc only (prose changes, no code sample modifications)
- [ ] Doc only (includes code sample changes)

## Quality Gates
<!-- Check one tests line and one docs line. Check other lines when
applicable. Add every requested justification or approval reference. -->
- [x] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [ ] Tests not applicable — justification:
- [ ] Docs updated for user-facing behavior changes
- [x] Docs not applicable — justification: This changes internal CI
bootstrap behavior only; public installation requirements remain
unchanged.
- [x] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [x] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification: Codex security review
PASS across all nine categories on exact diff fingerprint
`2981cff1a79a0c0acfaf5b0a8e55353809ec472c0565fa1f168996f92107b7ae`.
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Documentation Writer Review
<!-- Required for code and documentation changes after the changes and
applicable validation are complete. Keep one review checkbox and one
instance of each visible or hidden field. For Evidence, list changed
documentation paths. For documentation-only changes, also state that the
writing rules and documentation style were reviewed. For other results,
explain why no documentation change is needed or why the review is
blocked. For Agent, use a consistent product and surface name, such as
Codex Desktop, Codex CLI, Claude Code, or Cursor. After committing all
review changes, put `git rev-parse --short HEAD` and `git rev-parse
--short HEAD:AGENTS.md` in the hidden metadata below. Rerun the review
and refresh that metadata after any new commit. This receipt is advisory
during the data-collection pilot. -->
- [x] Documentation writer subagent reviewed the completed changes
- Result: `no-docs-needed`
- Evidence: Exact-head review confirmed the change is limited to CI
bootstrap workflows and their executable contract; public Node.js
requirements do not change.
- Agent: Codex Desktop
<!-- docs-review-head-sha: 062779c -->
<!-- docs-review-agents-blob-sha: be20a09 -->

## DGX Station Hardware Evidence
<!-- Required only when scripts/prepare-dgx-station-host.sh changes.
Maintainers must review the linked evidence before approving or merging.
This is human-reviewed evidence, not authenticated hardware provenance.
Exceptional bypasses use existing repository governance and must be
documented on the PR. -->
- [ ] Tested on DGX Station
- Tested commit:
- Station profile/scenario:
- Result:
- Supporting evidence:

## Verification
<!-- Check each applicable item only when supported by the requested
evidence. Run targeted tests once per relevant change set and rerun
after later edits or hook autofixes that can affect the tested behavior.
Do not rerun hook-covered checks. -->
- [x] PR description includes a `Signed-off-by:` line and every commit
appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run check:diff` passed when hooks were skipped or unavailable
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — command/result or justification: `npx
vitest run --project integration
test/platform-vitest-main-workflow.test.ts` (3 passed); both embedded
WSL installers pass `bash -n`.
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result:
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only)
- [ ] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)

---
<!-- DCO sign-off is required in this PR description, and every commit
must appear as Verified in GitHub. Run: git config user.name && git
config user.email -->
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>


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

## Summary by CodeRabbit

* **CI Improvements**
* Standardized Node.js 22 installation across WSL workflows with a
pinned version and architecture-specific downloads.
* Added archive checksum verification, version validation, cleanup, and
explicit failure handling.

* **Tests**
* Added coverage to verify secure, deterministic Node.js installation
behavior in both WSL workflows.

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

---------

Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
@cjagwani cjagwani added v0.0.98 and removed v0.0.97 labels Jul 28, 2026
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
@cjagwani

Copy link
Copy Markdown
Collaborator

Babysitting status for exact head 2e236bf (plain comment; no Changes Requested review from me): the deterministic gate currently reports a failed E2E / PR Gate, pending E2E coordination, and a stale base c4c020c versus current main da1b103. Maintainer edits are disabled. Please refresh and obtain clean exact-head E2E evidence; I will re-gate the next head after its one-hour quiet window.

@cjagwani

Copy link
Copy Markdown
Collaborator

Correction to my prior handoff: conflict-free base refreshes are explicitly waived. Please do not merge main solely for base currency; preserving exact-head evidence is preferred unless GitHub reports a real conflict or reviewed behavior requires a change. The substantive blocker or missing evidence described in the earlier handoff remains, but base age by itself is not a blocker. This is a plain coordination comment, not Changes Requested.

@cjagwani

Copy link
Copy Markdown
Collaborator

@cv @ericksoa — this exact head is still blocked only on the legacy protected-environment E2E authorization. GitHub lists you as the authorized reviewers and reports that my account cannot approve it. Please open controller run 30401679121 and approve the pending approve-credentialed-e2e-for-internal-pr deployment for PR head 2e236bf582bafacde65e538a26c15a0ff35673ee, base c4c020ca561bacadd3aa309ba5dffef7e5aa09ed, plan 260f9489649ccfab505e93ca3835082ec7caff837af961286f0c3bf5cd280419 (selected: cloud-inference, cloud-onboard, security-posture). This is a coordination comment, not Changes Requested; no branch refresh is requested.

apurvvkumaria and others added 4 commits July 31, 2026 10:34
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>

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

Security review PASS for revision c2553b7. Categories reviewed: secrets, input validation, authorization and filesystem authority, dependencies, logging, cryptography, configuration, tests, and failure modes. Traversal-only group access is limited to each confidentiality root; roots remain unlistable, descendants remain root-only, and negative tests preserve denial of nested traversal and secret reads. The current-main synchronization is conflict-free and does not alter the feature boundary. Python compilation, focused tests, CLI build and type checks, repository checks, documentation validation, commit hooks, and pre-push hooks pass. No findings remain; required CI must still complete before merge.

Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
@apurvvkumaria
apurvvkumaria enabled auto-merge (squash) August 4, 2026 00:20
apurvvkumaria added a commit that referenced this pull request Aug 4, 2026
<!-- markdownlint-disable MD041 -->
## Summary
<!-- 1-3 plain sentences: what changes and why. Describe
before-and-after behavior when it applies. Follow the NemoClaw Writing
Guide: https://github.com/NVIDIA/NemoClaw/blob/main/WRITING.md. Do not
add unrelated prose cleanup. -->
After a rebuild or manual relock, an OpenClaw sandbox whose
already-locked `.config-hash` had been re-permissioned by an in-sandbox
reconciler (perms only, bytes intact) failed the relock and split: host
shields reported UNLOCKED while the in-container state dirs stayed
root-locked, breaking skill install and agent turns with no clean
recovery. The already-locked lock transition now re-seals that
perms-only drift in place instead of failing closed, and the host prints
`Re-sealed a perms-only config-lock drift` so the self-heal is visible;
content or structural drift still fails closed.

## Related Issue
<!-- Fixes #NNN or Closes #NNN. Remove this section if none. -->
Parts of #7985 — fixes the rebuild config-lock drift/split (status
UNLOCKED but state dirs stay locked). The credentials-traversal EACCES
symptom in #7985 is handled separately by #7603 (#7545) and is not
closed here.
Refs #4663 (relock settle-window family), #7629 (unlock-side idempotency
precedent).

## Changes
<!-- List concrete changes. If this adds an abstraction, configuration,
fallback, migration, or compatibility path, name its current requirement
and consumer, explain why a direct change is insufficient, and identify
the test that protects it. -->
- `scripts/openclaw-config-guard.py`: `_transition("lock")` now repairs
only the recognized sidecar-permission drift after `_snapshot_pair`
proves the stored digest still matches the configuration bytes. Recovery
additionally requires `openclaw.json` to remain `root:root 0444` with no
blocking inode flags and `.config-hash` to be exactly `sandbox:sandbox
0660` with no blocking flags. Writable configuration, content drift,
structural drift, unknown metadata, and flagged files still fail closed.
The guard also emits a `resealedDrift` result flag.
- Recovery-path requirement and consumer: the closing relock
(`relockAndReconfirm` via the rebuild's `activateLockdownFromSnapshot`
and `shields up` drift-repair) re-confirms an already-locked config
whose `.config-hash` was re-permissioned by the upstream in-sandbox
OpenClaw gateway/doctor perm-normalizer. NemoClaw does not own that
writer, so a direct source fix is out of scope here; the
host-authenticated relock re-seal is the correct defense layer. Removal
condition documented inline: delete the path once the lock is durably
immutable on every platform (chattr +i, unavailable on overlayfs today)
or the upstream reconciler stops re-permissioning a locked config.
Protected by `test/openclaw-config-guard-lock-reseal.test.ts` and the
live e2e phase below.
- `src/lib/shields/openclaw-config-lock.ts`: parse and validate the new
`resealedDrift` boolean from the guard result.
- `src/lib/shields/index.ts`: `transitionOpenClawTopConfig` prints the
host-visible re-seal line when the guard reports `resealedDrift`, so a
rebuild or relock no longer repairs drift invisibly.
- Tests: the guard-posture harness uses realistic file snapshots and the
real classifier for the recoverable sidecar posture,
writable-configuration rejection, content and structural rejection,
unrelated errors, and clean verification. Parser coverage validates the
result flag, and the live E2E phase drives real sidecar permission drift
through `shields up`.

## Type of Change

- [x] Code change (feature, bug fix, or refactor)
- [ ] Code change with doc updates
- [ ] Doc only (prose changes, no code sample modifications)
- [ ] Doc only (includes code sample changes)

## Quality Gates
<!-- Check one tests line and one docs line. Check other lines when
applicable. Add every requested justification or approval reference. -->
- [x] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [ ] Tests not applicable — justification:
- [ ] Docs updated for user-facing behavior changes
- [x] Docs not applicable — justification: bug fix restores the intended
`shields up`/relock success on perms-only drift; no documented
CLI/API/config contract changes. The added line is diagnostic output.
- [x] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [x] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification: Nine-category security
review PASS:
#8086 (review)
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Documentation Writer Review
<!-- Required for code and documentation changes after the changes and
applicable validation are complete. Keep one review checkbox and one
instance of each visible or hidden field. For Evidence, list changed
documentation paths. For documentation-only changes, also state that the
writing rules and documentation style were reviewed. For other results,
explain why no documentation change is needed or why the review is
blocked. For Agent, use a consistent product and surface name, such as
Codex Desktop, Codex CLI, Claude Code, or Cursor. After committing all
review changes, put `git rev-parse --short HEAD` and `git rev-parse
--short HEAD:AGENTS.md` in the hidden metadata below. Rerun the review
and refresh that metadata after any new commit. This receipt is advisory
during the data-collection pilot. -->
- [x] Documentation writer subagent reviewed the completed changes
- Result: `no-docs-needed`
- Evidence: Reviewed `docs/manage-sandboxes/runtime-controls.mdx`,
`docs/reference/troubleshooting.mdx`, `docs/reference/commands.mdx`,
`docs/manage-sandboxes/recover-rebuild-sandboxes.mdx`, and
`docs/security/best-practices.mdx`. The latest follow-up changes only
the test harness so it exercises the real permission classifier with
realistic config and hash snapshots. It confirms that writable config is
rejected and does not change runtime behavior, diagnostic output,
commands, flags, configuration, policy, operator actions, or migration
guidance.
- Agent: Codex Desktop
<!-- docs-review-head-sha: 269e434 -->
<!-- docs-review-agents-blob-sha: 3dd7c24 -->

## DGX Station Hardware Evidence
<!-- Required only when scripts/prepare-dgx-station-host.sh changes.
Maintainers must review the linked evidence before approving or merging.
This is human-reviewed evidence, not authenticated hardware provenance.
Exceptional bypasses use existing repository governance and must be
documented on the PR. -->
- [ ] Tested on DGX Station
- Tested commit:
- Station profile/scenario:
- Result:
- Supporting evidence:

## Verification
<!-- Check each applicable item only when supported by the requested
evidence. Run targeted tests once per relevant change set and rerun
after later edits or hook autofixes that can affect the tested behavior.
Do not rerun hook-covered checks. -->
- [x] PR description includes a `Signed-off-by:` line and every commit
appears as `Verified` in GitHub — all 14 commits verified after
publishing revision 269e434
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run validate:pr` passed after refreshing `origin/main` when hooks
were skipped or unavailable — commit and push hooks passed
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — Linux Node 22 container: 68
guard/parser tests passed; Python compile passed
- [x] Applicable broad gate passed — `npm run checks`, `npm run
typecheck:cli`, `npm run test-size:check`, and `npm run
source-shape:check` passed locally
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only)
- [ ] Doc pages follow the style guide (doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)

---
<!-- DCO sign-off is required in this PR description, and every commit
must appear as Verified in GitHub. Run: git config user.name && git
config user.email -->
Signed-off-by: Hung Le <hple@nvidia.com>


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

* **Bug Fixes**
* `shields up` now recovers from permissions-only drift in locked
configuration files by re-sealing them.
  * Configuration contents remain unchanged during recovery.
  * Structural or content changes continue to fail safely.
  * Recovery results indicate when drift was successfully re-sealed.
  * An informational message is displayed when re-sealing occurs.

* **Tests**
* Added coverage for recovery, unchanged configuration contents, error
handling, and fail-closed behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Hung Le <hple@nvidia.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Co-authored-by: Apurv Kumaria <akumaria@nvidia.com>
@cjagwani

cjagwani commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Exact-head follow-up for 3f8bba830a49b46a18be6e74b510846e8c3c053d: the reviewed npm audit failed deterministically (1 unaccepted high finding in the reviewed archive, 4 in OpenClaw 2026.7.1, and 2 in mcporter 0.7.3), which leaves checks and the required E2E gate red. I am not treating this as infrastructure noise or rerunning it. This head needs a commit that resolves the audit policy failure, or a refresh incorporating an accepted policy update, before exact-head validation can continue. This is a coordination comment, not a Changes Requested review.

@cjagwani

cjagwani commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Release gate refresh needed for the current v0.0.102 queue:

  • exact head: 3f2847b3fb8db384495486ca4c9dd5d60fae27a5
  • recorded merge base: 8295d2069e1b4336a00573e717c838c2e04d62ee
  • GitHub compare result against current main: diverged, 16 commits behind
  • exact-head checks: green; review decision: approved

Please merge current main into this branch normally, refresh the exact-head documentation/security/test receipts, and let required CI/E2E complete on the new head. This is a release-gate refresh request, not a request to change the approved behavior.

@github-actions github-actions Bot added v0.0.103 and removed v0.0.102 labels Aug 4, 2026
@apurvvkumaria
apurvvkumaria merged commit e87a5f3 into main Aug 5, 2026
72 checks passed
@apurvvkumaria
apurvvkumaria deleted the fix/7545-confidentiality-dir-traversal branch August 5, 2026 05:42
@cjagwani cjagwani mentioned this pull request Aug 5, 2026
23 tasks
cjagwani added a commit that referenced this pull request Aug 5, 2026
<!-- markdownlint-disable MD041 -->
## Summary

Add the canonical dated changelog entry for the planned NemoClaw
v0.0.103 release.
The new `docs/changelog/2026-08-05.mdx` entry uses the exact `##
v0.0.103` heading and summarizes supported user-visible changes merged
since v0.0.102.

## Changes

- Add the parser-safe MDX SPDX header, three-paragraph release summary,
and detailed grouped bullets to `docs/changelog/2026-08-05.mdx`.
- Link each release-note group to the most specific published OpenClaw,
Hermes, or Deep Agents documentation routes.
- Exclude dormant MXC and Podman foundations, internal managed-inference
adapters, test-only changes, and maintainer tooling from the supported
product narrative.

### Source summary

- [#8082](#8082) ->
`docs/changelog/2026-08-05.mdx`: Document the new one-command agent
launch flow.
- [#8314](#8314) ->
`docs/changelog/2026-08-05.mdx`: Document managed vLLM host capability
validation and restart handling.
- [#8248](#8248) ->
`docs/changelog/2026-08-05.mdx`: Record the DGX Spark Qwen profile MTP
default change.
- [#8223](#8223) ->
`docs/changelog/2026-08-05.mdx`: Record explicit model preservation
across provider switches.
- [#8209](#8209) ->
`docs/changelog/2026-08-05.mdx`: Document corrected Windows WSL provider
selection.
- [#8316](#8316) ->
`docs/changelog/2026-08-05.mdx`: Record clean managed-checkout reuse
after installation.
- [#8239](#8239) ->
`docs/changelog/2026-08-05.mdx`: Record the packaged-service teardown
fallback.
- [#8247](#8247) ->
`docs/changelog/2026-08-05.mdx`: Document uninstall behavior for an
already-removed sandbox.
- [#7998](#7998) ->
`docs/changelog/2026-08-05.mdx`: Record preserved container-start
diagnostics.
- [#8027](#8027) ->
`docs/changelog/2026-08-05.mdx`: Record journal-backed not-ready repair
authority.
- [#7812](#7812) ->
`docs/changelog/2026-08-05.mdx`: Document actionable rebuild preflight
diagnostics.
- [#8222](#8222) ->
`docs/changelog/2026-08-05.mdx`: Record redacted top-level CLI failures.
- [#8313](#8313) ->
`docs/changelog/2026-08-05.mdx`: Record structured MCP bridge
destruction failures.
- [#8211](#8211) ->
`docs/changelog/2026-08-05.mdx`: Document cleanup of incomplete snapshot
captures.
- [#8212](#8212) ->
`docs/changelog/2026-08-05.mdx`: Document best-effort post-restore
policy reconciliation.
- [#8245](#8245) ->
`docs/changelog/2026-08-05.mdx`: Clarify manifest-defined OpenClaw
workspace persistence.
- [#8254](#8254) ->
`docs/changelog/2026-08-05.mdx`: Include corrected snapshot restore
selection guidance.
- [#8238](#8238) ->
`docs/changelog/2026-08-05.mdx`: Document preservation of managed MCP
policy entries.
- [#7568](#7568) ->
`docs/changelog/2026-08-05.mdx`: Record mutable-default Shields rollback
preservation.
- [#8200](#8200) ->
`docs/changelog/2026-08-05.mdx`: Record truthful Shields state after a
rejected transition.
- [#7895](#7895) ->
`docs/changelog/2026-08-05.mdx`: Record descriptor-bound Shields lock
inspection.
- [#7892](#7892) ->
`docs/changelog/2026-08-05.mdx`: Document the canonical Hermes dashboard
profile and migration.
- [#7871](#7871) ->
`docs/changelog/2026-08-05.mdx`: Document fail-closed Hermes cron
restore.
- [#7894](#7894) ->
`docs/changelog/2026-08-05.mdx`: Record the reset Hermes health budget
after recovery.
- [#8228](#8228) ->
`docs/changelog/2026-08-05.mdx`: Document Hermes build-time corporate CA
trust.
- [#8206](#8206) ->
`docs/changelog/2026-08-05.mdx`: Document bounded Deep Agents Code
failure classification.
- [#8297](#8297) ->
`docs/changelog/2026-08-05.mdx`: Record reuse of the published Deep
Agents Code base image.
- [#8321](#8321) ->
`docs/changelog/2026-08-05.mdx`: Document aligned endpoint SSRF
protections and userinfo rejection.
- [#8299](#8299) ->
`docs/changelog/2026-08-05.mdx`: Document the fail-closed `setpriv`
transition in managed images.
- [#7603](#7603) ->
`docs/changelog/2026-08-05.mdx`: Record corrected confidentiality-root
traversal.
- [#8334](#8334) ->
`docs/changelog/2026-08-05.mdx`: Record removal of the unsupported logs
audit example.
- [#8256](#8256) ->
`docs/changelog/2026-08-05.mdx`: Record reordered network-policy
walkthrough prerequisites.
- [#7767](#7767) ->
`docs/changelog/2026-08-05.mdx`: Record platform runtime shape
validation.

## Type of Change

- [ ] Code change (feature, bug fix, or refactor)
- [ ] Code change with doc updates
- [x] Doc only (prose changes, no code sample modifications)
- [ ] Doc only (includes code sample changes)

## Quality Gates

- [ ] Tests added or updated for changed behavior
- [x] Existing tests cover changed behavior — justification: `npx vitest
run test/changelog-docs.test.ts` passed all 6 tests.
- [ ] Tests not applicable — justification:
- [x] Docs updated for user-facing behavior changes
- [ ] Docs not applicable — justification:
- [ ] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [ ] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification:
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Documentation Writer Review

- [ ] Documentation writer subagent reviewed the completed changes
- Result: `docs-updated`
- Evidence: `docs/changelog/2026-08-05.mdx` follows the release-prep and
documentation writing rules. The changelog contract tests passed 6/6,
and `npm run docs` completed with 0 errors and the repository's 2
existing Fern warnings.
- Agent: Codex Desktop
<!-- docs-review-head-sha: 66fcd80 -->
<!-- docs-review-agents-blob-sha: 3dd7c24 -->

## DGX Station Hardware Evidence

- [ ] Tested on DGX Station
- Tested commit: Not applicable.
- Station profile/scenario: Not applicable.
- Result: Not applicable.
- Supporting evidence: Not applicable.

## Verification

- [x] PR description includes a `Signed-off-by:` line and every commit
appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run validate:pr` passed after refreshing `origin/main` when hooks
were skipped or unavailable
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — `npx vitest run
test/changelog-docs.test.ts`: 1 file and 6 tests passed.
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result: Not run for this doc-only
change.
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only) —
completed with 0 errors and 2 existing Fern warnings.
- [x] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)
— the native changelog uses the required parser-safe MDX SPDX comment
and does not use page frontmatter.

---
Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>


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

## Summary by CodeRabbit

* **Documentation**
  * Added release notes for v0.0.103.
  * Documented the new `nemoclaw launch` command.
* Included updates covering onboarding, inference, installation,
recovery, snapshots, security, integrations, endpoint validation,
sandbox hardening, and related guidance.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: security Security controls, permissions, secrets, or hardening

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[OpenClaw][Shields] Lockdown breaks gateway startup and Telegram dispatch on missing legacy oauth.json

6 participants