Hermes shields status silently repairs config-hash permission drift without reporting it
- Dominant language
- TypeScript
- Stars
- 22.5k
- Forks
- 3.1k
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 715
Description
## Description
A `shields status` check on a locked NemoHermes sandbox silently repairs a permissions-only drift on `/sandbox/.hermes/.config-hash` (ownership/mode reverted from `root:root 0444` back to `sandbox:sandbox 0660` by a host-root actor) as an undisclosed side effect. The command exits 0 and prints a clean `Shields: UP (lockdown active)` with no drift warning, while the file is silently restored to `0444 root:root` in the background. A supposedly read-only status check both mutates filesystem state and hides that unauthorized tampering ever happened.
Platform scope: Reproduced on Ubuntu 26.04 only; other platforms not tested.
Regression: Unknown — earlier versions not tested.
OpenShell issue: No
Related: A closely related but not identical issue was previously filed and fixed for the OpenClaw agent's `.openclaw/openclaw.json` + `.config-hash` drift detection (#4243, fixed and closed). That fix (a hash-seal cross-check added to `shields status`) does not appear to be present for the Hermes agent's `.hermes/.config-hash` — the symptom here is arguably worse than the original OpenClaw bug: instead of just failing to report drift, the Hermes path detects and silently repairs it, which actively erases the tampering evidence rather than merely missing it.
## Environment
```text
Device: Linux GPU test server
OS: Ubuntu 26.04 LTS
Architecture: x86_64
Node.js: v22.23.2
npm: 10.9.8
Docker: 29.7.2
OpenShell CLI: 0.0.106
NemoClaw: v0.0.118
OpenClaw: N/A (Hermes agent) — Hermes Agent v0.19.0
```
## Steps to Reproduce
1. Onboard a fresh Hermes sandbox and run:
```bash
nemoclaw {sandbox} shields up
```
2. Resolve the sandbox's runtime container ID by its OpenShell sandbox-name label, then as root inside that container:
```bash
chattr -i /sandbox/.hermes/.config-hash 2>/dev/null
chown sandbox:sandbox /sandbox/.hermes/.config-hash
chmod 0660 /sandbox/.hermes/.config-hash
```
(bytes are not modified, only ownership/mode)
3. Confirm the drift is present:
```bash
stat -c '%a %U:%G' /sandbox/.hermes/.config-hash
```
→ `660 sandbox:sandbox`
4. Run:
```bash
nemoclaw {sandbox} shields status
```
5. Immediately re-check:
```bash
stat -c '%a %U:%G' /sandbox/.hermes/.config-hash
```
## Expected Result
`shields status` exits non-zero and reports the exact ownership/mode drift on `.config-hash` (e.g. "UP (DRIFTED)" with a message identifying the mismatch), leaving the file in the drifted state until an explicit repair action (like `shields up`) is run.
## Actual Result
`shields status` exits 0 and prints only:
```text
Shields: UP (lockdown active)
Policy: restrictive
```
No drift is mentioned. Immediately after, the file's ownership/mode is back to `0444 root:root` — `shields status` silently repaired it as a side effect. Without independently monitoring the file from outside the sandbox, an operator running this status check would never learn that unauthorized permission tampering occurred, since running the check itself erases the evidence.
Confirmed the drift genuinely persists absent any `nemoclaw` command (checked repeatedly over 10s with no `nemoclaw` invocation in between — file stays at `660 sandbox:sandbox`), and confirmed `shields status` specifically is what repairs it (`stat` before/immediately after a single `shields status` call shows the change).
## Logs
Not captured — the observed behavior was a clean, silent CLI exit (no error/warning text to capture); the finding is the absence of any drift signal in stdout combined with the file-permission state change observed via `stat` before/after.
Contributor guide
Research direction
Start at the `nemoclaw {sandbox} shields status` CLI entry point and trace the Hermes `.hermes/.config-hash` handling. Compare its drift detection with the related OpenClaw fix in issue #4243. Done means status reports ownership/mode drift, exits non-zero, and does not repair the file; explicit `shields up` remains the repair action.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- docker, node.js, typescript
- Domain
- cli, infrastructure, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100