Skip to content

fix(shields): accept private mutable Hermes root - #7033

Closed
prekshivyas wants to merge 8 commits into
mainfrom
codex/fix-hermes-private-shields-root
Closed

fix(shields): accept private mutable Hermes root#7033
prekshivyas wants to merge 8 commits into
mainfrom
codex/fix-hermes-private-shields-root

Conversation

@prekshivyas

@prekshivyas prekshivyas commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

Summary

Hermes can tighten its mutable home from mode 03770 to the private mode 0700 after the dashboard starts. Shields now accepts either sandbox-owned mutable posture instead of rolling back a successful second unlock, while retaining exact ownership and protected-file checks.

Related Issue

Refs #6381

Changes

  • Accept mode 0700 or 03770 for the mutable Hermes config root only when it remains owned by sandbox:sandbox.
  • Keep protected Hermes config files restricted to mode 0640 and sandbox:sandbox ownership.
  • Cover the dashboard-tightened posture in a fast regression test and align the two-cycle live E2E assertion with both valid mutable modes.

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: The exact mutable root mode is an internal runtime posture; documented ownership, locked posture, commands, and operator-visible behavior are unchanged.
  • 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: Mode 0700 is narrower than 03770; acceptance remains Hermes-only and still requires sandbox:sandbox ownership, exact 0640 protected files, and cleared immutable flags. Locked posture is unchanged.
  • Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue:

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 check:diff passed when hooks were skipped or unavailable
  • Targeted behavior tests pass for the current change set, or tests are marked not applicable above — npx vitest run --project cli src/lib/shields/legacy-hermes-compat.test.ts (12 passed); npm run test:changed (32 files, 310 tests passed); npm run typecheck:cli 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: Prekshi Vyas prekshiv@nvidia.com

Summary by CodeRabbit

  • Bug Fixes
    • Updated Hermes config unlock compatibility for tightened 700 directory permissions, now specifically allowing it only in the managed non-root topology.
    • Refined Hermes-aware permission mismatch messaging to reflect the expected modes for that topology.
  • Tests
    • Enhanced legacy Hermes compatibility tests with parameterized Hermes root modes and lifecycle marker/topology simulation, including new unlock/deny assertions.
    • Updated end-to-end Hermes validation to accept 700 or 3770 for sandbox permissions via a more flexible match.

Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
@prekshivyas prekshivyas self-assigned this Jul 16, 2026
@coderabbitai

coderabbitai Bot commented Jul 16, 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

Hermes config unlock verification now detects workload topology before accepting mode 700. Compatibility and end-to-end tests cover managed-nonroot acceptance, rejected modes, and unsupported topologies.

Changes

Hermes topology-aware unlock

Layer / File(s) Summary
Topology inspection and mode validation
src/lib/shields/index.ts
Hermes unlock verification probes the lifecycle marker and accepts mode 700 only for an active managed-nonroot topology, with Hermes-specific mismatch reporting.
Compatibility and integration validation
src/lib/shields/legacy-hermes-compat.test.ts, test/e2e/live/hermes-shields-config.test.ts
Mocks parameterize Hermes directory modes and topology responses; tests cover accepted 700, default 3770, rejected 750, unsupported topologies, and live output matching both accepted modes.

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

Possibly related PRs

  • NVIDIA/NemoClaw#2227: Updates Hermes-specific permission verification in the shields config-unlock flow.

Suggested reviewers: cv

Sequence Diagram(s)

sequenceDiagram
  participant UnlockVerification
  participant HermesSandbox
  participant HermesConfigDirectory
  UnlockVerification->>HermesSandbox: inspect lifecycle marker
  HermesSandbox-->>UnlockVerification: return Hermes topology
  UnlockVerification->>HermesConfigDirectory: inspect directory mode
  HermesConfigDirectory-->>UnlockVerification: return mode
  UnlockVerification->>UnlockVerification: validate topology and mode
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: Shields now accepts a private mutable Hermes root.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/fix-hermes-private-shields-root

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

@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — Informational

Advisor assessment: Informational / high confidence
Next action: No advisor follow-up needed.
Findings: 0 blockers · 0 warnings · 0 suggestions
Status: No actionable findings remain in the canonical review ledger.

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 · 0 warnings · 0 suggestions
  • Model comparison: normalized findings match; normalized E2E selections differ; severity counts match.

Nemotron output stays in workflow artifacts and does not change the assessment above.

E2E guidance

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

Recommended E2E: cloud-onboard, credential-sanitization, full-e2e, hermes-e2e, security-posture, hermes-shields-config

Workflow run details

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

@github-code-quality

github-code-quality Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage remains at 96%, unchanged from the main branch.


Updated July 16, 2026 21:23 UTC
Code Coverage is in Public Preview. Learn more and provide us with your feedback.

@apurvvkumaria apurvvkumaria added bug-fix PR fixes a bug or regression area: sandbox OpenShell sandbox lifecycle, runtime, config, or recovery area: security Security controls, permissions, secrets, or hardening labels Jul 16, 2026
@apurvvkumaria apurvvkumaria self-assigned this Jul 16, 2026
@apurvvkumaria apurvvkumaria added integration: hermes Hermes integration behavior v0.0.85 labels Jul 16, 2026
Co-authored-by: Prekshi Vyas <prekshiv@nvidia.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.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.

