diff --git a/.agents/skills/nemoclaw-contributor-update-dependencies/SKILL.md b/.agents/skills/nemoclaw-contributor-update-dependencies/SKILL.md index 21d7700518f..c716b88ac18 100644 --- a/.agents/skills/nemoclaw-contributor-update-dependencies/SKILL.md +++ b/.agents/skills/nemoclaw-contributor-update-dependencies/SKILL.md @@ -71,6 +71,16 @@ Pass the reviewed absolute Git and gh executable paths. Preserve its minimal all environments and its byte and record ceilings. Keep private report permissions at mode 0600. Follow the current collector help when those controls evolve. +## Keep Review Evidence out of Public Documentation + +Do not write release ledgers, concern records, reviews, or qualification reports under `docs/`; they are maintainer evidence. Keep temporary evidence outside the repository with private permissions. +For Fern, do not create a dependency review document or durable review ledger. Keep Fern upgrade +evidence in the pull request description and executable configuration and publishing tests. Put +other durable records in `internal/security-reviews/`, by the owning component, or in the pull request description. + +For a user-visible change, update the canonical `docs/` page with supported behavior and operator action. +Do not publish review chronology or concern ledgers, add internal evidence to `docs/index.yml`, or link to it from public documentation. + ## Resolve concerns Use [Contract audit](references/contract-audit.md) to select the relevant risk surfaces and record diff --git a/Dockerfile b/Dockerfile index d4193dc3ab5..4da69d44984 100644 --- a/Dockerfile +++ b/Dockerfile @@ -603,7 +603,7 @@ ENV AWS_EC2_METADATA_DISABLED=true COPY --from=builder /usr/local/bin/node /usr/local/bin/node # Dependency review evidence for this runtime pin lives in -# docs/security/openclaw-2026.7.1-dependency-review.md. +# internal/security-reviews/openclaw-2026.7.1-dependency-review.md. ARG OPENCLAW_VERSION=2026.7.1 ARG OPENCLAW_2026_7_1_INTEGRITY=sha512-ge/Xss99CHAjPL/ikmH/UFoiOrjcxDB4sW3y9mhyCD+dYW3wzV7TKbAVdkrXFgAG2d2BjpJofP97zUZ+umxo8g== ARG OPENCLAW_2026_7_1_TARBALL=https://registry.npmjs.org/openclaw/-/openclaw-2026.7.1.tgz diff --git a/Dockerfile.base b/Dockerfile.base index db07a32ad32..0a3515a57e9 100644 --- a/Dockerfile.base +++ b/Dockerfile.base @@ -380,7 +380,7 @@ RUN chmod 444 /usr/local/lib/nemoclaw/sandbox-rlimits.sh \ # the base image on push to main, or use workflow_dispatch on base-image.yaml # with the openclaw_version input for a one-off build without editing this file. # Dependency review evidence for this runtime pin lives in -# docs/security/openclaw-2026.7.1-dependency-review.md. +# internal/security-reviews/openclaw-2026.7.1-dependency-review.md. ARG OPENCLAW_VERSION=2026.7.1 ARG OPENCLAW_2026_7_1_INTEGRITY=sha512-ge/Xss99CHAjPL/ikmH/UFoiOrjcxDB4sW3y9mhyCD+dYW3wzV7TKbAVdkrXFgAG2d2BjpJofP97zUZ+umxo8g== ARG OPENCLAW_2026_7_1_TARBALL=https://registry.npmjs.org/openclaw/-/openclaw-2026.7.1.tgz diff --git a/docs/changelog/2026-06-30.mdx b/docs/changelog/2026-06-30.mdx index 9b70f7b502a..cb78e4b2dc8 100644 --- a/docs/changelog/2026-06-30.mdx +++ b/docs/changelog/2026-06-30.mdx @@ -12,7 +12,7 @@ NemoClaw v0.0.71 improves gateway recovery, OpenShell gateway authentication, po For more information, refer to [Recover and Rebuild Sandboxes](/user-guide/openclaw/manage-sandboxes/operate-sandboxes/recover-and-rebuild-sandboxes), [NemoClaw CLI Commands Reference](/user-guide/openclaw/reference/commands), [Troubleshooting](/user-guide/openclaw/reference/troubleshooting), and [Trusted Computing Base](/user-guide/openclaw/security/trusted-computing-base). - OpenShell 0.0.71 is the validated gateway release for this train. NemoClaw generates local TLS, mTLS, and sandbox JWT material for Docker-driver gateways, keeps gateway binds on loopback while JWT auth is active, and documents the explicit compatibility-container boundary for older trusted Linux hosts. - For more information, refer to [OpenShell 0.0.71 Review](/user-guide/openclaw/security/openshell-0.0.71-gateway-auth-review), [Security Best Practices](/user-guide/openclaw/security/best-practices), and [Troubleshooting](/user-guide/openclaw/reference/troubleshooting). + For more information, refer to [Gateway and Secret Controls](/user-guide/openclaw/security/security-controls/gateway-authentication-controls), [Security Best Practices](/user-guide/openclaw/security/best-practices), and [Troubleshooting](/user-guide/openclaw/reference/troubleshooting). - Network policy output now explains why active presets are present. `policy-list` annotates verified active presets with tier, agent, user-added, or source-unverified provenance; Restricted onboarding suppresses agent-required preset additions; the Balanced tier no longer includes `weather`; and the `weather` preset covers read-only `wttr.in` lookups when you add it explicitly. For more information, refer to [Network Policies](/user-guide/openclaw/reference/network-policies), [NemoClaw CLI Commands Reference](/user-guide/openclaw/reference/commands), and [Common NemoClaw Integration Policy Examples](/user-guide/openclaw/network-policy/integration-policy-examples). diff --git a/docs/changelog/2026-07-04.mdx b/docs/changelog/2026-07-04.mdx index 338f1bf6332..ecee56c51f1 100644 --- a/docs/changelog/2026-07-04.mdx +++ b/docs/changelog/2026-07-04.mdx @@ -9,7 +9,7 @@ NemoClaw v0.0.74 upgrades the OpenShell policy boundary, adds managed MCP and pr - Stable installs pin OpenShell `0.0.72` release artifacts and the supervisor image, adding MCP Streamable HTTP and JSON-RPC request-policy enforcement. Policy mutations read the round-trippable base policy instead of the effective policy, which preserves existing MCP rules without sending provider-composed `_provider_*` entries back through `policy set`. - For more information, refer to [OpenShell 0.0.72 Compatibility Review](/user-guide/openclaw/security/openshell-0.0.72-compatibility-review) and [Replace the Live Network Policy](/user-guide/openclaw/network-policy/configure-policies/replace-live-network-policy). + For more information, refer to [Network Policies](/user-guide/openclaw/reference/network-policies) and [Replace the Live Network Policy](/user-guide/openclaw/network-policy/configure-policies/replace-live-network-policy). - Managed MCP commands use `add`, `list`, `status`, `restart`, and `remove` to manage authenticated HTTPS Streamable HTTP servers for OpenClaw, Hermes, and experimental LangChain Deep Agents Code through native OpenShell policy enforcement and provider-backed credential replacement. The LangChain Deep Agents Code rebuild path validates the recorded gateway, route, image, staged build context, and prepared replacement inputs before deleting the previous sandbox, then restores managed MCP state after the recreated runtime is ready. For more information, refer to [About Managed MCP Servers](/user-guide/openclaw/manage-sandboxes/mcp-servers/about-managed-mcp-servers), [Quickstart with LangChain Deep Agents Code](/user-guide/deepagents/get-started/quickstart), and the [accepted architecture decision](https://github.com/NVIDIA/NemoClaw/issues/566#issuecomment-4847534784). diff --git a/docs/changelog/2026-07-06.mdx b/docs/changelog/2026-07-06.mdx index 0bed2bd2e49..eca9f3ef245 100644 --- a/docs/changelog/2026-07-06.mdx +++ b/docs/changelog/2026-07-06.mdx @@ -8,14 +8,13 @@ NemoClaw v0.0.75 upgrades the bundled OpenClaw runtime to `2026.6.10` and improves sandbox upgrade and prepared-backup recovery, custom endpoint inference routing, and local Docker-driver sandbox JWT handling. - The bundled OpenClaw runtime upgrades to `2026.6.10` with reviewed package pins, fail-closed archive and patch validation, safer same-device pairing repair, and stricter rebuild route and credential recovery. - For more information, refer to the [OpenClaw 2026.6.10 Dependency Review](https://github.com/NVIDIA/NemoClaw/blob/main/docs/security/openclaw-2026.6.10-dependency-review.md). - Upgrading an existing install now recovers a previously onboarded sandbox instead of failing when the recreated gateway has not yet reconfigured its inference route. Prepared-backup recovery defers the live route check to authoritative onboarding, which restores and verifies the gateway provider and inference route before sandbox recreation; in-place upgrades recover gateway-orphaned sandboxes, and a same-name `--fresh` re-onboard preserves the newly selected LangChain Deep Agents Code routing. For more information, refer to [NemoClaw CLI Commands Reference](/user-guide/openclaw/reference/commands) and [Troubleshooting](/user-guide/openclaw/reference/troubleshooting). - Hermes custom Anthropic-compatible inference now uses the OpenAI frontend, and OpenAI-only agents keep the `/v1` base URL when pointed at an Anthropic-compatible endpoint, so switching a managed sandbox to a compatible endpoint routes and reports the provider and model correctly. For more information, refer to [Choose an Inference Provider](/user-guide/openclaw/inference/learn-and-choose/choose-inference-provider) and [Switch Inference Providers](/user-guide/openclaw/inference/manage-inference/switch-providers). - Local Docker-driver sandbox JWTs now use OpenShell's non-expiring local contract, which keeps a long-running local sandbox reachable without a manual gateway restart. - For more information, refer to [OpenShell 0.0.71 Gateway Authentication Review](/user-guide/openclaw/security/openshell-0.0.71-gateway-auth-review). + For more information, refer to [Gateway and Secret Controls](/user-guide/openclaw/security/security-controls/gateway-authentication-controls). - Hermes runtime and managed MCP state reconcile after a runtime change, and Hermes installs accept a pinned base platform digest. For more information, refer to [About Managed MCP Servers](/user-guide/openclaw/manage-sandboxes/mcp-servers/about-managed-mcp-servers) and [NemoClaw CLI Commands Reference](/user-guide/openclaw/reference/commands). - OpenClaw local CLI pairing restores its previous connection path so a local sandbox reconnects without re-pairing. diff --git a/docs/changelog/2026-07-14.mdx b/docs/changelog/2026-07-14.mdx index 6d2f57ffae6..0cbeb1a0ce5 100644 --- a/docs/changelog/2026-07-14.mdx +++ b/docs/changelog/2026-07-14.mdx @@ -69,4 +69,3 @@ NemoClaw v0.0.82 adds non-destructive sandbox stop and start commands, protects - Build and dependency trust boundaries cover more of the sandbox image path. Reviewed npm archives now share one production dependency audit, OpenClaw's managed WeChat runtime installs from a NemoClaw-owned offline lock, and the messaging build plan no longer persists in final OpenClaw or Hermes image environments. Source and blueprint rebuilds also reuse cached plugin dependency layers. - For more information, refer to the [OpenClaw 2026.6.10 Dependency Review](https://github.com/NVIDIA/NemoClaw/blob/main/docs/security/openclaw-2026.6.10-dependency-review.md). diff --git a/docs/changelog/2026-07-20.mdx b/docs/changelog/2026-07-20.mdx index 97300c5ff59..26459272ef8 100644 --- a/docs/changelog/2026-07-20.mdx +++ b/docs/changelog/2026-07-20.mdx @@ -12,7 +12,6 @@ NemoClaw v0.0.90 keeps managed-image routing identifiers out of secret-shaped bu For more information, refer to the [NemoClaw CLI Commands Reference](/user-guide/openclaw/reference/commands). - OpenClaw core, Slack, and Microsoft Teams installations now replace reviewed vulnerable transitive packages with integrity-verified remediated versions while retaining the `openclaw@2026.6.10` release pin. Archive validation fails closed, and the dependency audit records the remaining reviewed low- and moderate-severity findings. - For more information, refer to the [OpenClaw 2026.6.10 Dependency Review](https://github.com/NVIDIA/NemoClaw/blob/main/docs/security/openclaw-2026.6.10-dependency-review.md). - `credentials reset` now recognizes sandbox attachments from wrapped OpenShell diagnostics, validates each sandbox name, detaches affected sandboxes, and retries provider deletion without exposing credential values. For more information, refer to [Credential Rotation](/user-guide/openclaw/security/credential-rotation). - OpenClaw WhatsApp status now recognizes the current paired-session path and derives in-process bridge activity from redacted gateway-log evidence. diff --git a/docs/changelog/2026-07-22.mdx b/docs/changelog/2026-07-22.mdx index eb406ea8297..82c1f5ad47e 100644 --- a/docs/changelog/2026-07-22.mdx +++ b/docs/changelog/2026-07-22.mdx @@ -34,7 +34,6 @@ NemoClaw v0.0.91 strengthens completed sandbox images, makes rebuild replacement - Completed OpenClaw, Hermes, and Deep Agents Code images now replace affected `node-tar` installations with reviewed versions and scan the final filesystem before publication. Current and historical OpenClaw security-revision verifiers also validate exact dependency versions, resolved archives, integrity metadata, executable identity, and transactional state restoration in constrained containers. - For more information, refer to the [OpenClaw 2026.6.10 Dependency Review](https://github.com/NVIDIA/NemoClaw/blob/main/docs/security/openclaw-2026.6.10-dependency-review.md). - Rebuilds now carry validated local-base trust through Deep Agents Code image preparation, reuse the outer state backup during inner onboarding, and wait for OpenShell to confirm sandbox deletion before removing registry state or creating a replacement. These checks prevent rebuild from rejecting its own current base, taking a second backup against stale gateway state, or racing an asynchronous sandbox deletion. Rebuild also stops before deletion when a manifest-declared state file cannot be archived unless you pass `--force`. diff --git a/docs/changelog/2026-08-04.mdx b/docs/changelog/2026-08-04.mdx index e443cc30de0..a6e2d72ea65 100644 --- a/docs/changelog/2026-08-04.mdx +++ b/docs/changelog/2026-08-04.mdx @@ -46,7 +46,6 @@ It reduces the managed single-node DGX Spark Qwen profile's default memory deman For more information, refer to [Set Up WhatsApp](/user-guide/hermes/manage-sandboxes/messaging-channels/set-up-whatsapp), the Hermes [NemoClaw CLI Commands Reference](/user-guide/hermes/reference/commands), and [Configure Corporate CA Trust](/user-guide/deepagents/security/configure-corporate-ca-trust). - Managed OpenClaw, Hermes, Deep Agents Code, and MCP discovery images now carry reviewed dependency updates for the release advisory set. The changes update locked runtime graphs, remediate private npm dependencies during image assembly, and preserve fail-closed identity and integrity checks. - For more information, refer to the [OpenClaw 2026.7.1 Dependency Review](https://github.com/NVIDIA/NemoClaw/blob/main/docs/security/openclaw-2026.7.1-dependency-review.md) and [Hermes 0.19.0 Dependency Review](https://github.com/NVIDIA/NemoClaw/blob/main/docs/security/hermes-0.19.0-dependency-review.md). - Affected CLI paths now report invalid enumerated values, unresolved sandbox base images, and changed gateway authority without raw Node.js stack traces. Captured output from non-JSON OpenClaw agent commands is inspected for recognized embedded-fallback markers. When a marker is present, NemoClaw suppresses the captured transport output, exits with status `1`, and prints the documented recovery commands. diff --git a/docs/index.yml b/docs/index.yml index a5a5e06e94e..69833e07d5e 100644 --- a/docs/index.yml +++ b/docs/index.yml @@ -368,12 +368,6 @@ navigation: - page: "Trusted Computing Base" path: _build/agent-variants/security/tcb-boundary.openclaw.generated.mdx slug: trusted-computing-base - - page: "OpenShell 0.0.72 Compatibility Review" - path: _build/agent-variants/security/openshell-0.0.72-compatibility-review.openclaw.generated.mdx - slug: openshell-0.0.72-compatibility-review - - page: "OpenShell 0.0.71 Review" - path: _build/agent-variants/security/openshell-0.0.71-gateway-auth-review.openclaw.generated.mdx - slug: openshell-0.0.71-gateway-auth-review - page: "OpenClaw Controls" path: security/openclaw-controls.mdx slug: openclaw-controls @@ -720,9 +714,6 @@ navigation: - page: "Trusted Computing Base" path: _build/agent-variants/security/tcb-boundary.deepagents.generated.mdx slug: trusted-computing-base - - page: "OpenShell 0.0.72 Compatibility Review" - path: _build/agent-variants/security/openshell-0.0.72-compatibility-review.deepagents.generated.mdx - slug: openshell-0.0.72-compatibility-review - section: "Reference" slug: reference collapsed: open-by-default @@ -1117,12 +1108,6 @@ navigation: - page: "Trusted Computing Base" path: _build/agent-variants/security/tcb-boundary.hermes.generated.mdx slug: trusted-computing-base - - page: "OpenShell 0.0.72 Compatibility Review" - path: _build/agent-variants/security/openshell-0.0.72-compatibility-review.hermes.generated.mdx - slug: openshell-0.0.72-compatibility-review - - page: "OpenShell 0.0.71 Review" - path: _build/agent-variants/security/openshell-0.0.71-gateway-auth-review.hermes.generated.mdx - slug: openshell-0.0.71-gateway-auth-review - section: "Reference" slug: reference collapsed: open-by-default diff --git a/docs/reference/commands.mdx b/docs/reference/commands.mdx index 86d74a310ba..278d4b560d3 100644 --- a/docs/reference/commands.mdx +++ b/docs/reference/commands.mdx @@ -4708,7 +4708,7 @@ Set them before running `$$nemoclaw onboard`. | `NEMOCLAW_SANDBOX_BASE_IMAGE_REFRESH` | `1`, `true`, `yes`, or `on` to enable | Bypasses recorded sandbox base-image resolution metadata during onboarding, recreation, and rebuild. NemoClaw reruns candidate resolution but can still use a compatible image from Docker's local image store. Versioned release candidates that exist locally but fail validation are refreshed from the registry once during normal resolution. This setting does not discard onboarding session state. | | `NEMOCLAW_SANDBOX_BASE_LOCAL_BUILD` | unset or `auto` (default); `1`, `true`, `yes`, or `on` to enable; `0`, `false`, `no`, or `off` to disable | Controls whether base-image resolution may build a compatible image locally. The default allows builds during normal CLI runs and disables them when `NODE_ENV=test` or `VITEST=true`. When source inputs or a missing/incompatible release-version base require a fresh build, disabling local builds makes resolution fail instead of using an unproven image. | | `NEMOCLAW_DOCKER_GPU_PATCH` | unset, `auto`, `fallback`, `1`, or `0`; other legacy nonzero values remain accepted through `v0.0.x` and will be removed in `v0.1.0` | Selects Linux Docker-driver GPU routing. Unset, `auto`, or `0` uses native OpenShell GPU injection on ordinary native Linux. `fallback` explicitly opts into one native attempt followed by one bounded compatibility retry when trusted host evidence identifies a GPU-routing failure. `1` and legacy nonzero values select the compatibility patch from the outset. Docker Desktop WSL and Jetson/Tegra use the compatibility path by default; Docker Desktop WSL ignores `0`, while Jetson/Tegra accepts `0` only as a troubleshooting override that bypasses device-group propagation. | -| `NEMOCLAW_OPENSHELL_GATEWAY_CONTAINER_PATCH` | `1` to enable; disabled by default | This setting explicitly opts into the Linux gateway compatibility container for an older host ABI or a diagnostic run; use it only on a trusted local host because it uses host networking and mounts the Docker socket read-only even though the socket still exposes the privileged Docker API; prefer OpenShell 0.0.101's directly supported glibc 2.39+ path; see the [OpenShell gateway compatibility review](/user-guide/openclaw/security/openshell-0.0.72-compatibility-review#source-of-truth-boundaries) for the unchanged container boundary. | +| `NEMOCLAW_OPENSHELL_GATEWAY_CONTAINER_PATCH` | `1` to enable; disabled by default | This setting explicitly opts into the Linux gateway compatibility container for an older host ABI or a diagnostic run; use it only on a trusted local host because it uses host networking and mounts the Docker socket read-only even though the socket still exposes the privileged Docker API; prefer OpenShell 0.0.101's directly supported glibc 2.39+ path; see [Gateway Compatibility Container](/user-guide/openclaw/security/security-controls/gateway-authentication-controls#gateway-compatibility-container) for the container boundary and removal conditions. | | `NEMOCLAW_OPENSHELL_GATEWAY_BIN` | path | Advanced override for the `openshell-gateway` binary used by Linux Docker-driver startup. For the default port, the installer accepts the binary under an absolute `XDG_BIN_HOME` when set, otherwise `~/.local/bin/openshell-gateway`; it also accepts `/usr/local/bin/openshell-gateway` or `/usr/bin/openshell-gateway`. Another path fails service staging. The macOS Homebrew service uses the formula's binary. Defaults to the binary next to `openshell`, then common install paths. | | `NEMOCLAW_OPENSHELL_SANDBOX_BIN` | path | Advanced override for the `openshell-sandbox` binary used by Linux Docker-driver startup. The macOS Homebrew service uses the formula's driver layout. Defaults to the binary next to `openshell`, then common install paths. | | `NEMOCLAW_OPENSHELL_GATEWAY_STATE_DIR` | path | Advanced override for the Linux Docker-driver gateway SQLite state directory and standalone-fallback PID file. Defaults to `~/.local/state/nemoclaw/openshell-docker-gateway`. | diff --git a/docs/reference/troubleshooting.mdx b/docs/reference/troubleshooting.mdx index 6ce087c432e..06a7b106de7 100644 --- a/docs/reference/troubleshooting.mdx +++ b/docs/reference/troubleshooting.mdx @@ -377,7 +377,7 @@ Leave it unset on supported hosts. The compatibility container uses host networking and mounts the host Docker socket read-only. A read-only socket mount still permits privileged Docker API operations and can control the host, so do not enable this mode on an untrusted or shared host. The gateway remains loopback-bound, and startup fails closed unless the configured Unix socket answers as a Docker daemon. -See the [OpenShell gateway compatibility review](../security/openshell-0.0.72-compatibility-review#source-of-truth-boundaries) for the unchanged container boundary and removal conditions. +See [Gateway Compatibility Container](../security/security-controls/gateway-authentication-controls#gateway-compatibility-container) for the container boundary and removal conditions. Refer to [Environment Variables](commands#environment-variables) for the full list of port overrides. diff --git a/docs/security/fern-5.80.1-dependency-review.md b/docs/security/fern-5.80.1-dependency-review.md deleted file mode 100644 index 58ca05715e7..00000000000 --- a/docs/security/fern-5.80.1-dependency-review.md +++ /dev/null @@ -1,162 +0,0 @@ - - - -# Fern 5.80.1 dependency review - -Review date: 2026-07-23 - -## Decision - -Pin the documentation tool to `fern-api@5.80.1`. -This replaces `5.72.1` without changing a supported NemoClaw runtime or product integration. -All production, staging, pull-request preview, validation, and local preview commands read the exact version from `fern/fern.config.json`. - -The upgrade spans 21 adjacent published versions and 225 source commits. -The review found no unresolved high-severity concerns. -The only accepted residuals are pre-existing properties of the upstream package: its optional BAML dependency uses a compatible range, and its provenance does not include an SBOM or the complete build dependency graph. -The point-in-time dependency closure is identical for `5.72.1` and `5.80.1` except for the root package version and integrity. - -## Reviewed identities - -The npm registry is the artifact authority. -Fern does not publish semantic Git tags for these CLI versions, so the npm provenance source commits define the release boundaries. - -| Identity | Value | -| --- | --- | -| Current package | `fern-api@5.72.1` | -| Current source commit | `238ff9d037fc7653661a6850dc6dab47712b5bfb` | -| Current integrity | `sha512-b8qOEZ5vYQ7k0cbQMlS9sLEqyj0mdA+bjDZAPHqd5CpMeNO1tgFMp8shFLGVS7FHxUNmjxOVLxyXnduwTe3tuQ==` | -| Target package | `fern-api@5.80.1` | -| Target source commit | `76de91e1216afbdb56a36d3389ee6b91d3e59a9e` | -| Target integrity | `sha512-1GZglZnA8T1JogREverqNwIY5G9e3e6uRHv1bpMjX0iIJVr+Dh+5MMPSBq6NegTmBjppqRHF6PVNbnuuO9VfRA==` | -| Target SHA-1 | `a06a295390f91b8bbd42de56d0d481f545642595` | -| Target publish time | `2026-07-23T19:39:21.720Z` | -| Target provenance workflow | `.github/workflows/publish-cli.yml` | -| Target provenance run | `30038076483`, attempt `1`, successful push to `main` | - -The current and target archives each contain only `cli.cjs`, `package.json`, and `LICENSE`. -`cli.cjs` is the only executable. -Neither archive contains links, devices, unsafe paths, install scripts, a `NOTICE` file, or an SBOM. -Both packages declare Apache-2.0 and expose `fern` through `cli.cjs`. - -`npm audit signatures` reports zero invalid and zero missing signatures for both installed graphs. -Their npm signatures and SLSA provenance bind the registry artifacts to the source commits above. -The target provenance run completed successfully with the attested head commit on `main`. - -## Complete source range ledger - -Every adjacent comparison is contiguous: each target is ahead of its source with `behind_by=0`, and local ancestry checks agree. -A full sanitized upstream clone passed `git fsck --full --strict`; no upstream code was executed. - -| Range and source commits | Commits | NemoClaw-relevant change | -| --- | ---: | --- | -| `5.72.1` (`238ff9d`) to `5.73.0` (`60a6649`) | 15 | GitHub OIDC variables reach local generator containers; NemoClaw does not use this generator path. | -| `5.73.0` (`60a6649`) to `5.74.0` (`0ed4690`) | 15 | Webhook body hashes; no NemoClaw API or webhook generation. | -| `5.74.0` (`0ed4690`) to `5.74.1` (`63b552f`) | 2 | Generator attribution fix; no NemoClaw generator manifest. | -| `5.74.1` (`63b552f`) to `5.74.2` (`9b116de`) | 10 | OpenAPI union import fix; NemoClaw publishes documentation only. | -| `5.74.2` (`9b116de`) to `5.74.3` (`5802970`) | 13 | Internal docs publish logs move from info to debug; exit behavior is unchanged. | -| `5.74.3` (`5802970`) to `5.75.0` (`ec8bd05`) | 2 | Optional smart casing, disabled by default and absent from NemoClaw config. | -| `5.75.0` (`ec8bd05`) to `5.75.1` (`ddc0b4e`) | 22 | Theme uploads use an organization-scoped content-addressed path and explicit origin precedence. | -| `5.75.1` (`ddc0b4e`) to `5.75.2` (`c378ff0`) | 2 | Import warning for unmapped unions; no NemoClaw API import. | -| `5.75.2` (`c378ff0`) to `5.75.3` (`c4f032d`) | 2 | OpenAPI `allOf` example performance; no NemoClaw API import. | -| `5.75.3` (`c4f032d`) to `5.75.4` (`94fd7e3`) | 3 | `fern check` compiles MDX and reports malformed MDX as warnings. | -| `5.75.4` (`94fd7e3`) to `5.75.5` (`02364eb`) | 20 | Faster content-only reloads for `fern docs dev`; publish behavior is unchanged. | -| `5.75.5` (`02364eb`) to `5.75.6` (`36b3a5e`) | 15 | PHP package naming; no NemoClaw generator manifest. | -| `5.75.6` (`36b3a5e`) to `5.75.7` (`527c2ca`) | 3 | Generator changelog and header fix; no NemoClaw generator manifest. | -| `5.75.7` (`527c2ca`) to `5.75.8` (`474447f`) | 2 | Multi-API environment grouping; no NemoClaw API configuration. | -| `5.75.8` (`474447f`) to `5.75.9` (`bfa7994`) | 2 | Generator-specific follow-up; no NemoClaw generator manifest. | -| `5.75.9` (`bfa7994`) to `5.76.0` (`5416ce9`) | 3 | Webhook URL normalization; no NemoClaw webhook generation. | -| `5.76.0` (`5416ce9`) to `5.77.0` (`c031254`) | 34 | Optional OpenAPI tag filtering; no NemoClaw API import. | -| `5.77.0` (`c031254`) to `5.78.0` (`db64dc1`) | 7 | OpenAPI path-parameter deconfliction; no NemoClaw API import. | -| `5.78.0` (`db64dc1`) to `5.79.0` (`1d6a7e7`) | 6 | Optional external sitemaps; absent from NemoClaw config. | -| `5.79.0` (`1d6a7e7`) to `5.80.0` (`35b6f73`) | 26 | Optional navigation availability badges, disabled by default and absent from NemoClaw config. | -| `5.80.0` (`35b6f73`) to `5.80.1` (`76de91e`) | 21 | Preserve nested `allOf` descriptions in generated API docs; no NemoClaw API import. | - -The repository's documented release-ledger collector is not present on the reviewed `main` branch. -The audit therefore used equivalent read-only npm registry and GitHub API evidence plus the sanitized local clone. -This method exception changes how the ledger was collected, not its release boundaries or coverage. - -## Dependency closure and advisory result - -Lifecycle scripts were disabled while materializing both exact graphs. -Each graph contains 11 packages: - -- `@boundaryml/baml@0.219.0`; -- eight matching `@boundaryml/baml-*` platform packages at `0.219.0`; -- `@scarf/scarf@1.4.0`; -- the selected `fern-api` version. - -All transitive versions and licenses are identical between current and target. -The BAML packages are MIT and Scarf is Apache-2.0. -`npm audit --omit=dev` reports zero info, low, moderate, high, or critical findings for both graphs. - -The package declares optional `@boundaryml/baml@^0.219.0`, so a future fresh `npx` install could select a later compatible BAML release. -This is a pre-existing reproducibility residual, not a change introduced by `5.80.1`. -NemoClaw pins Fern exactly, uses it only as contributor and CI documentation tooling, and does not ship this graph in its CLI, plugin, blueprint, or runtime images. - -## Downstream contract audit - -`fern/fern.config.json` is the single version authority. -The following consumers all read that file before constructing an exact `fern-api@` selector: - -- the `docs:deps`, `docs:validate`, `docs:live`, and `docs:preview:watch` npm scripts; -- public and staging publication; -- pull-request previews; -- staging preview deletion. - -No lockfile, generated manifest, workflow input, environment default, cache key, or runtime image contains a second production Fern version. -The synthetic `3.67.1` in `test/fern-preview-config.test.ts` is an opaque unit-test input, not a production selector. - -NemoClaw has no Fern API definition or generator manifest. -Its Fern tree contains only the docs configuration, theme assets, components, and CSS. -Consequently, the OpenAPI, webhook, SDK generator, and multi-API changes in the range cannot affect a shipped artifact. - -The CLI emits human-readable logs, but NemoClaw does not parse them. -Workflows use the process exit status; the pull-request preview workflow captures output only to publish the preview URL. -The upstream log-level reduction therefore does not change a machine-consumed contract. - -## Concern ledger - -| ID | Severity | Failure mode | Evidence and disposition | -| --- | --- | --- | --- | -| `FERN-1` | Medium | Changed publish logging could break an output parser | No consumer parses publish log text; exit status and preview URL behavior remain authoritative, so there is no impact. | -| `FERN-2` | Medium | MDX compilation during `fern check` could expose invalid current docs | `npm run docs` passes with the target CLI, and current and target report the same two pre-existing warnings and zero errors, which resolves the concern with runtime proof. | -| `FERN-3` | Medium | Theme upload or preview behavior could target the wrong organization or URL | Upstream adds organization scoping and regression tests, while NemoClaw's staging deletion workflow remains covered with executed fake-CLI arguments as runtime proof. | -| `FERN-4` | Low | Incremental local preview state could serve stale content | The change is limited to `docs dev` content reloads, does not persist release state, and leaves local preview as an advisory developer surface, so there is no impact. | -| `FERN-5` | Low | New sitemap or navigation options could change the published site by default | Both settings are optional, availability badges default to false, and neither key is present in `fern/docs.yml`, so there is no impact. | -| `FERN-6` | Low | API importer and generator changes could alter generated SDK or API documentation | NemoClaw has no Fern API definition or generator manifest, so there is no impact. | -| `FERN-7` | Medium | The target archive or dependency graph could be substituted or add a vulnerable package | Registry integrity, npm signatures, SLSA provenance, the successful producer run, archive structure, licenses, and both exact graphs were verified, which resolves the concern. | -| `FERN-8` | Low | A hard-coded test version could drift from the production version authority | The staging workflow test now derives its expected exact selector from `fern/fern.config.json`, which resolves the concern. | -| `FERN-9` | Low | A persisted cache or migration could retain incompatible Fern state | Fern caches and generated docs are disposable build outputs with no migration, rollback data, or product state, so there is no impact. | -| `FERN-10` | Low | Live sandbox E2E exclusion could leave a runtime behavior untested | Fern is docs-only tooling that never runs inside a NemoClaw sandbox, so docs validation and workflow contract tests are the relevant lanes and live E2E is excluded. | - -Unresolved high-severity concerns: `0`. - -## Verification and remaining gates - -Completed audit evidence: - -- 21 adjacent source ranges and 225 commits reviewed; -- target SHA-1 and SHA-512 matched the downloaded archive; -- package structure and licenses inspected without executing upstream code; -- npm signatures and SLSA provenance verified for current and target; -- source provenance runs checked for successful completion and matching heads; -- full current and target dependency closures compared; -- current and target advisory audits reported zero findings. -- six focused dependency-review and staging workflow tests passed; -- source-shape validation reported no unapproved source-shape tests; -- Vitest project membership was exact across all eight projects; -- `npm run docs` passed with `fern-api@5.80.1`. -- `npm run check:diff` passed after generating the isolated worktree's local compiled artifacts. - -`fern check --warnings` reports zero errors and the same two warnings under both `5.72.1` and `5.80.1`: unauthenticated local validation cannot check remote redirects, and the existing light-theme accent contrast is 2.41:1. -Neither warning is introduced by this dependency change. -Authenticated publication and preview checks remain GitHub gates. - -Before merge, the reviewed PR head must still pass: - -- normal commit hooks and required GitHub checks; -- automated review with no unresolved actionable finding; -- documentation writer review. - -No live E2E, sandbox build, migration, rollback, compatibility shim, or changelog entry is required because the dependency is not part of a supported runtime or user-visible product behavior. diff --git a/docs/security/fern-5.92.4-dependency-review.md b/docs/security/fern-5.92.4-dependency-review.md deleted file mode 100644 index 2c88d2debdb..00000000000 --- a/docs/security/fern-5.92.4-dependency-review.md +++ /dev/null @@ -1,145 +0,0 @@ - - - -# Fern 5.92.4 Dependency Review - -Review date: 2026-08-10 - -## Decision - -Pin the documentation tool to `fern-api@5.92.4`. -This replaces `5.80.1` without changing a supported NemoClaw runtime or product integration. -All production, staging, pull-request preview, validation, and local preview commands read the version from `fern/fern.config.json`. - -The upgrade spans 194 contiguous source commits. -The review found no unresolved high-severity concerns. -The archive structure, dependency closure, lifecycle-script surface, and licenses are unchanged. -The Fern root package version, archive bytes, and integrity values differ. -Versions `5.92.3` and `5.92.4` correct Markdown image destinations with bracketed alternative text and angle-bracket delimiters, so `5.92.4` is the reviewed target. - -## Reviewed Identities - -The npm registry is the artifact authority. -Fern does not publish semantic Git tags for these CLI versions, so npm provenance identifies the source revisions. - -| Identity | Value | -| --- | --- | -| Current package | `fern-api@5.80.1` | -| Current source commit | `76de91e1216afbdb56a36d3389ee6b91d3e59a9e` | -| Current integrity | `sha512-1GZglZnA8T1JogREverqNwIY5G9e3e6uRHv1bpMjX0iIJVr+Dh+5MMPSBq6NegTmBjppqRHF6PVNbnuuO9VfRA==` | -| Target package | `fern-api@5.92.4` | -| Target source commit | `f501eb09d3a31776d54beaa70346af4174d09664` | -| Target integrity | `sha512-+vOR7M+G98poLJTSnyx2gw3Si+5AT/cTF7yRAdFst+977+DsTxWmUDx4RtajvR75EFqEOERwUcmDDUa2vCUerw==` | -| Target SHA-1 | `fd89c28f9f72d41be7d0a021da3a0136f88027c9` | -| Target publish time | `2026-08-10T22:34:31.983Z` | -| Target provenance workflow | `.github/workflows/publish-cli.yml` | -| Target provenance run | `31437991221`, attempt `1`, successful push to `main` | - -The current and target archives each contain only `cli.cjs`, `package.json`, and `LICENSE`. -`cli.cjs` is the only executable. -Neither archive contains links, devices, unsafe paths, install scripts, a `NOTICE` file, or an SBOM. -Both archives include an Apache-2.0 license and expose `fern` through `cli.cjs`. - -`npm audit signatures` reports verified registry signatures for all four packages installed on the review host and verified attestations for three. -The target npm provenance binds the registry artifact to the source revision and a successful GitHub-hosted publication run on `main`. - -## Complete Source Range Ledger - -Every range is contiguous, reports `behind_by=0`, and starts at the preceding range's endpoint. -The five ranges cover all 194 commits between the reviewed packages. - -| Range | Commits | NemoClaw-relevant change | -| --- | ---: | --- | -| `5.80.1` to `5.80.5` | 60 | Markdown image titles resolve correctly. Generator and API import changes do not apply to the NemoClaw docs-only configuration. | -| `5.80.5` to `5.86.0` | 42 | The CLI adds packaging, organization bounds, and OpenAPI options that NemoClaw does not invoke. | -| `5.86.0` to `5.89.6` | 40 | Named preview listing and Markdown substitution improve commands that NemoClaw uses. OAuth login and package-generation paths remain unused. | -| `5.89.6` to `5.92.2` | 46 | Git-ref docs versioning, MCP installation, and importer changes are inactive because NemoClaw does not configure or invoke them. Optional-request-body fixes do not affect this docs tree. | -| `5.92.2` to `5.92.4` | 6 | Markdown images with bracketed alternative text and angle-bracket destinations resolve correctly. | - -The published CLI source manifest adds only development dependencies for ZIP typing and implementation. -The published package still declares only the optional `@boundaryml/baml@^0.219.0` dependency. - -## Dependency Closure and Advisory Result - -Lifecycle scripts were disabled while materializing the current and target graphs. -Each graph contains 11 packages: - -- `@boundaryml/baml@0.219.0`; -- eight matching `@boundaryml/baml-*` platform packages at `0.219.0`; -- `@scarf/scarf@1.4.0`; -- the selected `fern-api` version. - -All transitive versions and licenses are identical between current and target. -The BAML packages use the MIT license, and Scarf uses Apache-2.0. -`npm audit --omit=dev` reports zero info, low, moderate, high, or critical findings for both graphs. - -The package still declares optional `@boundaryml/baml@^0.219.0`, so a future fresh `npx` install can select another compatible `0.219.x` release. -The currently resolved graph remains `0.219.0`. -This is a pre-existing reproducibility residual, not a change introduced by `5.92.4`. - -`@scarf/scarf@1.4.0` still has a best-effort postinstall telemetry script inherited through BAML. -The script honors `SCARF_ANALYTICS=false`, `SCARF_NO_ANALYTICS=true`, and `DO_NOT_TRACK=1`, redacts package names and paths before reporting, and does not fail installation when reporting fails. -NemoClaw's `npx` commands do not disable lifecycle scripts, so this remains a pre-existing low-severity side effect. -The target does not add or change that script or dependency path. - -NemoClaw pins Fern by version, uses it only for contributor and CI documentation tooling, and does not ship this graph in its CLI, plugin, blueprint, or runtime images. - -## Downstream Contract Audit - -`fern/fern.config.json` is the single version authority. -The following consumers read that file before constructing a versioned `fern-api` selector: - -- the `docs:deps`, `docs:validate`, `docs:live`, and `docs:preview:watch` npm scripts; -- public and staging publication; -- pull-request previews; -- staging preview deletion. - -No lockfile, generated manifest, workflow input, environment default, cache key, or runtime image contains a second production Fern version. -The synthetic `3.67.1` in `test/fern-preview-config.test.ts` is an opaque unit-test input, not a production selector. - -NemoClaw has no Fern API definition or generator manifest. -Its Fern tree contains docs configuration, theme assets, components, and CSS. -The API importer, SDK generator, OAuth login, MCP installation, packaging, and organization-management paths are therefore not invoked. - -The staging preview workflow uses named preview listing and deletion. -The relevant Fern changes preserve that contract, and NemoClaw tests the constructed command arguments. -Markdown-path fixes apply during docs validation and publication and are covered by the docs build. - -## Concern Ledger - -| ID | Severity | Failure mode | Evidence and disposition | -| --- | --- | --- | --- | -| `FERN-1` | Medium | New login or MCP commands could expose credentials during normal docs commands | NemoClaw does not invoke those commands, and no reviewed configuration activates them. Normal docs commands keep their existing entry points. | -| `FERN-2` | Medium | Git-ref docs versioning could publish a different source tree | NemoClaw does not configure the new `ref` field. Publication still checks out the repository revision selected by GitHub Actions. | -| `FERN-3` | Medium | Markdown parser changes could omit or rewrite local assets | `5.92.4` includes follow-up fixes for bracketed alternative text and angle-bracket destinations. The full docs build validates the current tree. | -| `FERN-4` | Medium | Named preview changes could delete or retain the wrong preview | The staging workflow constructs a repository-owned preview identifier, and focused workflow tests cover listing and deletion arguments. | -| `FERN-5` | Medium | The target archive could be substituted | Registry integrity, signatures, provenance, source revision, and successful publication run bind the reviewed artifact. | -| `FERN-6` | Medium | A changed dependency could introduce a vulnerability or license conflict | The current and target closures are identical apart from the Fern root package, and both advisory audits report zero findings. | -| `FERN-7` | Low | Scarf postinstall telemetry can run during a fresh `npx` install | The path and script are unchanged from `5.80.1`, opt-out variables remain available, and Fern is docs-only tooling. The residual is accepted for this upgrade. | -| `FERN-8` | Low | The compatible BAML range could resolve differently in a future install | The range is unchanged, the current resolution is `0.219.0`, and registry signature checks cover the materialized graph. | -| `FERN-9` | Low | New package-generation or importer features could alter shipped artifacts | NemoClaw has no generator manifest and does not invoke these commands. The Fern graph is not included in product artifacts. | -| `FERN-10` | Low | Persisted state could retain incompatible Fern behavior | Fern caches and generated docs are disposable build outputs with no product migration, rollback state, or runtime compatibility shim. | - -Unresolved high-severity concerns: `0`. - -## Verification and Remaining Gates - -Completed audit evidence: - -- 194 contiguous source commits reviewed across five non-overlapping ranges; -- target SHA-1 and SHA-512 identities matched npm registry metadata; -- package structure and licenses inspected without executing upstream lifecycle scripts; -- npm signatures and SLSA provenance verified for current and target graphs; -- current and target dependency closures compared; -- current and target advisory audits reported zero findings; -- the target source manifest and NemoClaw command consumers reviewed. - -Before merge, the reviewed PR must still pass: - -- the focused dependency-review and staging workflow tests; -- the full documentation build with `fern-api@5.92.4`; -- normal commit hooks and required GitHub checks; -- automated review with no unresolved actionable finding; -- documentation writer review. - -No live sandbox E2E, migration, rollback, compatibility shim, or runtime changelog entry is required because the dependency is not part of a supported NemoClaw runtime or user-visible product behavior. diff --git a/docs/security/gateway-authentication-controls.mdx b/docs/security/gateway-authentication-controls.mdx index 0d6b8944bee..d23c03c6eb3 100644 --- a/docs/security/gateway-authentication-controls.mdx +++ b/docs/security/gateway-authentication-controls.mdx @@ -17,6 +17,22 @@ LangChain Deep Agents Code has no in-sandbox agent gateway or dashboard, so devi The shared secret-handling controls below still apply. +## Gateway Compatibility Container + +On Linux hosts whose glibc is older than the OpenShell gateway binary requires, NemoClaw can run `openshell-gateway` in a Docker compatibility container so the Docker-driver gateway still starts. +This path requires the explicit opt-in `NEMOCLAW_OPENSHELL_GATEWAY_CONTAINER_PATCH=1`. + +| Aspect | Detail | +|---|---| +| Default | NemoClaw does not auto-enable the compatibility container on ABI mismatch. If `NEMOCLAW_OPENSHELL_GATEWAY_CONTAINER_PATCH=1` is set, the container keeps the main gateway listener on `127.0.0.1`, uses host networking so OpenShell computes the same Docker bridge callback addresses as a host-side gateway, mounts the Docker socket read-only, drops Linux capabilities, sets `no-new-privileges`, and publishes no extra Docker ports. | +| What you can change | Opt in with `NEMOCLAW_OPENSHELL_GATEWAY_CONTAINER_PATCH=1`, keep the path disabled with `NEMOCLAW_OPENSHELL_GATEWAY_CONTAINER_PATCH=0`, or run on a host/OpenShell build combination where the gateway binary launches directly. | +| Risk if relaxed | The Docker socket remains a privileged host API even when bind-mounted read-only. Treat this mode as equivalent to trusting the host user that can drive Docker, and do not enable it on untrusted shared hosts. | +| Recommendation | Prefer a host with glibc 2.39 or newer, which OpenShell 0.0.101 supports directly, and use the compatibility container only as an explicit local bridge on an older trusted host. | + +OpenShell owns the native Linux glibc support floor. +NemoClaw owns the explicit opt-in, host-networking configuration, read-only socket mount, and gateway authentication controls for this fallback. +Remove the fallback when every supported Linux host meets OpenShell's native floor and the gateway authentication and upgrade tests pass for the release candidate without the flag. + The OpenClaw gateway authenticates devices that connect to the Control UI dashboard. @@ -44,19 +60,6 @@ NemoClaw binds the OpenShell gateway to loopback by default. | Risk if relaxed | Other hosts on the network may be able to reach the OpenShell gateway. NemoClaw rejects wildcard Docker-driver gateway binds while gateway JWT auth is active. | | Recommendation | Keep the gateway loopback default and expose only the dashboard forward when remote access is needed. | -## Gateway Compatibility Container - -On Linux hosts whose glibc is older than the OpenShell gateway binary requires, NemoClaw can run `openshell-gateway` in a Docker compatibility container so the Docker-driver gateway still starts. This path requires the explicit opt-in `NEMOCLAW_OPENSHELL_GATEWAY_CONTAINER_PATCH=1`. - -| Aspect | Detail | -|---|---| -| Default | NemoClaw does not auto-enable the compatibility container on ABI mismatch. If `NEMOCLAW_OPENSHELL_GATEWAY_CONTAINER_PATCH=1` is set, the container keeps the main gateway listener on `127.0.0.1`, uses host networking so OpenShell computes the same Docker bridge callback addresses as a host-side gateway, mounts the Docker socket read-only, drops Linux capabilities, sets `no-new-privileges`, and publishes no extra Docker ports. | -| What you can change | Opt in with `NEMOCLAW_OPENSHELL_GATEWAY_CONTAINER_PATCH=1`, keep the path disabled with `NEMOCLAW_OPENSHELL_GATEWAY_CONTAINER_PATCH=0`, or run on a host/OpenShell build combination where the gateway binary launches directly. | -| Risk if relaxed | The Docker socket remains a privileged host API even when bind-mounted read-only. Treat this mode as equivalent to trusting the host user that can drive Docker, and do not enable it on untrusted shared hosts. | -| Recommendation | Prefer a host with glibc 2.39 or newer, which OpenShell 0.0.101 supports directly, and use the compatibility container only as an explicit local bridge on an older trusted host. | - -Refer to [OpenShell Gateway Compatibility Review](../openshell-0.0.72-compatibility-review) for the unchanged compatibility-container source-of-truth boundaries. - ## Insecure Auth Derivation The `allowInsecureAuth` setting controls whether the gateway permits non-HTTPS authentication. diff --git a/fern/docs.yml b/fern/docs.yml index ab28e789c2b..44e9752bc68 100644 --- a/fern/docs.yml +++ b/fern/docs.yml @@ -80,6 +80,88 @@ redirects: destination: "/nemoclaw/latest/user-guide/openclaw/home" - source: "/nemoclaw/latest/home" destination: "/nemoclaw/latest/user-guide/openclaw/home" + # Version-specific review pages are internal engineering evidence. Preserve their former public + # routes by sending readers to the current security guidance in one hop. + - source: "/nemoclaw/latest/user-guide/:variant/security/openshell-0.0.72-compatibility-review.html" + destination: "/nemoclaw/latest/user-guide/:variant/security/security-controls/gateway-authentication-controls" + - source: "/nemoclaw/latest/user-guide/:variant/security/openshell-0.0.72-compatibility-review/index.html" + destination: "/nemoclaw/latest/user-guide/:variant/security/security-controls/gateway-authentication-controls" + - source: "/nemoclaw/user-guide/:variant/security/openshell-0.0.72-compatibility-review.html" + destination: "/nemoclaw/user-guide/:variant/security/security-controls/gateway-authentication-controls" + - source: "/nemoclaw/user-guide/:variant/security/openshell-0.0.72-compatibility-review/index.html" + destination: "/nemoclaw/user-guide/:variant/security/security-controls/gateway-authentication-controls" + - source: "/nemoclaw/latest/security/openshell-0.0.72-compatibility-review.html" + destination: "/nemoclaw/latest/user-guide/openclaw/security/security-controls/gateway-authentication-controls" + - source: "/nemoclaw/latest/security/openshell-0.0.72-compatibility-review/index.html" + destination: "/nemoclaw/latest/user-guide/openclaw/security/security-controls/gateway-authentication-controls" + - source: "/nemoclaw/security/openshell-0.0.72-compatibility-review.html" + destination: "/nemoclaw/user-guide/openclaw/security/security-controls/gateway-authentication-controls" + - source: "/nemoclaw/security/openshell-0.0.72-compatibility-review/index.html" + destination: "/nemoclaw/user-guide/openclaw/security/security-controls/gateway-authentication-controls" + - source: "/nemoclaw/latest/user-guide/:variant/security/openshell-0.0.71-gateway-auth-review.html" + destination: "/nemoclaw/latest/user-guide/:variant/security/security-controls/gateway-authentication-controls" + - source: "/nemoclaw/latest/user-guide/:variant/security/openshell-0.0.71-gateway-auth-review/index.html" + destination: "/nemoclaw/latest/user-guide/:variant/security/security-controls/gateway-authentication-controls" + - source: "/nemoclaw/user-guide/:variant/security/openshell-0.0.71-gateway-auth-review.html" + destination: "/nemoclaw/user-guide/:variant/security/security-controls/gateway-authentication-controls" + - source: "/nemoclaw/user-guide/:variant/security/openshell-0.0.71-gateway-auth-review/index.html" + destination: "/nemoclaw/user-guide/:variant/security/security-controls/gateway-authentication-controls" + - source: "/nemoclaw/latest/security/openshell-0.0.71-gateway-auth-review.html" + destination: "/nemoclaw/latest/user-guide/openclaw/security/security-controls/gateway-authentication-controls" + - source: "/nemoclaw/latest/security/openshell-0.0.71-gateway-auth-review/index.html" + destination: "/nemoclaw/latest/user-guide/openclaw/security/security-controls/gateway-authentication-controls" + - source: "/nemoclaw/security/openshell-0.0.71-gateway-auth-review.html" + destination: "/nemoclaw/user-guide/openclaw/security/security-controls/gateway-authentication-controls" + - source: "/nemoclaw/security/openshell-0.0.71-gateway-auth-review/index.html" + destination: "/nemoclaw/user-guide/openclaw/security/security-controls/gateway-authentication-controls" + - source: "/nemoclaw/latest/user-guide/:variant/security/openshell-0.0.72-compatibility-review" + destination: "/nemoclaw/latest/user-guide/:variant/security/security-controls/gateway-authentication-controls" + - source: "/nemoclaw/latest/user-guide/:variant/security/openshell-0.0.72-compatibility-review.md" + destination: "/nemoclaw/latest/user-guide/:variant/security/security-controls/gateway-authentication-controls.md" + - source: "/nemoclaw/latest/user-guide/:variant/security/openshell-0.0.72-compatibility-review.mdx" + destination: "/nemoclaw/latest/user-guide/:variant/security/security-controls/gateway-authentication-controls.mdx" + - source: "/nemoclaw/user-guide/:variant/security/openshell-0.0.72-compatibility-review" + destination: "/nemoclaw/user-guide/:variant/security/security-controls/gateway-authentication-controls" + - source: "/nemoclaw/user-guide/:variant/security/openshell-0.0.72-compatibility-review.md" + destination: "/nemoclaw/user-guide/:variant/security/security-controls/gateway-authentication-controls.md" + - source: "/nemoclaw/user-guide/:variant/security/openshell-0.0.72-compatibility-review.mdx" + destination: "/nemoclaw/user-guide/:variant/security/security-controls/gateway-authentication-controls.mdx" + - source: "/nemoclaw/latest/security/openshell-0.0.72-compatibility-review" + destination: "/nemoclaw/latest/user-guide/openclaw/security/security-controls/gateway-authentication-controls" + - source: "/nemoclaw/latest/security/openshell-0.0.72-compatibility-review.md" + destination: "/nemoclaw/latest/user-guide/openclaw/security/security-controls/gateway-authentication-controls.md" + - source: "/nemoclaw/latest/security/openshell-0.0.72-compatibility-review.mdx" + destination: "/nemoclaw/latest/user-guide/openclaw/security/security-controls/gateway-authentication-controls.mdx" + - source: "/nemoclaw/security/openshell-0.0.72-compatibility-review" + destination: "/nemoclaw/user-guide/openclaw/security/security-controls/gateway-authentication-controls" + - source: "/nemoclaw/security/openshell-0.0.72-compatibility-review.md" + destination: "/nemoclaw/user-guide/openclaw/security/security-controls/gateway-authentication-controls.md" + - source: "/nemoclaw/security/openshell-0.0.72-compatibility-review.mdx" + destination: "/nemoclaw/user-guide/openclaw/security/security-controls/gateway-authentication-controls.mdx" + - source: "/nemoclaw/latest/user-guide/:variant/security/openshell-0.0.71-gateway-auth-review" + destination: "/nemoclaw/latest/user-guide/:variant/security/security-controls/gateway-authentication-controls" + - source: "/nemoclaw/latest/user-guide/:variant/security/openshell-0.0.71-gateway-auth-review.md" + destination: "/nemoclaw/latest/user-guide/:variant/security/security-controls/gateway-authentication-controls.md" + - source: "/nemoclaw/latest/user-guide/:variant/security/openshell-0.0.71-gateway-auth-review.mdx" + destination: "/nemoclaw/latest/user-guide/:variant/security/security-controls/gateway-authentication-controls.mdx" + - source: "/nemoclaw/user-guide/:variant/security/openshell-0.0.71-gateway-auth-review" + destination: "/nemoclaw/user-guide/:variant/security/security-controls/gateway-authentication-controls" + - source: "/nemoclaw/user-guide/:variant/security/openshell-0.0.71-gateway-auth-review.md" + destination: "/nemoclaw/user-guide/:variant/security/security-controls/gateway-authentication-controls.md" + - source: "/nemoclaw/user-guide/:variant/security/openshell-0.0.71-gateway-auth-review.mdx" + destination: "/nemoclaw/user-guide/:variant/security/security-controls/gateway-authentication-controls.mdx" + - source: "/nemoclaw/latest/security/openshell-0.0.71-gateway-auth-review" + destination: "/nemoclaw/latest/user-guide/openclaw/security/security-controls/gateway-authentication-controls" + - source: "/nemoclaw/latest/security/openshell-0.0.71-gateway-auth-review.md" + destination: "/nemoclaw/latest/user-guide/openclaw/security/security-controls/gateway-authentication-controls.md" + - source: "/nemoclaw/latest/security/openshell-0.0.71-gateway-auth-review.mdx" + destination: "/nemoclaw/latest/user-guide/openclaw/security/security-controls/gateway-authentication-controls.mdx" + - source: "/nemoclaw/security/openshell-0.0.71-gateway-auth-review" + destination: "/nemoclaw/user-guide/openclaw/security/security-controls/gateway-authentication-controls" + - source: "/nemoclaw/security/openshell-0.0.71-gateway-auth-review.md" + destination: "/nemoclaw/user-guide/openclaw/security/security-controls/gateway-authentication-controls.md" + - source: "/nemoclaw/security/openshell-0.0.71-gateway-auth-review.mdx" + destination: "/nemoclaw/user-guide/openclaw/security/security-controls/gateway-authentication-controls.mdx" # Direct legacy HTML forms for renamed Manage Sandboxes routes must precede # the generic HTML rules so each request reaches its final page in one hop. - source: "/nemoclaw/latest/user-guide/:variant/manage-sandboxes/extend-sandboxes/about-managed-mcp-servers.html" diff --git a/internal/security-reviews/README.md b/internal/security-reviews/README.md new file mode 100644 index 00000000000..8e91c5c30b9 --- /dev/null +++ b/internal/security-reviews/README.md @@ -0,0 +1,12 @@ + + + +# Internal Security Review Evidence + +This directory preserves point-in-time dependency, migration, and security review evidence that tests or maintainers still use. +It is not part of the public documentation set. + +Keep user-facing security behavior and procedures in `docs/security/`. +Keep review findings, concern ledgers, release qualification records, and other maintainer evidence here, in the owning component, or in the pull request that performed the review. +Do not add Fern dependency review records here. Keep Fern upgrade evidence in the pull request and executable configuration and publishing tests. +Do not add these artifacts to `docs/index.yml` or link to them from public documentation. diff --git a/docs/security/e2e-weather-plugin-fixture-dependency-review.md b/internal/security-reviews/e2e-weather-plugin-fixture-dependency-review.md similarity index 98% rename from docs/security/e2e-weather-plugin-fixture-dependency-review.md rename to internal/security-reviews/e2e-weather-plugin-fixture-dependency-review.md index e9663d8436a..4ed1f1a8589 100644 --- a/docs/security/e2e-weather-plugin-fixture-dependency-review.md +++ b/internal/security-reviews/e2e-weather-plugin-fixture-dependency-review.md @@ -3,6 +3,8 @@ # E2E Weather Plugin Fixture Dependency Review +> Internal engineering evidence. This file is not part of the public documentation set. + Review date: 2026-07-12 Scope: `test/e2e/fixtures/plugins/weather/package-lock.json` and the secret-free OpenClaw custom-plugin lifecycle regression lane. diff --git a/docs/security/hermes-0.19.0-dependency-review.md b/internal/security-reviews/hermes-0.19.0-dependency-review.md similarity index 99% rename from docs/security/hermes-0.19.0-dependency-review.md rename to internal/security-reviews/hermes-0.19.0-dependency-review.md index 9fb54a61b91..51778b028b7 100644 --- a/docs/security/hermes-0.19.0-dependency-review.md +++ b/internal/security-reviews/hermes-0.19.0-dependency-review.md @@ -3,6 +3,8 @@ # Hermes 0.19.0 dependency and compatibility review +> Internal engineering evidence. This file is not part of the public documentation set. + Review date: 2026-07-30 Issue `#8087` review date: August 2, 2026. diff --git a/docs/security/managed-base-libssh2-1.11.1-nemoclaw2-dependency-review.md b/internal/security-reviews/managed-base-libssh2-1.11.1-nemoclaw2-dependency-review.md similarity index 98% rename from docs/security/managed-base-libssh2-1.11.1-nemoclaw2-dependency-review.md rename to internal/security-reviews/managed-base-libssh2-1.11.1-nemoclaw2-dependency-review.md index 720fb912754..ba539f54434 100644 --- a/docs/security/managed-base-libssh2-1.11.1-nemoclaw2-dependency-review.md +++ b/internal/security-reviews/managed-base-libssh2-1.11.1-nemoclaw2-dependency-review.md @@ -3,6 +3,8 @@ # Managed Base Image libssh2 1.11.1 NemoClaw Revision 2 Dependency Review +> Internal engineering evidence. This file is not part of the public documentation set. + Date: August 12, 2026 ## Scope diff --git a/docs/security/managed-base-perl-5.44-dependency-review.md b/internal/security-reviews/managed-base-perl-5.44-dependency-review.md similarity index 98% rename from docs/security/managed-base-perl-5.44-dependency-review.md rename to internal/security-reviews/managed-base-perl-5.44-dependency-review.md index ce84cbc99ed..87fa82f9677 100644 --- a/docs/security/managed-base-perl-5.44-dependency-review.md +++ b/internal/security-reviews/managed-base-perl-5.44-dependency-review.md @@ -5,6 +5,8 @@ # Managed base-image Perl 5.44 review +> Internal engineering evidence. This file is not part of the public documentation set. + Date: 2026-07-29 ## Scope diff --git a/docs/security/managed-base-vim-9.2.0858-dependency-review.md b/internal/security-reviews/managed-base-vim-9.2.0858-dependency-review.md similarity index 97% rename from docs/security/managed-base-vim-9.2.0858-dependency-review.md rename to internal/security-reviews/managed-base-vim-9.2.0858-dependency-review.md index 65240d5eda6..5f9fc99d55d 100644 --- a/docs/security/managed-base-vim-9.2.0858-dependency-review.md +++ b/internal/security-reviews/managed-base-vim-9.2.0858-dependency-review.md @@ -3,6 +3,8 @@ # Managed Base Image Vim 9.2.0858 Dependency Review +> Internal engineering evidence. This file is not part of the public documentation set. + Date: August 12, 2026 ## Scope diff --git a/docs/security/openclaw-2026.6.10-dependency-review.md b/internal/security-reviews/openclaw-2026.6.10-dependency-review.md similarity index 99% rename from docs/security/openclaw-2026.6.10-dependency-review.md rename to internal/security-reviews/openclaw-2026.6.10-dependency-review.md index b16931e09fc..9235e7014a6 100644 --- a/docs/security/openclaw-2026.6.10-dependency-review.md +++ b/internal/security-reviews/openclaw-2026.6.10-dependency-review.md @@ -1,5 +1,10 @@ + + + # OpenClaw 2026.6.10 Dependency Review +> Internal engineering evidence. This file is not part of the public documentation set. + Review date: 2026-07-03 Advisory audit revalidated: 2026-07-21 diff --git a/docs/security/openclaw-2026.7.1-dependency-review.md b/internal/security-reviews/openclaw-2026.7.1-dependency-review.md similarity index 99% rename from docs/security/openclaw-2026.7.1-dependency-review.md rename to internal/security-reviews/openclaw-2026.7.1-dependency-review.md index 8fa38c118a7..5d9ad316acd 100644 --- a/docs/security/openclaw-2026.7.1-dependency-review.md +++ b/internal/security-reviews/openclaw-2026.7.1-dependency-review.md @@ -3,6 +3,8 @@ # OpenClaw 2026.7.1 dependency review +> Internal engineering evidence. This file is not part of the public documentation set. + Review date: 2026-07-21 Last updated: 2026-08-11 diff --git a/docs/security/openshell-0.0.101-migration-review.md b/internal/security-reviews/openshell-0.0.101-migration-review.md similarity index 99% rename from docs/security/openshell-0.0.101-migration-review.md rename to internal/security-reviews/openshell-0.0.101-migration-review.md index c194312e42b..0ab0322e1af 100644 --- a/docs/security/openshell-0.0.101-migration-review.md +++ b/internal/security-reviews/openshell-0.0.101-migration-review.md @@ -3,6 +3,8 @@ # OpenShell 0.0.101 Migration and Security Review +> Internal engineering evidence. This file is not part of the public documentation set. + ## Status and Decision This review covers two exact source boundaries: diff --git a/docs/security/openshell-0.0.71-gateway-auth-review.mdx b/internal/security-reviews/openshell-0.0.71-gateway-auth-review.mdx similarity index 99% rename from docs/security/openshell-0.0.71-gateway-auth-review.mdx rename to internal/security-reviews/openshell-0.0.71-gateway-auth-review.mdx index 737002b352c..c1072e75f9f 100644 --- a/docs/security/openshell-0.0.71-gateway-auth-review.mdx +++ b/internal/security-reviews/openshell-0.0.71-gateway-auth-review.mdx @@ -13,6 +13,8 @@ content: agent-variants: ["openclaw", "hermes"] --- +> Internal engineering evidence. This file is not part of the public documentation set. + Review date: 2026-06-26 Scope: NemoClaw Docker-driver gateway config generated for OpenShell `0.0.71`. diff --git a/docs/security/openshell-0.0.72-compatibility-review.mdx b/internal/security-reviews/openshell-0.0.72-compatibility-review.mdx similarity index 97% rename from docs/security/openshell-0.0.72-compatibility-review.mdx rename to internal/security-reviews/openshell-0.0.72-compatibility-review.mdx index 756bb052366..e5029cbae02 100644 --- a/docs/security/openshell-0.0.72-compatibility-review.mdx +++ b/internal/security-reviews/openshell-0.0.72-compatibility-review.mdx @@ -10,6 +10,8 @@ content: type: "reference" --- +> Internal engineering evidence. This file is not part of the public documentation set. + This review covers NemoClaw's stable OpenShell `0.0.72` pin, Docker-driver gateway authentication, policy mutation, and MCP and JSON-RPC policy compatibility. The dependency compatibility review was completed on June 29, 2026; the MCP integration and DNS source/runtime supplement were reviewed on June 30, 2026. @@ -86,7 +88,7 @@ MCP rules can match methods and `tools/call` tool names, support allow and deny The upstream MCP conformance lane passed `initialize`, `tools_call`, and `elicitation-sep1034-client-defaults` with no expected failures. NemoClaw preserves the new MCP and JSON-RPC YAML fields when it merges existing policies. -The strict blueprint-addition schema does not author MCP endpoints; `nemoclaw mcp add` is the supported managed product path described in [Add an MCP Server](../manage-sandboxes/mcp-servers/add-an-mcp-server) and the [accepted architecture decision](https://github.com/NVIDIA/NemoClaw/issues/566#issuecomment-4847534784). +The strict blueprint-addition schema does not author MCP endpoints; `nemoclaw mcp add` is the supported managed product path described in [Add an MCP Server](../../docs/manage-sandboxes/mcp-servers/add-an-mcp-server.mdx) and the [accepted architecture decision](https://github.com/NVIDIA/NemoClaw/issues/566#issuecomment-4847534784). OpenShell enforcement covers sandbox-to-server Streamable HTTP requests, not stdio MCP or generic inbound traffic. ## DNS Pinning Source and Runtime Contract diff --git a/docs/security/openshell-0.0.85-migration-review.md b/internal/security-reviews/openshell-0.0.85-migration-review.md similarity index 99% rename from docs/security/openshell-0.0.85-migration-review.md rename to internal/security-reviews/openshell-0.0.85-migration-review.md index 6d957490ae5..43108c2c692 100644 --- a/docs/security/openshell-0.0.85-migration-review.md +++ b/internal/security-reviews/openshell-0.0.85-migration-review.md @@ -3,6 +3,8 @@ # OpenShell 0.0.72 to 0.0.85 migration review +> Internal engineering evidence. This file is not part of the public documentation set. + ## Status and decision OpenShell published stable tag `v0.0.85` at verified commit diff --git a/docs/security/openshell-0.0.99-migration-review.md b/internal/security-reviews/openshell-0.0.99-migration-review.md similarity index 99% rename from docs/security/openshell-0.0.99-migration-review.md rename to internal/security-reviews/openshell-0.0.99-migration-review.md index c268beeccbb..571a509540e 100644 --- a/docs/security/openshell-0.0.99-migration-review.md +++ b/internal/security-reviews/openshell-0.0.99-migration-review.md @@ -3,6 +3,8 @@ # OpenShell 0.0.85 to 0.0.99 Migration Review +> Internal engineering evidence. This file is not part of the public documentation set. + ## Status and Decision This review covers the complete public source boundary from the previously supported OpenShell diff --git a/docs/security/sandbox-base-2026-07-25-dependency-review.md b/internal/security-reviews/sandbox-base-2026-07-25-dependency-review.md similarity index 99% rename from docs/security/sandbox-base-2026-07-25-dependency-review.md rename to internal/security-reviews/sandbox-base-2026-07-25-dependency-review.md index e049edc2d27..51d20c9a79a 100644 --- a/docs/security/sandbox-base-2026-07-25-dependency-review.md +++ b/internal/security-reviews/sandbox-base-2026-07-25-dependency-review.md @@ -3,6 +3,8 @@ # Sandbox base dependency review for Vim, jq, Expat, Perl modules, and bundled npm +> Internal engineering evidence. This file is not part of the public documentation set. + Date: 2026-07-25 Last updated: August 11, 2026 diff --git a/docs/security/sandbox-base-2026-07-27-native-package-review.md b/internal/security-reviews/sandbox-base-2026-07-27-native-package-review.md similarity index 98% rename from docs/security/sandbox-base-2026-07-27-native-package-review.md rename to internal/security-reviews/sandbox-base-2026-07-27-native-package-review.md index bd8cebfae5f..e487a73965c 100644 --- a/docs/security/sandbox-base-2026-07-27-native-package-review.md +++ b/internal/security-reviews/sandbox-base-2026-07-27-native-package-review.md @@ -3,6 +3,8 @@ # Sandbox Base Native Package Review for libssh2 and Python HTMLParser +> Internal engineering evidence. This file is not part of the public documentation set. + Date: 2026-07-27 ## Scope diff --git a/docs/security/sandbox-base-libexpat-jq-2026-07-24-dependency-review.md b/internal/security-reviews/sandbox-base-libexpat-jq-2026-07-24-dependency-review.md similarity index 99% rename from docs/security/sandbox-base-libexpat-jq-2026-07-24-dependency-review.md rename to internal/security-reviews/sandbox-base-libexpat-jq-2026-07-24-dependency-review.md index d1bda836bc0..d1c7d79295c 100644 --- a/docs/security/sandbox-base-libexpat-jq-2026-07-24-dependency-review.md +++ b/internal/security-reviews/sandbox-base-libexpat-jq-2026-07-24-dependency-review.md @@ -3,6 +3,8 @@ # Sandbox base libexpat and jq dependency review +> Internal engineering evidence. This file is not part of the public documentation set. + Review date: 2026-07-24 ## Decision diff --git a/src/lib/onboard/docker-driver-gateway-compat-container.test.ts b/src/lib/onboard/docker-driver-gateway-compat-container.test.ts index 5fe7f19ef7d..1d257f37edf 100644 --- a/src/lib/onboard/docker-driver-gateway-compat-container.test.ts +++ b/src/lib/onboard/docker-driver-gateway-compat-container.test.ts @@ -234,7 +234,7 @@ describe("docker-driver-gateway compatibility container", () => { " Compatibility gateway bind: 127.0.0.1 main listener plus OpenShell Docker-driver bridge reachability.", ); expect(warnings).toEqual([ - " SECURITY NOTICE: compatibility container uses host networking plus Docker API access; enabled only by NEMOCLAW_OPENSHELL_GATEWAY_CONTAINER_PATCH=1. Review/removal conditions: docs/security/openshell-0.0.72-compatibility-review.mdx#source-of-truth-boundaries.", + " SECURITY NOTICE: compatibility container uses host networking plus Docker API access; enabled only by NEMOCLAW_OPENSHELL_GATEWAY_CONTAINER_PATCH=1. Details: https://docs.nvidia.com/nemoclaw/latest/user-guide/openclaw/security/security-controls/gateway-authentication-controls#gateway-compatibility-container.", ]); expect(messages).toContain( " Gateway auth boundary: host-side OpenShell CLI uses local mTLS; sandbox callbacks use mTLS plus OpenShell gateway JWT.", diff --git a/src/lib/onboard/docker-driver-gateway-compat.ts b/src/lib/onboard/docker-driver-gateway-compat.ts index 72547785298..398b500cd9a 100644 --- a/src/lib/onboard/docker-driver-gateway-compat.ts +++ b/src/lib/onboard/docker-driver-gateway-compat.ts @@ -312,7 +312,7 @@ export function logContainerizedDockerDriverGatewayLaunch( log(` OpenShell gateway compatibility patch active (${launch.reason}).`); log(" Running openshell-gateway inside a Docker compatibility container."); warn( - " SECURITY NOTICE: compatibility container uses host networking plus Docker API access; enabled only by NEMOCLAW_OPENSHELL_GATEWAY_CONTAINER_PATCH=1. Review/removal conditions: docs/security/openshell-0.0.72-compatibility-review.mdx#source-of-truth-boundaries.", + " SECURITY NOTICE: compatibility container uses host networking plus Docker API access; enabled only by NEMOCLAW_OPENSHELL_GATEWAY_CONTAINER_PATCH=1. Details: https://docs.nvidia.com/nemoclaw/latest/user-guide/openclaw/security/security-controls/gateway-authentication-controls#gateway-compatibility-container.", ); log( " Compatibility gateway bind: 127.0.0.1 main listener plus OpenShell Docker-driver bridge reachability.", diff --git a/src/lib/onboard/docker-driver-gateway-config.ts b/src/lib/onboard/docker-driver-gateway-config.ts index fc0418adc97..be037081035 100644 --- a/src/lib/onboard/docker-driver-gateway-config.ts +++ b/src/lib/onboard/docker-driver-gateway-config.ts @@ -13,7 +13,7 @@ import { PORTABLE_HOST_GATEWAY_IP } from "./docker-driver-platform"; export type { DockerDriverGatewayJwtBundle } from "./docker-driver-gateway-jwt-bundle"; export { ensureDockerDriverGatewayJwtBundle } from "./docker-driver-gateway-jwt-bundle"; -// See docs/security/openshell-0.0.72-compatibility-review.mdx for the source-of-truth review. +// See docs/security/gateway-authentication-controls.mdx for the public compatibility boundary. export const DOCKER_DRIVER_GATEWAY_CONFIG_NAME = "openshell-gateway.toml"; export const DOCKER_DRIVER_GATEWAY_JWT_TTL_SECS = 0; export const NEMOCLAW_OPENSHELL_SANDBOX_NAMESPACE_ENV = "NEMOCLAW_OPENSHELL_SANDBOX_NAMESPACE"; diff --git a/src/lib/onboard/docker-driver-gateway-local-tls.ts b/src/lib/onboard/docker-driver-gateway-local-tls.ts index 8f902cb92e1..2989daa57d6 100644 --- a/src/lib/onboard/docker-driver-gateway-local-tls.ts +++ b/src/lib/onboard/docker-driver-gateway-local-tls.ts @@ -8,7 +8,7 @@ import path from "node:path"; import { isPortableExperimentalProfile, PORTABLE_HOST_GATEWAY_IP } from "./docker-driver-platform"; -// See docs/security/openshell-0.0.72-compatibility-review.mdx for the source-of-truth review. +// See docs/security/gateway-authentication-controls.mdx for the public compatibility boundary. export const DOCKER_DRIVER_GATEWAY_LOCAL_TLS_DIR_NAME = "tls"; const REQUIRED_SERVER_DNS_SANS = ["host.openshell.internal", "localhost"]; diff --git a/test/agent-variant-docs.test.ts b/test/agent-variant-docs.test.ts index 6674939f77b..039ef9a587e 100644 --- a/test/agent-variant-docs.test.ts +++ b/test/agent-variant-docs.test.ts @@ -438,7 +438,7 @@ import { AgentOnly } from "../_components/AgentGuide"; expect(hermes).not.toContain("platforms.whatsapp.extra.session_path"); }); - it("keeps the troubleshooting security review link within each agent guide (#6558)", () => { + it("keeps the troubleshooting security guidance link within each agent guide (#6558)", () => { const troubleshooting = readFileSync( new URL("../docs/reference/troubleshooting.mdx", import.meta.url), "utf8", @@ -451,10 +451,10 @@ import { AgentOnly } from "../_components/AgentGuide"; }); expect(rendered).toContain( - "[OpenShell gateway compatibility review](../security/openshell-0.0.72-compatibility-review#source-of-truth-boundaries)", + "[Gateway Compatibility Container](../security/security-controls/gateway-authentication-controls#gateway-compatibility-container)", ); expect(rendered).not.toMatch( - /\/user-guide\/(?:openclaw|hermes|deepagents)\/security\/openshell-0\.0\.72-compatibility-review/, + /\/user-guide\/(?:openclaw|hermes|deepagents)\/security\/security-controls\/gateway-authentication-controls/, ); } }); diff --git a/test/check-docs-published-routes.test.ts b/test/check-docs-published-routes.test.ts index 450b7b8304f..befe203398b 100644 --- a/test/check-docs-published-routes.test.ts +++ b/test/check-docs-published-routes.test.ts @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs"; +import { mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; import path from "node:path"; @@ -516,6 +516,71 @@ describe("Documentation Engineering routes", () => { }); }); +describe("public security review boundaries", () => { + const index = buildPublishedRouteIndex(); + const redirects = fernRedirects ?? []; + const destinations = new Map(redirects.map(({ source, destination }) => [source, destination])); + const redirectIndexes = new Map(redirects.map(({ source }, index) => [source, index])); + + it("keeps internal review records out of the public Security section", () => { + const publicReviewFiles = readdirSync(path.join(repoRoot, "docs", "security")).filter((name) => + /review/iu.test(name), + ); + + expect(publicReviewFiles).toEqual([]); + for (const variant of ["openclaw", "hermes", "deepagents"]) { + expect( + index.routes.has(`/user-guide/${variant}/security/openshell-0.0.72-compatibility-review`), + ).toBe(false); + expect( + index.routes.has(`/user-guide/${variant}/security/openshell-0.0.71-gateway-auth-review`), + ).toBe(false); + } + }); + + it("redirects retired review routes directly to current security guidance", () => { + for (const reviewSlug of [ + "openshell-0.0.72-compatibility-review", + "openshell-0.0.71-gateway-auth-review", + ]) { + for (const [sourceBase, destinationBase] of [ + [ + `/nemoclaw/latest/user-guide/:variant/security/${reviewSlug}`, + "/nemoclaw/latest/user-guide/:variant/security/security-controls/gateway-authentication-controls", + ], + [ + `/nemoclaw/user-guide/:variant/security/${reviewSlug}`, + "/nemoclaw/user-guide/:variant/security/security-controls/gateway-authentication-controls", + ], + [ + `/nemoclaw/latest/security/${reviewSlug}`, + "/nemoclaw/latest/user-guide/openclaw/security/security-controls/gateway-authentication-controls", + ], + [ + `/nemoclaw/security/${reviewSlug}`, + "/nemoclaw/user-guide/openclaw/security/security-controls/gateway-authentication-controls", + ], + ]) { + expect(destinations.get(sourceBase)).toBe(destinationBase); + expect(destinations.get(`${sourceBase}.html`)).toBe(destinationBase); + expect(destinations.get(`${sourceBase}/index.html`)).toBe(destinationBase); + expect(destinations.get(`${sourceBase}.md`)).toBe(`${destinationBase}.md`); + expect(destinations.get(`${sourceBase}.mdx`)).toBe(`${destinationBase}.mdx`); + + expect(redirectIndexes.get(`${sourceBase}.html`)).toBeLessThan( + redirectIndexes.get("/nemoclaw/:path*.html") ?? -1, + ); + const genericIndexSource = sourceBase.startsWith("/nemoclaw/latest/") + ? "/nemoclaw/latest/:path*/index.html" + : "/nemoclaw/:path*/index.html"; + expect(redirectIndexes.get(`${sourceBase}/index.html`)).toBeLessThan( + redirectIndexes.get(genericIndexSource) ?? -1, + ); + } + } + }); +}); + describe("headless server deployment routes", () => { const index = buildPublishedRouteIndex(); diff --git a/test/dependency-upgrade-skill.test.ts b/test/dependency-upgrade-skill.test.ts index 51ca79a9713..fd4f1bc08fa 100644 --- a/test/dependency-upgrade-skill.test.ts +++ b/test/dependency-upgrade-skill.test.ts @@ -339,6 +339,17 @@ describe("dependency upgrade skill policy", () => { expect(skill).toContain("release notes and PR descriptions as leads, not behavior authority"); expect(skill).toContain("Inspect test selection and observed results"); expect(skill).toContain("does not establish artifact identity or runtime selection"); + expect(skill).toContain("Do not write release ledgers"); + expect(skill).toContain("under `docs/`"); + expect(skill).toContain("internal/security-reviews/"); + expect(skill).toContain("For Fern, do not create a dependency review document"); + expect(skill).toContain("executable configuration and publishing tests"); + expect(skill).toContain("link to it from public documentation"); + expect( + fs + .readdirSync(path.join(repoRoot, "internal", "security-reviews")) + .filter((filename) => /^fern-.*review/u.test(filename)), + ).toEqual([]); expect(discovery).toContain("Use the current checkout as the source of truth"); expect(discovery).toContain("Record discovered specifics in task or PR evidence"); expect(guide).toContain("`nemoclaw-contributor-update-dependencies`"); diff --git a/test/e2e-fixture-dependency-review.test.ts b/test/e2e-fixture-dependency-review.test.ts index 2ee548fe89e..8ab650980e4 100644 --- a/test/e2e-fixture-dependency-review.test.ts +++ b/test/e2e-fixture-dependency-review.test.ts @@ -12,8 +12,8 @@ const REPO_ROOT = path.resolve(__dirname, ".."); const FIXTURES_ROOT = path.join(REPO_ROOT, "test", "e2e", "fixtures"); const REVIEW_PATH = path.join( REPO_ROOT, - "docs", - "security", + "internal", + "security-reviews", "e2e-weather-plugin-fixture-dependency-review.md", ); diff --git a/test/e2e/support/mcp-bridge-sandbox.test.ts b/test/e2e/support/mcp-bridge-sandbox.test.ts index c0db4601e87..a5e5e27741a 100644 --- a/test/e2e/support/mcp-bridge-sandbox.test.ts +++ b/test/e2e/support/mcp-bridge-sandbox.test.ts @@ -188,7 +188,7 @@ describe("MCP curl policy denial classification", SUITE_OPTIONS, () => { expect(docs).toContain("reopens proxy-side DNS resolution"); const migrationReview = fs.readFileSync( - "docs/security/openshell-0.0.101-migration-review.md", + "internal/security-reviews/openshell-0.0.101-migration-review.md", "utf8", ); expect(migrationReview).toContain(commit); diff --git a/test/fern-dependency-review.test.ts b/test/fern-dependency-review.test.ts deleted file mode 100644 index ad423180e78..00000000000 --- a/test/fern-dependency-review.test.ts +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -import { readFileSync } from "node:fs"; -import path from "node:path"; -import { describe, expect, it } from "vitest"; - -const repoRoot = path.join(import.meta.dirname, ".."); -const fernConfig = JSON.parse( - readFileSync(path.join(repoRoot, "fern", "fern.config.json"), "utf8"), -) as { version: string }; -const review = readFileSync( - path.join(repoRoot, "docs", "security", "fern-5.92.4-dependency-review.md"), - "utf8", -); - -function tableRows(sectionName: string): string[][] { - const section = review.split(`## ${sectionName}\n`)[1]?.split(/\n## /u)[0]; - expect(section, `Missing review section: ${sectionName}`).toBeDefined(); - return (section ?? "") - .split("\n") - .filter((line) => line.startsWith("|")) - .slice(2) - .map((line) => - line - .slice(1, -1) - .split("|") - .map((cell) => cell.trim()), - ); -} - -describe("Fern dependency review", () => { - it("binds the production pin to the reviewed target artifact", () => { - const identities = Object.fromEntries( - tableRows("Reviewed Identities").map(([label, value]) => [label, value]), - ); - - expect(fernConfig.version).toBe("5.92.4"); - expect(identities["Target package"]).toBe("`fern-api@5.92.4`"); - expect(identities["Target source commit"]).toBe("`f501eb09d3a31776d54beaa70346af4174d09664`"); - expect(identities["Target integrity"]).toBe( - "`sha512-+vOR7M+G98poLJTSnyx2gw3Si+5AT/cTF7yRAdFst+977+DsTxWmUDx4RtajvR75EFqEOERwUcmDDUa2vCUerw==`", - ); - expect(identities["Target SHA-1"]).toBe("`fd89c28f9f72d41be7d0a021da3a0136f88027c9`"); - }); - - it("records complete range, closure, and concern dispositions", () => { - const ranges = tableRows("Complete Source Range Ledger"); - const concerns = tableRows("Concern Ledger"); - - expect(ranges).toHaveLength(5); - expect(ranges.reduce((total, [, commits]) => total + Number(commits), 0)).toBe(194); - expect(review).toMatch(/Each\s+graph contains 11 packages/); - expect(review).toContain("zero info, low, moderate, high, or critical findings"); - expect(review).toContain("Unresolved high-severity concerns: `0`"); - expect(concerns.map(([id]) => id)).toEqual( - Array.from({ length: 10 }, (_, index) => `\`FERN-${index + 1}\``), - ); - expect(concerns.every((row) => row.length === 4 && row.every(Boolean))).toBe(true); - }); -}); diff --git a/test/hermes-dependency-review.test.ts b/test/hermes-dependency-review.test.ts index aff2218d1fe..4e71039b86d 100644 --- a/test/hermes-dependency-review.test.ts +++ b/test/hermes-dependency-review.test.ts @@ -22,7 +22,7 @@ const cliAdapter = JSON.parse( fs.readFileSync(path.join(root, "agents", "hermes", "hermes-cli-adapter-v1.json"), "utf8"), ); const review = fs.readFileSync( - path.join(root, "docs", "security", "hermes-0.19.0-dependency-review.md"), + path.join(root, "internal", "security-reviews", "hermes-0.19.0-dependency-review.md"), "utf8", ); const securityDependenciesPatch = fs.readFileSync( diff --git a/test/issue-4434-error-fields.test.ts b/test/issue-4434-error-fields.test.ts index dce22ea8776..5635fc60064 100644 --- a/test/issue-4434-error-fields.test.ts +++ b/test/issue-4434-error-fields.test.ts @@ -14,7 +14,7 @@ const REPO_ROOT = path.join(import.meta.dirname, ".."); const DOCKERFILE = path.join(REPO_ROOT, "Dockerfile"); const DEPENDENCY_REVIEW = path.join( REPO_ROOT, - "docs/security/openclaw-2026.7.1-dependency-review.md", + "internal/security-reviews/openclaw-2026.7.1-dependency-review.md", ); const LIVE_VITEST_GUARD = path.join( REPO_ROOT, diff --git a/test/openclaw-dependency-review.test.ts b/test/openclaw-dependency-review.test.ts index a8a0d4affde..b252504ebea 100644 --- a/test/openclaw-dependency-review.test.ts +++ b/test/openclaw-dependency-review.test.ts @@ -12,14 +12,14 @@ import { readYaml, type WorkflowJob, type WorkflowStep } from "./helpers/e2e-wor const REPO_ROOT = path.join(import.meta.dirname, ".."); const DEPENDENCY_REVIEW = path.join( REPO_ROOT, - "docs", - "security", + "internal", + "security-reviews", "openclaw-2026.6.10-dependency-review.md", ); const ACTIVE_DEPENDENCY_REVIEW = path.join( REPO_ROOT, - "docs", - "security", + "internal", + "security-reviews", "openclaw-2026.7.1-dependency-review.md", ); const MCP_TROUBLESHOOTING = path.join( diff --git a/test/openclaw-integrity-pin-suite.ts b/test/openclaw-integrity-pin-suite.ts index f7a6bf88bfc..09d534a5973 100644 --- a/test/openclaw-integrity-pin-suite.ts +++ b/test/openclaw-integrity-pin-suite.ts @@ -25,8 +25,8 @@ const PRODUCTION_DOCKERFILES = [ const BLUEPRINT = path.join(REPO_ROOT, "nemoclaw-blueprint", "blueprint.yaml"); const DEPENDENCY_REVIEW_NOTE = path.join( REPO_ROOT, - "docs", - "security", + "internal", + "security-reviews", "openclaw-2026.7.1-dependency-review.md", ); const PRODUCTION_BUILD_ARG_GUARD = path.join( @@ -803,35 +803,35 @@ export function registerOpenClawIntegrityPinTests(group: OpenClawIntegrityPinTes ).toEqual(sortedEntries(expectedEntries)); }); - it.each([ - "latest", - "^2026.7.1", - ])("rejects a trusted OpenClaw plugin manifest with non-exact version %s", (version) => { - const slackManifest = createBuiltInChannelManifestRegistry().get("slack"); - expect(slackManifest).toBeDefined(); - const nonExactManifest = { - ...slackManifest!, - agentPackages: slackManifest!.agentPackages?.map((agentPackage) => - agentPackage.agent === "openclaw" && agentPackage.manager === "openclaw-plugin" - ? { - ...agentPackage, - spec: `npm:@openclaw/slack@${version}`, - integrity: PINNED_OPENCLAW_SLACK_INTEGRITY, - integrityByVersion: undefined, - } - : agentPackage, - ), - }; + it.each(["latest", "^2026.7.1"])( + "rejects a trusted OpenClaw plugin manifest with non-exact version %s", + (version) => { + const slackManifest = createBuiltInChannelManifestRegistry().get("slack"); + expect(slackManifest).toBeDefined(); + const nonExactManifest = { + ...slackManifest!, + agentPackages: slackManifest!.agentPackages?.map((agentPackage) => + agentPackage.agent === "openclaw" && agentPackage.manager === "openclaw-plugin" + ? { + ...agentPackage, + spec: `npm:@openclaw/slack@${version}`, + integrity: PINNED_OPENCLAW_SLACK_INTEGRITY, + integrityByVersion: undefined, + } + : agentPackage, + ), + }; - expect(() => - reviewedOpenClawPluginIntegrityByPackageSpec( - { OPENCLAW_VERSION: PINNED_OPENCLAW_VERSION }, - [nonExactManifest], - ), - ).toThrow( - `must use an exact-version OpenClaw plugin package: npm:@openclaw/slack@${version}`, - ); - }); + expect(() => + reviewedOpenClawPluginIntegrityByPackageSpec( + { OPENCLAW_VERSION: PINNED_OPENCLAW_VERSION }, + [nonExactManifest], + ), + ).toThrow( + `must use an exact-version OpenClaw plugin package: npm:@openclaw/slack@${version}`, + ); + }, + ); } if (group === "plugin-install") { diff --git a/test/openshell-0.0.101-migration-review.test.ts b/test/openshell-0.0.101-migration-review.test.ts index 9fb1e890c1f..83c6d3c1b2a 100644 --- a/test/openshell-0.0.101-migration-review.test.ts +++ b/test/openshell-0.0.101-migration-review.test.ts @@ -11,7 +11,7 @@ import { buildDockerDriverGatewayConfigToml } from "../src/lib/onboard/docker-dr const repoRoot = path.resolve(import.meta.dirname, ".."); const review = fs.readFileSync( - path.join(repoRoot, "docs", "security", "openshell-0.0.101-migration-review.md"), + path.join(repoRoot, "internal", "security-reviews", "openshell-0.0.101-migration-review.md"), "utf8", ); diff --git a/test/openshell-0.0.85-migration-review.test.ts b/test/openshell-0.0.85-migration-review.test.ts index f9c2cf9c9ec..4d4e7c615b4 100644 --- a/test/openshell-0.0.85-migration-review.test.ts +++ b/test/openshell-0.0.85-migration-review.test.ts @@ -7,7 +7,7 @@ import { describe, expect, it } from "vitest"; const repoRoot = path.resolve(import.meta.dirname, ".."); const review = fs.readFileSync( - path.join(repoRoot, "docs", "security", "openshell-0.0.85-migration-review.md"), + path.join(repoRoot, "internal", "security-reviews", "openshell-0.0.85-migration-review.md"), "utf8", ); diff --git a/test/openshell-0.0.99-migration-review.test.ts b/test/openshell-0.0.99-migration-review.test.ts index a5d660f56a8..d2ef374d08c 100644 --- a/test/openshell-0.0.99-migration-review.test.ts +++ b/test/openshell-0.0.99-migration-review.test.ts @@ -13,7 +13,7 @@ import { validateName } from "../src/lib/runner.js"; const repoRoot = path.resolve(import.meta.dirname, ".."); const review = fs.readFileSync( - path.join(repoRoot, "docs", "security", "openshell-0.0.99-migration-review.md"), + path.join(repoRoot, "internal", "security-reviews", "openshell-0.0.99-migration-review.md"), "utf8", ); diff --git a/test/perl-critical-cve-remediation.test.ts b/test/perl-critical-cve-remediation.test.ts index 75a3c8a5f3c..8999e88094e 100644 --- a/test/perl-critical-cve-remediation.test.ts +++ b/test/perl-critical-cve-remediation.test.ts @@ -20,7 +20,12 @@ const packageBuilder = fs.readFileSync( const netPingCapabilityPatchPath = "scripts/security/patches/perl-5.44.0-net-ping-capability-tests.patch"; const dependencyReview = fs.readFileSync( - path.join(repoRoot, "docs", "security", "managed-base-perl-5.44-dependency-review.md"), + path.join( + repoRoot, + "internal", + "security-reviews", + "managed-base-perl-5.44-dependency-review.md", + ), "utf8", ); const managedImages = [ diff --git a/test/support/openshell-gateway-config-helpers.ts b/test/support/openshell-gateway-config-helpers.ts index f368d4f7197..47220524a95 100644 --- a/test/support/openshell-gateway-config-helpers.ts +++ b/test/support/openshell-gateway-config-helpers.ts @@ -22,14 +22,14 @@ export { DOCKER_DRIVER_GATEWAY_JWT_TTL_SECS }; export const REPO_ROOT = path.resolve(import.meta.dirname, "../.."); export const GATEWAY_AUTH_REVIEW_NOTE = path.join( REPO_ROOT, - "docs", - "security", + "internal", + "security-reviews", "openshell-0.0.72-compatibility-review.mdx", ); export const GATEWAY_MIGRATION_REVIEW_NOTE = path.join( REPO_ROOT, - "docs", - "security", + "internal", + "security-reviews", "openshell-0.0.85-migration-review.md", ); const SANDBOX_JWT_SUBJECT_PREFIX = "spiffe://openshell/sandbox/";