Description
On NemoClaw v0.0.57, the documented secret-boundary protection (validate_hermes_env_secret_boundary, per agents/hermes/start.sh:1050) is not enforced on gateway recover. With the Hermes gateway already healthy, injecting a plaintext raw secret (TELEGRAM_BOT_TOKEN=1234567890:AAExample-RawSecretValueHere) into /sandbox/.hermes/.env and running nemohermes hermes recover lets the gateway restart and keep serving — no [SECURITY] log line is emitted and startup is not refused. If a real bearer token is written into a sandbox-visible .env, the secret boundary does not block the gateway, violating the documented security design.
Severity: High / Security
Environment
| Field |
Value |
| Device |
a1u2n2g-0087-02 |
| OS |
Ubuntu 24.04 |
| Architecture |
x86_64 |
| Node.js |
v22.22.3 |
| npm |
10.9.8 |
| Docker |
29.5.3, build d1c06ef |
| OpenShell CLI |
0.0.44 |
| NemoClaw |
v0.0.57 |
| Hermes Agent |
v0.14.0 |
| Sandbox |
hermes (model nvidia/nemotron-3-super-120b-a12b, provider nvidia-prod) |
Steps to Reproduce
Precondition: sandbox hermes running and healthy; /sandbox/.hermes/.env contains only placeholder values (API_SERVER_PORT, API_SERVER_HOST).
# 1. Confirm gateway is healthy
curl -sf http://127.0.0.1:8642/health # -> {"status": "ok", "platform": "hermes-agent"}
# 2. Inject a raw secret into /sandbox/.hermes/.env
echo 'TELEGRAM_BOT_TOKEN=1234567890:AAExample-RawSecretValueHere' >> /sandbox/.hermes/.env
# 3. Trigger gateway restart / validator
nemohermes hermes recover
# 4. Inspect gateway logs for a [SECURITY] refusal line
docker logs <hermes-container> --tail 40 | grep -iE "SECURITY|Refusing|raw secret|secret.boundary"
# 5. Check health
curl -sf http://127.0.0.1:8642/health
Expected Result
Gateway startup is refused. Logs contain:
[SECURITY] Refusing Hermes startup because /sandbox/.hermes/.env contains raw secret-shaped values
[SECURITY] TELEGRAM_BOT_TOKEN (line N)
And /health returns HEALTH_DOWN (gateway must NOT serve).
Actual Result
No security enforcement occurred. Clean reproduction with the gateway healthy throughout (this run isolates the secret-boundary behavior; an earlier attempt was inconclusive because hermes recover had failed for an unrelated reason):
- Step 1 (pre-check): gateway healthy →
{"status": "ok", "platform": "hermes-agent"}
- Step 2 (inject
TELEGRAM_BOT_TOKEN raw secret): PASS (write confirmed in .env)
- Step 3 (
nemohermes hermes recover): "Hermes Agent gateway is running in 'hermes'", RECOVER_EXIT:0
- Step 4 (expect
[SECURITY] Refusing in logs): FAIL → NO_REJECTION_MESSAGE
- Step 5 (expect
/health = HEALTH_DOWN): FAIL → /health = {"status": "ok", "platform": "hermes-agent"}, gateway SERVING with the raw secret present.
Additional finding: the documented allowed-placeholder forms (openshell:resolve:env: / xoxb-OPENSHELL-RESOLVE-ENV-) are not present in the hermes sandbox .env at all, indicating the secret-boundary placeholder mechanism is not deployed in this build. The symlink-rejection assertion was not tested because the validator itself does not appear to exist.
Possible Causes (UNCONFIRMED, for triage)
validate_hermes_env_secret_boundary may not be implemented in v0.0.57 / Hermes Agent v0.14.0.
nemohermes hermes recover may not trigger the validator path in start.sh.
- The validator regex may not match the
TELEGRAM_BOT_TOKEN format.
Logs
$ curl -sf http://127.0.0.1:8642/health # before injection
{"status": "ok", "platform": "hermes-agent"}
$ nemohermes hermes recover
Probe complete: Hermes Agent gateway is running in 'hermes'.
RECOVER_EXIT:0
$ docker logs <hermes-container> --tail 40 | grep -iE "SECURITY|Refusing|raw secret|secret.boundary"
NO_REJECTION_MESSAGE
$ curl -sf http://127.0.0.1:8642/health # after injecting raw secret + recover
{"status": "ok", "platform": "hermes-agent"}
Description
On NemoClaw v0.0.57, the documented secret-boundary protection (
validate_hermes_env_secret_boundary, peragents/hermes/start.sh:1050) is not enforced on gateway recover. With the Hermes gateway already healthy, injecting a plaintext raw secret (TELEGRAM_BOT_TOKEN=1234567890:AAExample-RawSecretValueHere) into/sandbox/.hermes/.envand runningnemohermes hermes recoverlets the gateway restart and keep serving — no[SECURITY]log line is emitted and startup is not refused. If a real bearer token is written into a sandbox-visible.env, the secret boundary does not block the gateway, violating the documented security design.Severity: High / Security
Environment
Steps to Reproduce
Precondition: sandbox
hermesrunning and healthy;/sandbox/.hermes/.envcontains only placeholder values (API_SERVER_PORT,API_SERVER_HOST).Expected Result
Gateway startup is refused. Logs contain:
And
/healthreturnsHEALTH_DOWN(gateway must NOT serve).Actual Result
No security enforcement occurred. Clean reproduction with the gateway healthy throughout (this run isolates the secret-boundary behavior; an earlier attempt was inconclusive because
hermes recoverhad failed for an unrelated reason):{"status": "ok", "platform": "hermes-agent"}TELEGRAM_BOT_TOKENraw secret): PASS (write confirmed in.env)nemohermes hermes recover):"Hermes Agent gateway is running in 'hermes'",RECOVER_EXIT:0[SECURITY] Refusingin logs): FAIL →NO_REJECTION_MESSAGE/health= HEALTH_DOWN): FAIL →/health={"status": "ok", "platform": "hermes-agent"}, gateway SERVING with the raw secret present.Additional finding: the documented allowed-placeholder forms (
openshell:resolve:env:/xoxb-OPENSHELL-RESOLVE-ENV-) are not present in the hermes sandbox.envat all, indicating the secret-boundary placeholder mechanism is not deployed in this build. The symlink-rejection assertion was not tested because the validator itself does not appear to exist.Possible Causes (UNCONFIRMED, for triage)
validate_hermes_env_secret_boundarymay not be implemented in v0.0.57 / Hermes Agent v0.14.0.nemohermes hermes recovermay not trigger the validator path instart.sh.TELEGRAM_BOT_TOKENformat.Logs