Repository navigation
Description
Source
Identified in PR #5876 — feat(mcp): add OpenShell-managed MCP servers, specifically the PR Review Advisor findings.
Problem
The credential boundary manifest openshell-child-visible-credentials.v0.0.72.json is baked for OpenShell 0.0.72 and supplies the deny-lists used to protect child-visible credentials. The TypeScript and Python consumers validate the manifest structure, but neither verifies that the running openshell binary matches manifest.openshellVersion. The Hermes image and startup path also lack an equivalent runtime gate.
A sandbox can therefore use credential-boundary rules for OpenShell 0.0.72 while actually running a newer or older OpenShell after an image, installer, or manual runtime change.
Findings consolidated
PRA-4 — TypeScript validation boundary
Affected paths:
src/lib/actions/sandbox/mcp-bridge-validation.tssrc/lib/security/mcp-url-target.ts
The manifest is imported and its runtimeControlKeys, runtimeControlPrefixes, rawChildValueKeys, and rewrittenChildValueKeys are used without executing openshell --version.
PRA-5 — Python Hermes transaction boundary
Affected path:
agents/hermes/mcp-config-transaction.py
_load_credential_boundary_manifest() checks the baked manifest version but never compares it with the installed OpenShell binary.
PRA-6 — Hermes runtime/startup boundary
Affected paths:
agents/hermes/Dockerfileagents/hermes/start.shagents/hermes/mcp-config-transaction.py
The Dockerfile checks MCP Python imports at build time, but Hermes startup does not verify the runtime OpenShell version before using the credential deny-list.
Security impact
When the manifest and runtime diverge:
- newly reserved OpenShell credential names may be accepted and exposed across the child credential boundary;
- names that are legitimate for the running version may be rejected;
- the credential isolation contract silently depends on stale metadata.
Required behavior
- Execute and parse
openshell --versionin the TypeScript credential-validation path. - Execute and parse
subprocess.run(["openshell", "--version"], capture_output=True, text=True)in the Python/Hermes path. - Compare the parsed version exactly with
manifest.openshellVersion. - Fail closed when the binary is missing, exits unsuccessfully, produces unparseable output, or reports a different version.
- Ensure the Hermes check runs for every relevant startup. If the Python transaction is guaranteed to execute before credential configuration on every startup, it may satisfy the startup boundary; otherwise add an entrypoint check.
- A short-lived cache may be used in frequently invoked TypeScript validation, but it must not allow a stale result to survive a runtime change indefinitely.
- Error output should identify expected versus actual version without exposing credential values.
Regression coverage
- Add TypeScript tests in
src/lib/actions/sandbox/mcp-bridge-input-validation.test.tsfor:- matching runtime and manifest versions;
- runtime version 0.0.73 with a 0.0.72 manifest;
- missing binary;
- non-zero exit;
- unparseable version output.
- Add equivalent Python transaction coverage in
test/hermes-mcp-config-transaction.test.ts. - Add a Hermes runtime/E2E test in
test/e2e/live/rebuild-hermes.test.tsthat substitutes a mismatched OpenShell version and proves startup or credential configuration fails closed.
Acceptance criteria
- TypeScript and Hermes/Python credential-boundary paths verify the actual runtime OpenShell version before applying manifest deny-lists.
- Exact matches proceed normally.
- Mismatch, missing binary, command failure, and parse failure are rejected before credentials are written or the affected runtime starts.
- Unit tests cover both implementations.
- Hermes runtime coverage proves the check cannot be bypassed by starting an image with a different OpenShell binary.
Activity
fix(mcp): reconcile Hermes runtime state (#6261)
wscurran commentedon Jul 6, 2026
✨
Related open PRs:
fix(e2e): classify unsupported MCP dev runtimes (#6479)
cv commentedon Jul 9, 2026
Host-side enforcement is complete via #6261 and #6479: current main validates the selected OpenShell CLI version before MCP credential mutations. The remaining Hermes criterion cannot safely attest the supervisor from inside the workload on pinned 0.0.72, so this is now blocked on an authenticated upstream supervisor-version capability and deferred from v0.0.80.
fix(mcp): reconcile Hermes runtime state (NVIDIA#6261)
fix(e2e): classify unsupported MCP dev runtimes (NVIDIA#6479)
chore(deps): trust OpenShell 0.0.106 manifests (#9224)
chore(deps): update OpenShell to 0.0.106 (#9192)
chore(deps): update openshell to 0.0.116
chore(deps): update openshell to 0.0.116
chore(deps): update openshell to 0.0.116
chore(deps): update openshell to 0.0.116
chore(deps): trust OpenShell 0.0.116 manifests (#10790)