Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions .github/workflows/e2e.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1026,7 +1026,7 @@ jobs:
E2E_ARTIFACT_DIR: ${{ github.workspace }}/e2e-artifacts/live/openshell-gateway-auth-contract
NEMOCLAW_RUN_LIVE_E2E: "1"
NEMOCLAW_NON_INTERACTIVE: "1"
NEMOCLAW_OPENSHELL_PIN_VERSION: "0.0.99"
NEMOCLAW_OPENSHELL_PIN_VERSION: "0.0.101"
DOCKER_GRPC_PROBE_IMAGE: "node:22-trixie-slim@sha256:e6d9a389d34ff9678438af985c9913fbd1eb6ed36e80fea56644f4b4f6dd70ba"
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
Expand Down Expand Up @@ -1111,7 +1111,7 @@ jobs:
NEMOCLAW_OPENSHELL_CHANNEL: stable
NEMOCLAW_OPENSHELL_EXACT_MAIN_PROOF: "1"
NEMOCLAW_RUN_LIVE_E2E: "1"
OPENSHELL_DOCKER_SUPERVISOR_IMAGE: ghcr.io/nvidia/openshell/supervisor@sha256:ea3632b6e9528e2309103af5b6949606fcdc83ca1f69e8db81482a25bea84bb6
OPENSHELL_DOCKER_SUPERVISOR_IMAGE: ghcr.io/nvidia/openshell/supervisor@sha256:b58be5e40c788977ffa0e8305a8cad9c656efdf1a3fe182582a00ca870bb0edb
steps:
- id: trusted_hermes_swap
name: Provision trusted Hermes E2E swap
Expand Down Expand Up @@ -1364,12 +1364,12 @@ jobs:
jq -n '{
schemaVersion: 1,
sourceRepository: "NVIDIA/OpenShell",
releaseTag: "v0.0.99",
sourceSha: "8c7dd148a9e6360c9d5b2830e339a0dc4b3f3032",
releaseTag: "v0.0.101",
sourceSha: "8ddd98c3dff62619a3963f99ba1e055b67650e72",
artifacts: {
cli: {binarySha256: "5c0dabb90152a3cfae9005731771da99f00a22403080c81952c7be8ba4b5728f"},
gateway: {binarySha256: "05bd6c982dd72b73364b91ab694487c026bc56d0cd869f4289b44cc392a5c2ba"},
standaloneSandbox: {binarySha256: "a4b0c38ed90a6dd4b4f312ad3727824a25ec478d88d4e65d22a82377b18e6214"}
cli: {binarySha256: "1ad48efd5e1de8f3f017a81b3a7177872f350343a1a8d8074c7e844bca4801e9"},
gateway: {binarySha256: "a6a5d754605a2144b148637b85a09291d2eeb77e08a4ee34b83685c6920448f5"},
standaloneSandbox: {binarySha256: "a2704babbb468fd0a359bfdd9844de71095b730758541b4ca8cbab77d4018920"}
}
}' > "$E2E_ARTIFACT_DIR/mcp-bridge-deepagents/openshell-exact-main-provenance.json"
fi
Expand Down Expand Up @@ -1433,7 +1433,7 @@ jobs:
NEMOCLAW_OPENSHELL_CHANNEL: stable
NEMOCLAW_OPENSHELL_EXACT_MAIN_PROOF: "1"
NEMOCLAW_RUN_LIVE_E2E: "1"
OPENSHELL_DOCKER_SUPERVISOR_IMAGE: ghcr.io/nvidia/openshell/supervisor@sha256:ea3632b6e9528e2309103af5b6949606fcdc83ca1f69e8db81482a25bea84bb6
OPENSHELL_DOCKER_SUPERVISOR_IMAGE: ghcr.io/nvidia/openshell/supervisor@sha256:b58be5e40c788977ffa0e8305a8cad9c656efdf1a3fe182582a00ca870bb0edb
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
Expand Down Expand Up @@ -1485,12 +1485,12 @@ jobs:
jq -n '{
schemaVersion: 1,
sourceRepository: "NVIDIA/OpenShell",
releaseTag: "v0.0.99",
sourceSha: "8c7dd148a9e6360c9d5b2830e339a0dc4b3f3032",
releaseTag: "v0.0.101",
sourceSha: "8ddd98c3dff62619a3963f99ba1e055b67650e72",
artifacts: {
cli: {binarySha256: "5c0dabb90152a3cfae9005731771da99f00a22403080c81952c7be8ba4b5728f"},
gateway: {binarySha256: "05bd6c982dd72b73364b91ab694487c026bc56d0cd869f4289b44cc392a5c2ba"},
standaloneSandbox: {binarySha256: "a4b0c38ed90a6dd4b4f312ad3727824a25ec478d88d4e65d22a82377b18e6214"}
cli: {binarySha256: "1ad48efd5e1de8f3f017a81b3a7177872f350343a1a8d8074c7e844bca4801e9"},
gateway: {binarySha256: "a6a5d754605a2144b148637b85a09291d2eeb77e08a4ee34b83685c6920448f5"},
standaloneSandbox: {binarySha256: "a2704babbb468fd0a359bfdd9844de71095b730758541b4ca8cbab77d4018920"}
}
}' > "$E2E_ARTIFACT_DIR/openshell-credential-generation-window/openshell-exact-main-provenance.json"

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/podman-cpu-proof.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
E2E_JOB: "1"
E2E_TARGET_ID: podman-cpu-lifecycle
NEMOCLAW_RUN_LIVE_E2E: "1"
NEMOCLAW_OPENSHELL_PIN_VERSION: "0.0.99"
NEMOCLAW_OPENSHELL_PIN_VERSION: "0.0.101"
PODMAN_APT_VERSION: "5.7.0+ds2-3build1"
steps:
- name: Checkout
Expand Down
6 changes: 3 additions & 3 deletions agents/hermes/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ COPY agents/hermes/finalize-tirith-marker.py /usr/local/lib/nemoclaw/finalize-ti
COPY agents/hermes/build-mcp-digest.py /usr/local/lib/nemoclaw/build-hermes-mcp-digest.py
COPY agents/hermes/mcp-config-transaction.py /usr/local/lib/nemoclaw/hermes-mcp-config-transaction.py
COPY agents/hermes/cron-restore-control.py /usr/local/lib/nemoclaw/hermes-cron-restore-control.py
COPY src/lib/actions/sandbox/openshell-child-visible-credentials.v0.0.99.json /usr/local/lib/nemoclaw/openshell-child-visible-credentials.v0.0.99.json
COPY src/lib/actions/sandbox/openshell-child-visible-credentials.v0.0.101.json /usr/local/lib/nemoclaw/openshell-child-visible-credentials.v0.0.101.json
COPY scripts/state-dir-guard.py /usr/local/lib/nemoclaw/state-dir-guard.py
COPY agents/hermes/state-lock-plan.json /usr/local/share/nemoclaw/state-lock-plan.json
COPY nemoclaw-blueprint/scripts/*.js /usr/local/lib/nemoclaw/preloads/
Expand Down Expand Up @@ -378,12 +378,12 @@ RUN chmod -R a+rX /opt/nemoclaw-blueprint/
# minimum supported Hermes sandbox base tag guarantees those artifacts and
# test/sandbox-rlimit-hooks.test.ts covers that base.
RUN chmod 755 /usr/local/bin/nemoclaw-start /usr/local/bin/nemoclaw-managed-startup-hold /usr/local/bin/nemoclaw-managed-bootstrap /usr/local/lib/nemoclaw/sandbox-init.sh /usr/local/lib/nemoclaw/validate-hermes-env-secret-boundary.py /usr/local/lib/nemoclaw/patch-hermes-session-list-preview.py /usr/local/lib/nemoclaw/patch-hermes-sqlite-temp-store.py /usr/local/lib/nemoclaw/patch-hermes-discord-recovery-permissions.py /usr/local/lib/nemoclaw/patch-hermes-profile-policy-defaults.py /usr/local/lib/nemoclaw/seed-hermes-dashboard-config.py /usr/local/lib/nemoclaw/hermes-runtime-config-guard.py /usr/local/lib/nemoclaw/finalize-tirith-marker.py /usr/local/lib/nemoclaw/hermes-mcp-config-transaction.py \
&& chown root:root /usr/local/bin/nemoclaw-gateway-control /usr/local/lib/nemoclaw/gateway-supervisor.sh /usr/local/lib/nemoclaw/state-dir-guard.py /usr/local/share/nemoclaw/state-lock-plan.json /usr/local/lib/nemoclaw/managed-gateway-control.py /usr/local/lib/nemoclaw/build-hermes-mcp-digest.py /usr/local/lib/nemoclaw/hermes-cron-restore-control.py /usr/local/lib/nemoclaw/openshell-child-visible-credentials.v0.0.99.json \
&& chown root:root /usr/local/bin/nemoclaw-gateway-control /usr/local/lib/nemoclaw/gateway-supervisor.sh /usr/local/lib/nemoclaw/state-dir-guard.py /usr/local/share/nemoclaw/state-lock-plan.json /usr/local/lib/nemoclaw/managed-gateway-control.py /usr/local/lib/nemoclaw/build-hermes-mcp-digest.py /usr/local/lib/nemoclaw/hermes-cron-restore-control.py /usr/local/lib/nemoclaw/openshell-child-visible-credentials.v0.0.101.json \
&& chmod 700 /usr/local/bin/nemoclaw-gateway-control /usr/local/lib/nemoclaw/hermes-cron-restore-control.py \
&& chmod 500 /usr/local/lib/nemoclaw/state-dir-guard.py /usr/local/lib/nemoclaw/managed-gateway-control.py \
&& chmod 444 /usr/local/lib/nemoclaw/entrypoint-env-wrapper.sh /usr/local/share/nemoclaw/state-lock-plan.json /usr/local/lib/nemoclaw/gateway-supervisor.sh /usr/local/lib/nemoclaw/build-hermes-mcp-digest.py /usr/local/lib/nemoclaw/managed_policy.py \
&& chmod 444 /usr/local/lib/nemoclaw/patch-hermes-langfuse-credentials.mts \
&& chmod 444 /usr/local/lib/nemoclaw/openshell-child-visible-credentials.v0.0.99.json \
&& chmod 444 /usr/local/lib/nemoclaw/openshell-child-visible-credentials.v0.0.101.json \
&& if [ -d /usr/local/lib/nemoclaw/preloads ]; then \
chown -R 0:0 /usr/local/lib/nemoclaw/preloads \
&& find /usr/local/lib/nemoclaw/preloads -type f -exec chmod 444 {} + \
Expand Down
10 changes: 5 additions & 5 deletions agents/hermes/mcp-config-transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
r"^Bearer openshell:resolve:env:([A-Za-z_][A-Za-z0-9_]{0,127})$"
)
OPENSHELL_REVISIONED_CREDENTIAL_NAME_RE = re.compile(r"^v[0-9]+_[A-Za-z0-9_]+$")
BOUNDARY_MANIFEST_NAME = "openshell-child-visible-credentials.v0.0.99.json"
BOUNDARY_MANIFEST_NAME = "openshell-child-visible-credentials.v0.0.101.json"
ANSI_ESCAPE_RE = re.compile(
r"\x1b(?:\[[0-?]*[ -/]*[@-~]|\][^\x07]*(?:\x07|\x1b\\)|[@-_])"
)
Expand Down Expand Up @@ -107,7 +107,7 @@ def _load_credential_boundary_manifest() -> dict[str, object]:
# corrupt, or wrong-version OpenShell boundary manifest.
# sourceBoundary: NemoClaw owns one reviewed manifest installed beside this
# helper in images; the second path is the deterministic source-checkout layout.
# whyNotSourceFix: OpenShell v0.0.99 has no machine-readable child-env contract.
# whyNotSourceFix: OpenShell v0.0.101 has no machine-readable child-env contract.
# It also deliberately hides the supervisor identity mount from workload
# children and the Hermes image contains no OpenShell CLI. Executing
# ``openshell --version`` here would therefore either fail every real
Expand Down Expand Up @@ -135,7 +135,7 @@ def _load_credential_boundary_manifest() -> dict[str, object]:
manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
if (
not isinstance(manifest, dict)
or manifest.get("openshellVersion") != "0.0.99"
or manifest.get("openshellVersion") != "0.0.101"
):
raise RuntimeError("Hermes MCP credential boundary manifest is invalid")
return manifest
Expand Down Expand Up @@ -319,7 +319,7 @@ def _validate_payload(action: str, payload: dict[str, object]) -> None:
}
if action == "add" and hostname in host_aliases:
raise ValueError(
"Authenticated MCP OpenShell host aliases are unavailable with OpenShell v0.0.99"
"Authenticated MCP OpenShell host aliases are unavailable with OpenShell v0.0.101"
)
# Host preflight owns destination trust and binds every accepted endpoint to
# exact OpenShell address pins. This in-sandbox check revalidates canonical
Expand Down Expand Up @@ -1091,7 +1091,7 @@ def _assert_non_root_lifecycle_identity() -> None:
# topology.
# sourceBoundary: OpenShell owns workload topology; NemoClaw owns the
# immutable root-lifecycle marker and validates it before mutation.
# whyNotSourceFix: OpenShell 0.0.99 supports both topologies but exposes no
# whyNotSourceFix: OpenShell 0.0.101 supports both topologies but exposes no
# attested same-UID capability that this packaged helper can query.
# regressionTest: hermes-mcp-config-transaction.test.ts rejects both probe
# and add when the root-lifecycle marker identifies the legacy topology.
Expand Down
2 changes: 1 addition & 1 deletion agents/hermes/runtime-config-guard.py
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,7 @@ def _pinned_process_matches_supervised_nonroot_start(
supervisor_identity: tuple[str, int | None],
expected_effective_uid: int,
) -> bool:
# OpenShell 0.0.99 keeps its supervisor at PID 1 and launches the non-root
# OpenShell 0.0.101 keeps its supervisor at PID 1 and launches the non-root
# NemoClaw entrypoint as a child, so startup authority must be proved from
# pinned procfs identity rather than a PID-1 equality check. Remove this
# compatibility proof when #6256 provides authenticated supervisor/runtime
Expand Down
2 changes: 1 addition & 1 deletion agents/hermes/start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3279,7 +3279,7 @@ fi
# while Hermes actually runs in the legacy root-separated topology.
# sourceBoundary: OpenShell owns workload topology; NemoClaw owns the immutable
# root-lifecycle marker and stamps it before starting the root-separated gateway.
# whyNotSourceFix: OpenShell 0.0.99 supports both topologies but exposes no
# whyNotSourceFix: OpenShell 0.0.101 supports both topologies but exposes no
# attested same-UID capability that this packaged entrypoint can query.
# regressionTest: hermes-mcp-config-transaction.test.ts rejects both probe and
# add when the root-lifecycle marker identifies the legacy topology.
Expand Down
24 changes: 12 additions & 12 deletions docs/deployment/set-up-mcp-bridge.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ The integration has three parts:

This integration depends on the OpenShell MCP/JSON-RPC L7 policy support from [NVIDIA/OpenShell#1865](https://github.com/NVIDIA/OpenShell/pull/1865).

Current NemoClaw builds default to the pinned stable OpenShell `0.0.99` release, which exposes native `protocol: mcp` policy handling and provider-backed credential replacement.
Current NemoClaw builds default to the pinned stable OpenShell `0.0.101` release, which exposes native `protocol: mcp` policy handling and provider-backed credential replacement.
The optional OpenShell development channel is compatibility evidence only and is not a shipping target.

NemoClaw accepts Streamable HTTP MCP endpoints only.
Expand Down Expand Up @@ -69,36 +69,36 @@ NemoClaw accepts canonical HTTPS MCP URLs and writes the credential placeholder

### DNS Pinning Contract

The MCP integration pins its OpenShell DNS enforcement contract to [`NVIDIA/OpenShell@8c7dd148a9e6360c9d5b2830e339a0dc4b3f3032`](https://github.com/NVIDIA/OpenShell/tree/8c7dd148a9e6360c9d5b2830e339a0dc4b3f3032).
The MCP integration pins its OpenShell DNS enforcement contract to [`NVIDIA/OpenShell@8ddd98c3dff62619a3963f99ba1e055b67650e72`](https://github.com/NVIDIA/OpenShell/tree/8ddd98c3dff62619a3963f99ba1e055b67650e72).

With `proxy_connect_by_hostname` disabled, OpenShell uses one socket-address list throughout resolution, validation, and connection:

- [`crates/openshell-supervisor-network/src/proxy.rs:3030-3055`](https://github.com/NVIDIA/OpenShell/blob/8c7dd148a9e6360c9d5b2830e339a0dc4b3f3032/crates/openshell-supervisor-network/src/proxy.rs#L3030-L3055) produces the list.
- [`crates/openshell-supervisor-network/src/proxy.rs:3060-3115`](https://github.com/NVIDIA/OpenShell/blob/8c7dd148a9e6360c9d5b2830e339a0dc4b3f3032/crates/openshell-supervisor-network/src/proxy.rs#L3060-L3115) validates every address.
- [`crates/openshell-supervisor-network/src/proxy.rs:3130-3211`](https://github.com/NVIDIA/OpenShell/blob/8c7dd148a9e6360c9d5b2830e339a0dc4b3f3032/crates/openshell-supervisor-network/src/proxy.rs#L3130-L3211) connects through the validated list.
- [`crates/openshell-supervisor-network/src/proxy.rs:3030-3055`](https://github.com/NVIDIA/OpenShell/blob/8ddd98c3dff62619a3963f99ba1e055b67650e72/crates/openshell-supervisor-network/src/proxy.rs#L3030-L3055) produces the list.
- [`crates/openshell-supervisor-network/src/proxy.rs:3060-3115`](https://github.com/NVIDIA/OpenShell/blob/8ddd98c3dff62619a3963f99ba1e055b67650e72/crates/openshell-supervisor-network/src/proxy.rs#L3060-L3115) validates every address.
- [`crates/openshell-supervisor-network/src/proxy.rs:3130-3211`](https://github.com/NVIDIA/OpenShell/blob/8ddd98c3dff62619a3963f99ba1e055b67650e72/crates/openshell-supervisor-network/src/proxy.rs#L3130-L3211) connects through the validated list.

The CONNECT path passes that validated connector to the direct or operator-configured upstream dial path.
By default, direct connections and corporate-proxy CONNECT requests use the validated address list at [`crates/openshell-supervisor-network/src/proxy.rs:3179-3211`](https://github.com/NVIDIA/OpenShell/blob/8c7dd148a9e6360c9d5b2830e339a0dc4b3f3032/crates/openshell-supervisor-network/src/proxy.rs#L3179-L3211).
The explicit HTTP-forward path carries the same connector from [`crates/openshell-supervisor-network/src/proxy.rs:4650-4656`](https://github.com/NVIDIA/OpenShell/blob/8c7dd148a9e6360c9d5b2830e339a0dc4b3f3032/crates/openshell-supervisor-network/src/proxy.rs#L4650-L4656) into the actual connection at [`crates/openshell-supervisor-network/src/proxy.rs:4706-4711`](https://github.com/NVIDIA/OpenShell/blob/8c7dd148a9e6360c9d5b2830e339a0dc4b3f3032/crates/openshell-supervisor-network/src/proxy.rs#L4706-L4711).
By default, direct connections and corporate-proxy CONNECT requests use the validated address list at [`crates/openshell-supervisor-network/src/proxy.rs:3179-3211`](https://github.com/NVIDIA/OpenShell/blob/8ddd98c3dff62619a3963f99ba1e055b67650e72/crates/openshell-supervisor-network/src/proxy.rs#L3179-L3211).
The explicit HTTP-forward path carries the same connector from [`crates/openshell-supervisor-network/src/proxy.rs:4650-4656`](https://github.com/NVIDIA/OpenShell/blob/8ddd98c3dff62619a3963f99ba1e055b67650e72/crates/openshell-supervisor-network/src/proxy.rs#L4650-L4656) into the actual connection at [`crates/openshell-supervisor-network/src/proxy.rs:4706-4711`](https://github.com/NVIDIA/OpenShell/blob/8ddd98c3dff62619a3963f99ba1e055b67650e72/crates/openshell-supervisor-network/src/proxy.rs#L4706-L4711).

The exception is OpenShell's operator-controlled `proxy_connect_by_hostname` option.
When enabled, OpenShell sends the requested hostname to the corporate proxy instead of the validated address, which reopens proxy-side DNS resolution; the upstream source records that residual risk at [`crates/openshell-supervisor-network/src/proxy.rs:3168-3200`](https://github.com/NVIDIA/OpenShell/blob/8c7dd148a9e6360c9d5b2830e339a0dc4b3f3032/crates/openshell-supervisor-network/src/proxy.rs#L3168-L3200).
When enabled, OpenShell sends the requested hostname to the corporate proxy instead of the validated address, which reopens proxy-side DNS resolution; the upstream source records that residual risk at [`crates/openshell-supervisor-network/src/proxy.rs:3168-3200`](https://github.com/NVIDIA/OpenShell/blob/8ddd98c3dff62619a3963f99ba1e055b67650e72/crates/openshell-supervisor-network/src/proxy.rs#L3168-L3200).
NemoClaw does not enable or prohibit that host-level OpenShell option, so operators who require the pinned-address guarantee must leave it disabled and ensure their gateway configuration does not enable it.

### Stable OpenShell 0.0.99 Limitations
### Stable OpenShell 0.0.101 Limitations

OpenShell v0.0.99 attributes network policy with `/proc/<pid>/exe` and process ancestors, so script-based adapters require Node or Python interpreter grants rather than immutable package-entrypoint identities.
OpenShell v0.0.101 attributes network policy with `/proc/<pid>/exe` and process ancestors, so script-based adapters require Node or Python interpreter grants rather than immutable package-entrypoint identities.
NemoClaw compensates with an exact HTTPS destination, path, MCP method profile, DNS pins, and a unique least-privilege credential for each server.

Remove the interpreter grants when OpenShell exposes stable script or package entrypoint attribution.

OpenShell v0.0.99 attaches static provider credentials at sandbox scope rather than reserving a credential key exclusively for one endpoint.
OpenShell v0.0.101 attaches static provider credentials at sandbox scope rather than reserving a credential key exclusively for one endpoint.
It also does not expose an immutable provider binding on an attachment.

NemoClaw rejects credential-key reuse between managed MCP servers, creates a dedicated provider for each definition, reports the residual risk in `status`, and requires a unique least-privilege token and environment key.
Do not grant a broader inspected-HTTP route to the same adapter runtime because that route could resolve the sandbox-scoped placeholder.

OpenShell v0.0.99 updates, attaches, detaches, and deletes providers by mutable name instead of an atomic immutable identity.
OpenShell v0.0.101 updates, attaches, detaches, and deletes providers by mutable name instead of an atomic immutable identity.
NemoClaw compensates with randomized provider names, the per-sandbox lifecycle lock, and immediate ownership checks against the recorded provider ID, type, and credential-key metadata before mutations.

NemoClaw fails closed and preserves retryable state when those checks do not match, but the checks do not provide compare-and-swap behavior against another OpenShell client.
Expand Down
Loading
Loading