Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/workflows/managed-images.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,16 @@ jobs:
ref: ${{ github.event.pull_request.head.sha }}
persist-credentials: false

- name: Make reviewed runtime bundle files group-writable
shell: bash
run: |
set -euo pipefail
chmod 0664 \
tools/mcp-tool-discovery-runtime/reviewed-runtime-bundle/managed-startup-image-runtime.bundle \
tools/mcp-tool-discovery-runtime/reviewed-runtime-bundle/mcp-tool-discovery/BUNDLED_PACKAGES.json \
tools/mcp-tool-discovery-runtime/reviewed-runtime-bundle/mcp-tool-discovery/THIRD_PARTY_LICENSES.txt \
tools/mcp-tool-discovery-runtime/reviewed-runtime-bundle/mcp-tool-discovery/mcp-tool-discovery.bundle
Comment thread
coderabbitai[bot] marked this conversation as resolved.

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0

Expand Down
53 changes: 35 additions & 18 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,12 @@
# graph during image assembly. Protected rebuilds remain network-free and the
# final image still receives only the generated bundles.
FROM scratch AS mcp-tool-discovery-runtime
COPY tools/mcp-tool-discovery-runtime/reviewed-runtime-bundle/mcp-tool-discovery/BUNDLED_PACKAGES.json tools/mcp-tool-discovery-runtime/reviewed-runtime-bundle/mcp-tool-discovery/THIRD_PARTY_LICENSES.txt /opt/mcp-tool-discovery-runtime/dist/
COPY tools/mcp-tool-discovery-runtime/reviewed-runtime-bundle/mcp-tool-discovery/mcp-tool-discovery.bundle /opt/mcp-tool-discovery-runtime/dist/mcp-tool-discovery.mjs
# Set root ownership and read-only modes because scratch-stage COPY preserves source metadata.
COPY --chown=0:0 --chmod=0444 tools/mcp-tool-discovery-runtime/reviewed-runtime-bundle/mcp-tool-discovery/BUNDLED_PACKAGES.json tools/mcp-tool-discovery-runtime/reviewed-runtime-bundle/mcp-tool-discovery/THIRD_PARTY_LICENSES.txt /opt/mcp-tool-discovery-runtime/dist/
COPY --chown=0:0 --chmod=0444 tools/mcp-tool-discovery-runtime/reviewed-runtime-bundle/mcp-tool-discovery/mcp-tool-discovery.bundle /opt/mcp-tool-discovery-runtime/dist/mcp-tool-discovery.mjs

FROM scratch AS managed-startup-runtime-builder
COPY tools/mcp-tool-discovery-runtime/reviewed-runtime-bundle/managed-startup-image-runtime.bundle /out/managed-startup-image-runtime.cjs
COPY --chown=0:0 --chmod=0444 tools/mcp-tool-discovery-runtime/reviewed-runtime-bundle/managed-startup-image-runtime.bundle /out/managed-startup-image-runtime.cjs

# Compile the bootstrap boundary on the target platform. The output is a
# freestanding static ELF; only its reviewed, non-executable Bash body remains
Expand Down Expand Up @@ -1502,21 +1503,37 @@
exit 1; \
}; \
discovery_contract="$(node /usr/local/lib/nemoclaw/mcp-tool-discovery-runtime/mcp-tool-discovery.mjs)" \
&& node -e "const result = JSON.parse(process.argv[1]); if (result.protocol !== 1 || result.ok !== false || result.detail !== \"tool discovery received invalid runtime arguments\") process.exit(1);" "$discovery_contract" \
&& discovery_unsafe="$(find -L /usr/local/lib/nemoclaw/mcp-tool-discovery-runtime \( ! -user root -o -perm /022 \) -print -quit)" \
&& test -z "$discovery_unsafe" \
&& { test -f /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs || managed_runtime_assertion_failed regular-file /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs; } \
&& { test ! -L /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs || managed_runtime_assertion_failed non-symlink /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs; } \
&& { chown root:root /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs 2>/dev/null || managed_runtime_assertion_failed owner-root-root /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs; } \
&& { chmod 0444 /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs 2>/dev/null || managed_runtime_assertion_failed mode-0444 /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs; } \
&& { test "$(stat -c '%u:%g:%a' /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs 2>/dev/null)" = '0:0:444' || managed_runtime_assertion_failed metadata-0:0:444 /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs; } \
&& test -f /usr/local/bin/nemoclaw-managed-bootstrap \
&& test ! -L /usr/local/bin/nemoclaw-managed-bootstrap \
&& test "$(stat -c '%u:%g:%a' /usr/local/bin/nemoclaw-managed-bootstrap)" = '0:0:755' \
&& test -f /usr/local/lib/nemoclaw/managed-bootstrap-trampoline.sh \
&& test ! -L /usr/local/lib/nemoclaw/managed-bootstrap-trampoline.sh \
&& test "$(stat -c '%u:%g:%a' /usr/local/lib/nemoclaw/managed-bootstrap-trampoline.sh)" = '0:0:444' \
&& install -d -o root -g root -m 0755 /run/nemoclaw
|| managed_runtime_assertion_failed discovery-exec /usr/local/lib/nemoclaw/mcp-tool-discovery-runtime/mcp-tool-discovery.mjs; \
node -e "const result = JSON.parse(process.argv[1]); if (result.protocol !== 1 || result.ok !== false || result.detail !== \"tool discovery received invalid runtime arguments\") process.exit(1);" "$discovery_contract" \
|| managed_runtime_assertion_failed discovery-contract /usr/local/lib/nemoclaw/mcp-tool-discovery-runtime/mcp-tool-discovery.mjs; \
discovery_unsafe="$(find -L /usr/local/lib/nemoclaw/mcp-tool-discovery-runtime \( ! -user root -o -perm /022 \) -print -quit)" \
|| managed_runtime_assertion_failed discovery-tree-scan /usr/local/lib/nemoclaw/mcp-tool-discovery-runtime; \
test -z "$discovery_unsafe" \
|| managed_runtime_assertion_failed discovery-tree-owner-mode "$discovery_unsafe"; \
test -f /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs \
|| managed_runtime_assertion_failed regular-file /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs; \
test ! -L /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs \
|| managed_runtime_assertion_failed non-symlink /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs; \
chown root:root /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs 2>/dev/null \
|| managed_runtime_assertion_failed owner-root-root /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs; \
chmod 0444 /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs 2>/dev/null \
|| managed_runtime_assertion_failed mode-0444 /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs; \
test "$(stat -c '%u:%g:%a' /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs 2>/dev/null)" = '0:0:444' \
|| managed_runtime_assertion_failed metadata-0:0:444 /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs; \
test -f /usr/local/bin/nemoclaw-managed-bootstrap \
|| managed_runtime_assertion_failed managed-bootstrap-regular-file /usr/local/bin/nemoclaw-managed-bootstrap; \
test ! -L /usr/local/bin/nemoclaw-managed-bootstrap \
|| managed_runtime_assertion_failed managed-bootstrap-non-symlink /usr/local/bin/nemoclaw-managed-bootstrap; \
test "$(stat -c '%u:%g:%a' /usr/local/bin/nemoclaw-managed-bootstrap)" = '0:0:755' \
|| managed_runtime_assertion_failed managed-bootstrap-metadata-0:0:755 /usr/local/bin/nemoclaw-managed-bootstrap; \
test -f /usr/local/lib/nemoclaw/managed-bootstrap-trampoline.sh \
|| managed_runtime_assertion_failed managed-bootstrap-trampoline-regular-file /usr/local/lib/nemoclaw/managed-bootstrap-trampoline.sh; \
test ! -L /usr/local/lib/nemoclaw/managed-bootstrap-trampoline.sh \
|| managed_runtime_assertion_failed managed-bootstrap-trampoline-non-symlink /usr/local/lib/nemoclaw/managed-bootstrap-trampoline.sh; \
test "$(stat -c '%u:%g:%a' /usr/local/lib/nemoclaw/managed-bootstrap-trampoline.sh)" = '0:0:444' \
|| managed_runtime_assertion_failed managed-bootstrap-trampoline-metadata-0:0:444 /usr/local/lib/nemoclaw/managed-bootstrap-trampoline.sh; \
install -d -o root -g root -m 0755 /run/nemoclaw \
|| managed_runtime_assertion_failed runtime-directory-0:0:755 /run/nemoclaw
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

# Copy startup script and shared sandbox initialisation library.
RUN chmod 755 /usr/local/bin/nemoclaw-start /usr/local/bin/nemoclaw-codex-acp \
Expand Down Expand Up @@ -1621,10 +1638,10 @@
# CHAT_UI_URL is a non-loopback address (Brev Launchable, remote deployments)
# since terminal-based pairing is impossible in those contexts.
# Default: "0" (device auth enabled for local deployments — secure by default).
ARG NEMOCLAW_DISABLE_DEVICE_AUTH=0

Check warning on line 1641 in Dockerfile

View workflow job for this annotation

GitHub Actions / PR build and direct managed startup (OpenClaw)

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ARG "NEMOCLAW_DISABLE_DEVICE_AUTH") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/

Check warning on line 1641 in Dockerfile

View workflow job for this annotation

GitHub Actions / PR build and direct managed startup (OpenClaw)

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ARG "NEMOCLAW_DISABLE_DEVICE_AUTH") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/
# Internal audit provenance for the opt-out above. Standard onboarding rewrites
# this to managed-onboard; direct image builders retain operator provenance.
ARG NEMOCLAW_DEVICE_AUTH_OPT_OUT_SOURCE=operator

Check warning on line 1644 in Dockerfile

View workflow job for this annotation

GitHub Actions / PR build and direct managed startup (OpenClaw)

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ARG "NEMOCLAW_DEVICE_AUTH_OPT_OUT_SOURCE") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/

Check warning on line 1644 in Dockerfile

View workflow job for this annotation

GitHub Actions / PR build and direct managed startup (OpenClaw)

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ARG "NEMOCLAW_DEVICE_AUTH_OPT_OUT_SOURCE") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/
# Compatibility build arg for older custom Dockerfiles and rebuild tooling.
# NemoClaw-managed images intentionally do not consume it; gateway auth tokens
# are generated at container startup and are never baked into image layers.
Expand Down Expand Up @@ -1658,7 +1675,7 @@
# NEMOCLAW_MESSAGING_PLAN_B64 intentionally remains ARG-only: Docker exposes it
# to build RUN processes without retaining the full plan in the final image env.
# Direct ARG interpolation into inline source is a code injection vector (C-2).
ENV NEMOCLAW_MODEL=${NEMOCLAW_MODEL} \

Check warning on line 1678 in Dockerfile

View workflow job for this annotation

GitHub Actions / PR build and direct managed startup (OpenClaw)

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ENV "NEMOCLAW_DEVICE_AUTH_OPT_OUT_SOURCE") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/

Check warning on line 1678 in Dockerfile

View workflow job for this annotation

GitHub Actions / PR build and direct managed startup (OpenClaw)

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ENV "NEMOCLAW_DISABLE_DEVICE_AUTH") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/

Check warning on line 1678 in Dockerfile

View workflow job for this annotation

GitHub Actions / PR build and direct managed startup (OpenClaw)

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ENV "NEMOCLAW_DEVICE_AUTH_OPT_OUT_SOURCE") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/

Check warning on line 1678 in Dockerfile

View workflow job for this annotation

GitHub Actions / PR build and direct managed startup (OpenClaw)

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ENV "NEMOCLAW_DISABLE_DEVICE_AUTH") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/
NEMOCLAW_INFERENCE_PROVIDER_ID=${NEMOCLAW_INFERENCE_PROVIDER_ID} \
NEMOCLAW_UPSTREAM_PROVIDER=${NEMOCLAW_UPSTREAM_PROVIDER} \
NEMOCLAW_PRIMARY_MODEL_REF=${NEMOCLAW_PRIMARY_MODEL_REF} \
Expand Down
53 changes: 35 additions & 18 deletions agents/hermes/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ ARG NEMOCLAW_MANAGED_IMAGE_CAPABILITY_UNION=0
# The reviewed npm graph is audited in CI; image assembly copies only its
# generated runtime artifacts and therefore needs neither npm nor network.
FROM scratch AS mcp-tool-discovery-runtime
COPY tools/mcp-tool-discovery-runtime/reviewed-runtime-bundle/mcp-tool-discovery/BUNDLED_PACKAGES.json tools/mcp-tool-discovery-runtime/reviewed-runtime-bundle/mcp-tool-discovery/THIRD_PARTY_LICENSES.txt /opt/mcp-tool-discovery-runtime/dist/
COPY tools/mcp-tool-discovery-runtime/reviewed-runtime-bundle/mcp-tool-discovery/mcp-tool-discovery.bundle /opt/mcp-tool-discovery-runtime/dist/mcp-tool-discovery.mjs
# Set root ownership and read-only modes because scratch-stage COPY preserves source metadata.
COPY --chown=0:0 --chmod=0444 tools/mcp-tool-discovery-runtime/reviewed-runtime-bundle/mcp-tool-discovery/BUNDLED_PACKAGES.json tools/mcp-tool-discovery-runtime/reviewed-runtime-bundle/mcp-tool-discovery/THIRD_PARTY_LICENSES.txt /opt/mcp-tool-discovery-runtime/dist/
COPY --chown=0:0 --chmod=0444 tools/mcp-tool-discovery-runtime/reviewed-runtime-bundle/mcp-tool-discovery/mcp-tool-discovery.bundle /opt/mcp-tool-discovery-runtime/dist/mcp-tool-discovery.mjs

FROM scratch AS managed-startup-runtime-builder
COPY tools/mcp-tool-discovery-runtime/reviewed-runtime-bundle/managed-startup-image-runtime.bundle /out/managed-startup-image-runtime.cjs
COPY --chown=0:0 --chmod=0444 tools/mcp-tool-discovery-runtime/reviewed-runtime-bundle/managed-startup-image-runtime.bundle /out/managed-startup-image-runtime.cjs

# Compile the bootstrap boundary on the target platform. The output is a
# freestanding static ELF; only its reviewed, non-executable Bash body remains
Expand Down Expand Up @@ -364,21 +365,37 @@ RUN managed_runtime_assertion_failed() { \
exit 1; \
}; \
discovery_contract="$(node /usr/local/lib/nemoclaw/mcp-tool-discovery-runtime/mcp-tool-discovery.mjs)" \
&& node -e 'const result = JSON.parse(process.argv[1]); if (result.protocol !== 1 || result.ok !== false || result.detail !== "tool discovery received invalid runtime arguments") process.exit(1);' "$discovery_contract" \
&& discovery_unsafe="$(find -L /usr/local/lib/nemoclaw/mcp-tool-discovery-runtime \( ! -user root -o -perm /022 \) -print -quit)" \
&& test -z "$discovery_unsafe" \
&& { test -f /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs || managed_runtime_assertion_failed regular-file /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs; } \
&& { test ! -L /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs || managed_runtime_assertion_failed non-symlink /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs; } \
&& { chown root:root /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs 2>/dev/null || managed_runtime_assertion_failed owner-root-root /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs; } \
&& { chmod 0444 /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs 2>/dev/null || managed_runtime_assertion_failed mode-0444 /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs; } \
&& { test "$(stat -c '%u:%g:%a' /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs 2>/dev/null)" = '0:0:444' || managed_runtime_assertion_failed metadata-0:0:444 /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs; } \
&& test -f /usr/local/bin/nemoclaw-managed-bootstrap \
&& test ! -L /usr/local/bin/nemoclaw-managed-bootstrap \
&& test "$(stat -c '%u:%g:%a' /usr/local/bin/nemoclaw-managed-bootstrap)" = '0:0:755' \
&& test -f /usr/local/lib/nemoclaw/managed-bootstrap-trampoline.sh \
&& test ! -L /usr/local/lib/nemoclaw/managed-bootstrap-trampoline.sh \
&& test "$(stat -c '%u:%g:%a' /usr/local/lib/nemoclaw/managed-bootstrap-trampoline.sh)" = '0:0:444' \
&& install -d -o root -g root -m 0755 /run/nemoclaw
|| managed_runtime_assertion_failed discovery-exec /usr/local/lib/nemoclaw/mcp-tool-discovery-runtime/mcp-tool-discovery.mjs; \
node -e 'const result = JSON.parse(process.argv[1]); if (result.protocol !== 1 || result.ok !== false || result.detail !== "tool discovery received invalid runtime arguments") process.exit(1);' "$discovery_contract" \
|| managed_runtime_assertion_failed discovery-contract /usr/local/lib/nemoclaw/mcp-tool-discovery-runtime/mcp-tool-discovery.mjs; \
discovery_unsafe="$(find -L /usr/local/lib/nemoclaw/mcp-tool-discovery-runtime \( ! -user root -o -perm /022 \) -print -quit)" \
|| managed_runtime_assertion_failed discovery-tree-scan /usr/local/lib/nemoclaw/mcp-tool-discovery-runtime; \
test -z "$discovery_unsafe" \
|| managed_runtime_assertion_failed discovery-tree-owner-mode "$discovery_unsafe"; \
test -f /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs \
|| managed_runtime_assertion_failed regular-file /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs; \
test ! -L /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs \
|| managed_runtime_assertion_failed non-symlink /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs; \
chown root:root /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs 2>/dev/null \
|| managed_runtime_assertion_failed owner-root-root /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs; \
chmod 0444 /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs 2>/dev/null \
|| managed_runtime_assertion_failed mode-0444 /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs; \
test "$(stat -c '%u:%g:%a' /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs 2>/dev/null)" = '0:0:444' \
|| managed_runtime_assertion_failed metadata-0:0:444 /usr/local/lib/nemoclaw/managed-startup-image-runtime.cjs; \
test -f /usr/local/bin/nemoclaw-managed-bootstrap \
|| managed_runtime_assertion_failed managed-bootstrap-regular-file /usr/local/bin/nemoclaw-managed-bootstrap; \
test ! -L /usr/local/bin/nemoclaw-managed-bootstrap \
|| managed_runtime_assertion_failed managed-bootstrap-non-symlink /usr/local/bin/nemoclaw-managed-bootstrap; \
test "$(stat -c '%u:%g:%a' /usr/local/bin/nemoclaw-managed-bootstrap)" = '0:0:755' \
|| managed_runtime_assertion_failed managed-bootstrap-metadata-0:0:755 /usr/local/bin/nemoclaw-managed-bootstrap; \
test -f /usr/local/lib/nemoclaw/managed-bootstrap-trampoline.sh \
|| managed_runtime_assertion_failed managed-bootstrap-trampoline-regular-file /usr/local/lib/nemoclaw/managed-bootstrap-trampoline.sh; \
test ! -L /usr/local/lib/nemoclaw/managed-bootstrap-trampoline.sh \
|| managed_runtime_assertion_failed managed-bootstrap-trampoline-non-symlink /usr/local/lib/nemoclaw/managed-bootstrap-trampoline.sh; \
test "$(stat -c '%u:%g:%a' /usr/local/lib/nemoclaw/managed-bootstrap-trampoline.sh)" = '0:0:444' \
|| managed_runtime_assertion_failed managed-bootstrap-trampoline-metadata-0:0:444 /usr/local/lib/nemoclaw/managed-bootstrap-trampoline.sh; \
install -d -o root -g root -m 0755 /run/nemoclaw \
|| managed_runtime_assertion_failed runtime-directory-0:0:755 /run/nemoclaw

# Ensure sandbox user can read blueprint files copied as root
RUN chmod -R a+rX /opt/nemoclaw-blueprint/
Expand Down
Loading
Loading