Security/correctness review at exact head 291aa0d confirms PRA-1. The exception is unconditional for every Hermes topology, but the retained root-entrypoint topology launches Hermes as the separate gateway UID in the sandbox group (agents/hermes/start.sh) and relies on 03770 traversal/write access. Treating 0700 sandbox:sandbox as a completed unlock can therefore report success while that gateway cannot traverse the config root. The new live test explicitly covers only managed non-root/same-UID startup, so it does not close this case. Please either bind the 0700 allowance to an attested same-UID/non-root topology, or restore/verify 03770 before finish where a separate gateway UID exists, and add a regression that rejects or repairs 0700 in the root-separated topology. Categories 1–6 PASS; configuration/holistic posture FAIL for the cross-topology exception; security testing WARNING until that negative topology is covered. I am withholding trusted E2E authorization until this blocker is fixed.

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

@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 `@src/lib/shields/legacy-hermes-compat.test.ts`:
- Around line 151-152: Replace the command mock branch keyed by
HERMES_ROOT_LIFECYCLE_MARKER with focused tests that exercise the real
lifecycle-marker probe predicate and topology mapping. Cover missing, existing,
and symlink marker paths, and add negative security-boundary cases proving
bypass attempts are rejected rather than classified as hermesTopology.
🪄 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: b486a2df-332f-4758-8219-616de010f750

📥 Commits

Reviewing files that changed from the base of the PR and between 291aa0d and e86c250.

📒 Files selected for processing (2)
  • src/lib/shields/index.ts
  • src/lib/shields/legacy-hermes-compat.test.ts

Comment thread src/lib/shields/legacy-hermes-compat.test.ts Outdated
@cv

cv commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

Re-audit at exact head e86c250190c4db07bc51303b8eb81008dea07afb: the production topology gate fixes my prior root-separated 0700 blocker. The PR remains HOLD on the valid unresolved CodeRabbit Major: the unit suite mocks the final topology string instead of exercising the actual lifecycle-marker shell predicate. Please add focused coverage for missing => managed-nonroot and existing or dangling-symlink => root-separated, then resolve the thread, sync current main, and rerun exact-head gates/E2E. The current focused suite passes 15/15 and all commits are Verified+DCO; I can re-review promptly after that smallest fix.

prekshivyas and others added 4 commits July 16, 2026 13:45
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
…ate-shields-root

Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
@github-actions

Copy link
Copy Markdown
Contributor

@apurvvkumaria

Copy link
Copy Markdown
Collaborator

Superseded by #7049. The replacement preserves all seven original commits from this PR in its ancestry and credits Prekshi Vyas as co-author of the maintainer remediation commit. Closing this PR without merge so the descriptor-safe marker and topology attestation can proceed through the normal gate.

apurvvkumaria added a commit that referenced this pull request Jul 16, 2026
<!-- markdownlint-disable MD041 -->
## Summary

Supersedes #7033 with an append-only maintainer follow-up that preserves
every original commit by Prekshi Vyas. It keeps the intended private
Hermes root support while requiring descriptor-safe lifecycle-marker and
process-topology attestation before accepting or repairing that state.

## Related Issue

Refs #6381

## Changes

- Preserve all seven commits from #7033 and their original authorship.
- Authenticate the root-separated lifecycle marker by pinned descriptor,
exact ownership, mode, link count, and content.
- Attest the pinned process topology before distinguishing
root-separated and same-UID runtimes.
- Re-sample lifecycle and startup-ready state after the procfs proof and
fail closed if topology changes during attestation.
- Restrict accepted same-UID modes and repair root-separated mode inside
the sealed transaction.
- Fail closed on malformed, symlinked, hard-linked, changed, or raced
marker and topology state while retaining rollback.
- Exercise real root-owned repair and exact rollback in a pinned,
network-isolated Linux container independent of the host UID.
- Assert the rollback protocol order: prepare abort, restore the locked
state directory, then commit abort.
- Credit Prekshi Vyas as co-author of both maintainer remediation
commits.

## 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

- [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: an independent documentation
audit confirmed this tightens an internal sandbox guard without changing
supported commands, configuration, or operator workflow.
- [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: independent exact-head
maintainer review covered topology transitions, filesystem authority,
rollback order, test isolation, and the automated findings; the
remaining analyzer comments were verified as duplicate false positives
or inapplicable to the explicitly same-UID E2E fixture.
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Verification

- [x] PR description includes the DCO sign-off declaration and every
pushed commit appears as `Verified` in GitHub
- [x] Normal pre-commit, commit-msg, and pre-push hooks passed
- [x] Targeted tests pass for changed behavior
- [ ] Full `npm test` passes (broad runtime changes only)
- [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)

Targeted evidence: the topology suite passed (3 host tests; 2
platform-gated), the Docker-backed real-root rollback case passed
independently, the legacy shields suite passed (14/14), Python
compilation and CLI typecheck passed, and changed-file hooks plus title,
size, source-shape, Biome, Docker-abstraction, and diff checks passed.
Fresh exact-head CI and trusted E2E are pending.

---

Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>


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

## Summary by CodeRabbit

* **Security & Reliability**
* Strengthened Hermes runtime topology attestation using a root
lifecycle marker.
* Added stricter fail-closed behavior for missing/unsafe marker states
and unknown topologies.
* Reconciles/repairs mutable private Hermes directory metadata
(mode/ownership) before finalization.
* Added durability checks by introducing a directory metadata fsync
barrier when required.
* **Bug Fixes**
* Relaxed non-final Hermes config-directory mode matching (while keeping
owner validation strict), with clearer expected-mode failures during
in-progress transactions.
* **Tests**
* Added new Hermes runtime-config-guard topology and reconciliation test
coverage (local + Docker), including race/drift and transition recovery
scenarios.

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

---------

Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Co-authored-by: Prekshi Vyas <prekshiv@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: sandbox OpenShell sandbox lifecycle, runtime, config, or recovery area: security Security controls, permissions, secrets, or hardening bug-fix PR fixes a bug or regression integration: hermes Hermes integration behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants