Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
0a1853c
fix(ci): trust npm 12 Brev template
cjagwani Sep 5, 2026
a1a0a68
test(ci): bind npm 12 Brev trust evidence
cjagwani Sep 5, 2026
4206008
fix(ci): stage reviewed npm bootstrap before trust
cjagwani Sep 5, 2026
90ee876
refactor(ci): consolidate reviewed npm bootstrap
cjagwani Sep 5, 2026
87ee5c1
fix(ci): reject npm version drift before install
cjagwani Sep 5, 2026
2d3b536
fix(ci): complete reviewed npm trust handoff
cjagwani Sep 5, 2026
e02c839
fix(ci): qualify reviewed npm bootstrap changes
cjagwani Sep 5, 2026
0d112df
fix(ci): close npm bootstrap publication gaps
cjagwani Sep 5, 2026
3786d51
docs(security): describe npm archive verification
cjagwani Sep 5, 2026
559b35a
test(ci): complete reviewed npm fixture identity
cjagwani Sep 8, 2026
b7adea8
merge(main): refresh npm trust prerequisite
cjagwani Sep 8, 2026
9228ab9
test(ci): remove source-shape review coverage
cjagwani Sep 8, 2026
80fa85c
merge(main): refresh npm trust review repair
cjagwani Sep 8, 2026
f90f4aa
test(ci): exercise reviewed npm trust handoff
cjagwani Sep 8, 2026
da62bbb
merge(main): refresh npm trust review repair
cjagwani Sep 8, 2026
0425c5e
Merge branch 'main' into codex/npm12-base-trust
cv Sep 8, 2026
a838b44
refactor(ci): clarify npm audit terminology
cjagwani Sep 8, 2026
ed5527c
Merge remote-tracking branch 'refs/remotes/origin/main' into codex/np…
cjagwani Sep 8, 2026
6c5207b
fix(ci): require npm audit failure evidence
cjagwani Sep 9, 2026
f84bc2d
merge: sync current main for patched js-yaml
cjagwani Sep 9, 2026
c670367
fix(ci): preserve npm audit signatures
cjagwani Sep 9, 2026
450938d
fix(ci): complete reviewed npm audit handoff
cjagwani Sep 9, 2026
334cff2
test(ci): validate reviewed npm failure routing
cjagwani Sep 9, 2026
5c10dc1
merge: sync current main
cjagwani Sep 9, 2026
3cc61fa
chore(node): use default TypeScript stripping
cjagwani Sep 9, 2026
c6b6db9
fix(ci): classify npm audit failures by evidence
cjagwani Sep 9, 2026
120f429
fix(ci): close npm audit review gaps
cjagwani Sep 9, 2026
3885100
fix(ci): classify invalid npm archive metadata
cjagwani Sep 9, 2026
c317455
merge: sync current main for Hermes image digest
cjagwani Sep 9, 2026
15bd4df
fix(ci): remove stale audit correlation branch
cjagwani Sep 9, 2026
9e2a42a
fix(ci): bind audit evidence to installed npm
cjagwani Sep 10, 2026
1dcbb4b
merge: sync current main for smol-toml advisory
cjagwani Sep 10, 2026
c5607f8
fix(ci): pass audit identity through CLI cache
cjagwani Sep 10, 2026
62ef062
fix(ci): bind receipts to reviewed npm identity
cjagwani Sep 10, 2026
03a94e9
fix(ci): tighten reviewed npm audit validation
cjagwani Sep 10, 2026
c70a28a
docs(skills): distinguish durable dependency contracts
cjagwani Sep 10, 2026
04e87bf
merge: sync current main for formatter baseline
cjagwani Sep 10, 2026
27d3e14
chore(test): apply current formatter baseline
cjagwani Sep 10, 2026
1dce30c
test(skills): enforce review report prohibition
cjagwani Sep 10, 2026
3a71dfc
Merge remote-tracking branch 'origin/main' into codex/npm12-base-trus…
cjagwani Sep 10, 2026
14e15b2
fix(ci): trust current Node 24 Brev template
cjagwani Sep 10, 2026
677317f
refactor(ci): reduce npm trust test duplication
cjagwani Sep 10, 2026
233cfd9
Merge branch 'main' into codex/npm12-base-trust
cjagwani Sep 10, 2026
bf8492a
Merge branch 'main' into codex/npm12-base-trust
cjagwani Sep 10, 2026
d575033
Merge branch 'main' into codex/npm12-base-trust
cjagwani Sep 10, 2026
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
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ Follow the current collector help when those controls evolve.

## Keep Point-in-Time Review Records out of the Repository

Do not commit point-in-time release ledgers, concern records, review reports, or qualification reports anywhere in the repository. Encode durable claims in executable configuration and tests. For a user-visible change, update the canonical `docs/` page with current supported behavior and operator action. Preserve historical executable fixtures only when they still support a current test.
Do not commit or update point-in-time release ledgers, concern records, dependency-review reports, review reports, or qualification reports anywhere in the repository. This prohibition does not apply to durable, code-synchronized dependency contract documents owned by a component. Encode durable claims in executable configuration and tests. For a user-visible change, update the canonical `docs/` page with current supported behavior and operator action. Preserve historical executable fixtures only when they still support a current test.

## Resolve concerns

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ const SYSTEM_EXECUTABLES = {
tail: "/usr/bin/tail",
wc: "/usr/bin/wc",
} as const;
const NPM_AUDIT_FAILURE_PATTERN =
/npm audit (?:threshold failed|scan remained incomplete|failed without vulnerability findings|requires npm [^\n;]+; running npm)|unused npm audit exceptions|\d+ unaccepted at or above (?:high|critical)/i;
const NPM_BOOTSTRAP_FAILURE_PATTERN =
/npm(?:@[0-9A-Za-z.-]+ archive (?:integrity mismatch|package\/package\.json is missing or invalid)| archive version [0-9A-Za-z.-]+ does not match reviewed npm@[0-9A-Za-z.-]+| audit configuration (?:is not valid JSON|has an invalid npm(?:Version|Integrity|ArchiveSha256)))/i;

type TrustedExecutableStat = {
isFile: () => boolean;
Expand Down Expand Up @@ -801,7 +805,12 @@ async function classifyCiFailureWithRuntime(
const selectedIndexes = new Set<number>();
let matchedLines = 0;
for (let index = 0; index < logLines.length; index += 1) {
if (!logPattern.test(logLines[index])) continue;
if (
!logPattern.test(logLines[index]) &&
!NPM_AUDIT_FAILURE_PATTERN.test(logLines[index]) &&
!NPM_BOOTSTRAP_FAILURE_PATTERN.test(logLines[index])
)
continue;
matchedLines += 1;
const first = Math.max(0, index - 20);
const last = Math.min(logLines.length - 1, index + 20);
Expand Down Expand Up @@ -1079,14 +1088,19 @@ async function classifyCiFailureWithRuntime(
"The environment-variable documentation gate failed.",
"Document the new NEMOCLAW_* variable in the required reference or remove it.",
);
if (
/reviewed-npm-audit/i.test(job.name) ||
/reviewed npm audit|npm audit report|audit-reviewed-npm-graph/i.test(text)
)
const hasNpmAuditFailure = NPM_AUDIT_FAILURE_PATTERN.test(text);
const hasNpmBootstrapFailure = NPM_BOOTSTRAP_FAILURE_PATTERN.test(text);
if (hasNpmBootstrapFailure)
add(
"reviewed-npm-bootstrap",
"The reviewed npm bootstrap rejected the pinned npm archive or identity.",
"Inspect the pinned npm identity and downloaded archive; do not change the advisory exception baseline.",
);
else if (hasNpmAuditFailure)
add(
"reviewed-npm-audit",
"The reviewed npm audit check reported advisory drift.",
"Determine whether this is live advisory drift or update the reviewed baseline through the security process.",
"The npm audit check reported advisory drift.",
"Determine whether this is live advisory drift or update the accepted baseline through the security process.",
);
if (/docs-review|Documentation writer review/i.test(text))
add(
Expand Down
8 changes: 1 addition & 7 deletions .dsh/tools/e2e_root_cause_correlator/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,6 @@ export default async function e2e_root_cause_correlator(input: {
return "launch-readiness/publication/evidence-failed";
if (text.includes("sandbox_phase=deleting") || text.includes("sandbox in deleting"))
return "openshell/lifecycle/sandbox-deleting";
if (
text.includes("reviewed npm audit") ||
text.includes("unaccepted at or above high") ||
text.includes("advisory")
)
return "dependency-audit/unaccepted-advisory";
if (text.includes("timed out") || text.includes("timeout"))
return "runtime/timeout/unclassified";
const first =
Expand Down Expand Up @@ -111,7 +105,7 @@ export default async function e2e_root_cause_correlator(input: {
(path) => file === path || file.startsWith(`${path}/`) || path.startsWith(`${file}/`),
),
);
const externalSignature = key.includes("dependency-audit") || key.includes("sandbox-deleting");
const externalSignature = key.includes("sandbox-deleting");
const classification =
matched.length > 0
? "source-change-candidate"
Expand Down
53 changes: 25 additions & 28 deletions .github/actions/ci-reviewed-npm-audit/action.yaml
Comment thread
cjagwani marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

name: ci-reviewed-npm-audit
description: Audit a target tree's reviewed production npm graphs from trusted CI code.
name: npm audit
description: Audit a target tree's production dependency graphs with the repository's pinned npm.

inputs:
target-root:
Expand All @@ -12,7 +12,7 @@ inputs:
description: Report directory relative to target-root.
required: true
cache-directory:
description: Absolute directory used for identity-bound reviewed npm audit records.
description: Absolute directory used for identity-bound npm audit records.
required: true
trusted-cache-write:
description: Whether this trusted caller may publish reusable audit records.
Expand All @@ -27,7 +27,7 @@ runs:
with:
node-version: "22.23.2"

- name: Resolve reviewed npm audit cache buckets
- name: Resolve npm audit cache buckets
id: cache-buckets
shell: bash
env:
Expand All @@ -39,66 +39,63 @@ runs:
previous_bucket="$(( current_bucket - 1 ))"
node --input-type=module - \
"$GITHUB_ACTION_PATH/../../../ci/reviewed-npm-audit.json" \
"$GITHUB_ACTION_PATH/../../../scripts/lib/repository-input-path.mts" <<'NODE'
"$GITHUB_ACTION_PATH/../../../scripts/lib/repository-input-path.mts" \
"$GITHUB_ACTION_PATH/../../../scripts/lib/reviewed-npm-audit.mts" <<'NODE'
import { createHash } from "node:crypto";
import { appendFileSync, readFileSync } from "node:fs";
import { join } from "node:path";
import { pathToFileURL } from "node:url";
const targetRoot = process.env.NEMOCLAW_REVIEWED_NPM_AUDIT_TARGET_ROOT;
const [configFile, resolverFile] = process.argv.slice(2);
const [configFile, resolverFile, reviewedNpmAuditFile] = process.argv.slice(2);
if (!targetRoot) {
throw new Error("reviewed npm audit target root is required");
throw new Error("npm audit target root is required");
}
const { resolvePathWithinRoot } = await import(pathToFileURL(resolverFile).href);
const { parseReviewedNpmIdentity } = await import(pathToFileURL(reviewedNpmAuditFile).href);
const configSource = readFileSync(configFile, "utf8");
const config = JSON.parse(configSource);
if (!/^(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)$/.test(config.npmVersion) || /[\r\n]/.test(config.npmVersion)) {
throw new Error("reviewed npm audit configuration has an invalid npmVersion");
}
if (!/^sha512-[A-Za-z0-9+/]+={0,2}$/.test(config.npmIntegrity) || /[\r\n]/.test(config.npmIntegrity)) {
throw new Error("reviewed npm audit configuration has an invalid npmIntegrity");
}
const identity = parseReviewedNpmIdentity(config);
const directories = ["", ...config.lockedGraphs.map((graph) => graph.directory)].sort();
const hash = createHash("sha256");
hash.update(configSource);
hash.update(JSON.stringify({ argv: ["audit", "--registry=https://registry.yarnpkg.com", "--omit=dev", "--json"], npmVersion: config.npmVersion, registry: "https://registry.yarnpkg.com/", schemaVersion: 1 }));
hash.update(JSON.stringify({ argv: ["audit", "--registry=https://registry.yarnpkg.com", "--omit=dev", "--json"], ...identity, registry: "https://registry.yarnpkg.com/", schemaVersion: 2 }));
for (const directory of directories) {
for (const file of ["package.json", "package-lock.json"]) {
const relative = join(directory, file);
hash.update(relative);
hash.update(readFileSync(resolvePathWithinRoot(targetRoot, relative, "reviewed npm audit target input")));
hash.update(readFileSync(resolvePathWithinRoot(targetRoot, relative, "npm audit target input")));
}
}
appendFileSync(
process.env.GITHUB_OUTPUT,
`input-digest=${hash.digest("hex")}\nnpm-version=${config.npmVersion}\nnpm-integrity=${config.npmIntegrity}\n`,
`input-digest=${hash.digest("hex")}\n`,
);
NODE
printf 'current=%s\nprevious=%s\n' "$current_bucket" "$previous_bucket" >> "$GITHUB_OUTPUT"
mkdir -p "$NEMOCLAW_REVIEWED_NPM_AUDIT_CACHE_DIRECTORY"

- name: Restore current reviewed npm audit cache bucket
- name: Restore current npm audit cache bucket
id: cache-current
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ${{ inputs.cache-directory }}
key: reviewed-npm-audit-v1-${{ runner.os }}-${{ steps.cache-buckets.outputs.input-digest }}-${{ steps.cache-buckets.outputs.current }}
key: reviewed-npm-audit-v2-${{ runner.os }}-${{ steps.cache-buckets.outputs.input-digest }}-${{ steps.cache-buckets.outputs.current }}

- name: Restore previous reviewed npm audit cache bucket
- name: Restore previous npm audit cache bucket
if: steps.cache-current.outputs.cache-hit != 'true'
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ${{ inputs.cache-directory }}
key: reviewed-npm-audit-v1-${{ runner.os }}-${{ steps.cache-buckets.outputs.input-digest }}-${{ steps.cache-buckets.outputs.previous }}
key: reviewed-npm-audit-v2-${{ runner.os }}-${{ steps.cache-buckets.outputs.input-digest }}-${{ steps.cache-buckets.outputs.previous }}

- name: Download and verify production npm
shell: bash
env:
NEMOCLAW_REVIEWED_NPM_VERSION: ${{ steps.cache-buckets.outputs.npm-version }}
NEMOCLAW_REVIEWED_NPM_INTEGRITY: ${{ steps.cache-buckets.outputs.npm-integrity }}
run: env -u NODE_AUTH_TOKEN -u NPM_TOKEN -u NPM_CONFIG__AUTH_TOKEN "$GITHUB_ACTION_PATH/verify-and-install-npm.sh"
run: >-
env -u NODE_AUTH_TOKEN -u NPM_TOKEN -u NPM_CONFIG__AUTH_TOKEN
"$GITHUB_ACTION_PATH/verify-and-install-npm.sh"
"$GITHUB_ACTION_PATH/../../../ci/reviewed-npm-audit.json"

- name: Materialize and audit reviewed npm graphs
- name: Materialize and audit production dependency graphs
shell: bash
env:
NEMOCLAW_REVIEWED_NPM_AUDIT_TARGET_ROOT: ${{ inputs.target-root }}
Expand All @@ -108,14 +105,14 @@ runs:
NPM_CONFIG_USERCONFIG: /dev/null
run: env -u NODE_AUTH_TOKEN -u NPM_TOKEN -u NPM_CONFIG__AUTH_TOKEN node "$GITHUB_ACTION_PATH/../../../scripts/audit-reviewed-npm-graph.mts"

- name: Save current reviewed npm audit cache bucket
- name: Save current npm audit cache bucket
if: inputs.trusted-cache-write == 'true' && steps.cache-current.outputs.cache-hit != 'true'
uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ${{ inputs.cache-directory }}
key: reviewed-npm-audit-v1-${{ runner.os }}-${{ steps.cache-buckets.outputs.input-digest }}-${{ steps.cache-buckets.outputs.current }}
key: reviewed-npm-audit-v2-${{ runner.os }}-${{ steps.cache-buckets.outputs.input-digest }}-${{ steps.cache-buckets.outputs.current }}

- name: Upload reviewed npm audit reports
- name: Upload npm audit reports
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
Expand Down
60 changes: 50 additions & 10 deletions .github/actions/ci-reviewed-npm-audit/verify-and-install-npm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,32 @@

set -euo pipefail

version="${NEMOCLAW_REVIEWED_NPM_VERSION:?}"
expected_integrity="${NEMOCLAW_REVIEWED_NPM_INTEGRITY:?}"
if [ "$#" -ne 1 ]; then
echo "ERROR: reviewed npm identity path is required." >&2
exit 1
fi

config_file="$1"
script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
download_dir="$(mktemp -d "$RUNNER_TEMP/reviewed-npm.XXXXXX")"
trap 'rm -rf "$download_dir"' EXIT

IFS=$'\t' read -r version expected_integrity expected_sha256 < <(
node --input-type=module - \
"$config_file" \
"$script_dir/../../../scripts/lib/reviewed-npm-audit.mts" <<'NODE'
import { readFileSync } from "node:fs";
import { pathToFileURL } from "node:url";

const [configFile, reviewedNpmAuditFile] = process.argv.slice(2);
const { parseReviewedNpmIdentityConfig } = await import(pathToFileURL(reviewedNpmAuditFile).href);
const identity = parseReviewedNpmIdentityConfig(readFileSync(configFile, "utf8"));
process.stdout.write(`${identity.npmVersion}\t${identity.npmIntegrity}\t${identity.npmArchiveSha256}\n`);
NODE
)
[ -n "$version" ]
[ -n "$expected_integrity" ]
[ -n "$expected_sha256" ]

npm pack "npm@$version" \
--pack-destination "$download_dir" \
Expand All @@ -15,19 +38,36 @@ npm pack "npm@$version" \
--ignore-scripts --no-audit --no-fund >/dev/null

archive="$download_dir/npm-$version.tgz"
actual_sha512="$(
node -e '
const fs = require("node:fs");
const crypto = require("node:crypto");
process.stdout.write(crypto.createHash("sha512").update(fs.readFileSync(process.argv[1])).digest("base64"));
' "$archive"
)"
IFS=$'\t' read -r actual_sha512 actual_sha256 < <(node -e '
const fs = require("node:fs");
const crypto = require("node:crypto");
const archive = fs.readFileSync(process.argv[1]);
process.stdout.write(
crypto.createHash("sha512").update(archive).digest("base64") + "\t" +
crypto.createHash("sha256").update(archive).digest("hex") + "\n",
);
' "$archive")
actual_integrity="sha512-$actual_sha512"
if [ "$actual_integrity" != "$expected_integrity" ]; then
if [ "$actual_integrity" != "$expected_integrity" ] || [ "$actual_sha256" != "$expected_sha256" ]; then
echo "ERROR: npm@$version archive integrity mismatch." >&2
exit 1
fi

if ! archive_version="$(
tar -xOf "$archive" package/package.json | node -e '
const version = JSON.parse(require("node:fs").readFileSync(0, "utf8")).version;
if (typeof version !== "string") process.exit(1);
process.stdout.write(version);
'
)"; then
echo "ERROR: npm@$version archive package/package.json is missing or invalid." >&2
exit 1
fi
if [ "$archive_version" != "$version" ]; then
echo "ERROR: npm archive version $archive_version does not match reviewed npm@$version." >&2
exit 1
fi

npm install --global "$archive" \
--userconfig /dev/null \
--ignore-scripts --no-audit --no-fund --offline
2 changes: 1 addition & 1 deletion .github/workflows/base-image-platform.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ jobs:
with:
persist-credentials: false

- name: Download same-run reviewed npm audit evidence
- name: Download same-run npm audit evidence
if: inputs.agent == 'openclaw'
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/managed-images.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ env:

jobs:
pr-reviewed-npm-audit:
name: PR reviewed npm audit
name: PR npm audit
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
timeout-minutes: 25
Expand All @@ -89,7 +89,7 @@ jobs:
path: candidate
persist-credentials: false

- name: Checkout trusted reviewed npm audit
- name: Checkout npm audit code from the base commit
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ github.event.pull_request.base.sha }}
Expand Down Expand Up @@ -475,7 +475,7 @@ jobs:
chmod 0664 "$artifact_path"
done

- name: Download same-run reviewed npm audit evidence
- name: Download same-run npm audit evidence
if: matrix.agent == 'openclaw'
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
Expand Down Expand Up @@ -1604,7 +1604,7 @@ jobs:
printf 'cohort=ghrun-%s-%s\n' "$GITHUB_RUN_ID" "$GITHUB_RUN_ATTEMPT" >> "$GITHUB_OUTPUT"

reviewed-npm-audit:
name: Reviewed npm audit for managed image publication
name: npm audit for managed image publication
if: github.event_name != 'pull_request'
runs-on: ubuntu-latest
timeout-minutes: 25
Expand Down Expand Up @@ -1721,7 +1721,7 @@ jobs:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0

- name: Download same-run reviewed npm audit evidence
- name: Download same-run npm audit evidence
if: matrix.agent == 'openclaw'
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ jobs:
with:
persist-credentials: false

- name: Checkout trusted reviewed npm audit
- name: Checkout npm audit code from the base commit
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ github.event.pull_request.base.sha }}
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -995,7 +995,7 @@
--package-lock /usr/local/lib/nemoclaw/mcporter-runtime/package-lock.json \
--raw-report "$MCPORTER_RAW_REPORT" --exceptions /scripts/npm-audit-exceptions.json \
--graph mcporter-runtime --audit-config /scripts/reviewed-npm-audit.json \
--registry https://registry.yarnpkg.com --threshold high --legacy-npmjs true; \
--registry https://registry.yarnpkg.com --threshold high --legacy-audit true; \
else \
node /scripts/lib/reviewed-npm-audit.mts \
--directory /usr/local/lib/nemoclaw/mcporter-runtime \
Expand Down Expand Up @@ -1570,10 +1570,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 1573 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 1576 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 @@ -1607,7 +1607,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 1610 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 1610 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
2 changes: 1 addition & 1 deletion Dockerfile.base
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ RUN --mount=type=bind,source=nemoclaw-blueprint/blueprint.yaml,target=/tmp/bluep
--raw-report "$MCPORTER_RAW_REPORT" --exceptions /scripts/npm-audit-exceptions.json \
--graph mcporter-runtime --audit-config /scripts/reviewed-npm-audit.json \
--registry https://registry.yarnpkg.com --threshold high \
--legacy-npmjs true \
--legacy-audit true \
--result /tmp/mcporter-npm-audit-policy.json \
&& cp "$MCPORTER_RAW_REPORT" /tmp/mcporter-npm-audit.json; \
else \
Expand Down
1 change: 1 addition & 0 deletions ci/reviewed-npm-audit.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"nodeVersion": "22.23.2",
"npmVersion": "10.9.4",
"npmIntegrity": "sha512-OnUG836FwboQIbqtefDNlyR0gTHzIfwRfE3DuiNewBvnMnWEpB0VEXwBlFVgqpNzIgYo/MHh3d2Hel/pszapAA==",
"npmArchiveSha256": "4bfba8a0c823024d1926ec9d97a37a00eb60fd2adf44b3d34a686fc32e8f51e4",
"registryOrigin": "https://registry.npmjs.org/",
"sourceRegistryPackage": {
"artifactName": "nvidia-openshell-sdk-0.0.106.tgz",
Expand Down
Loading
Loading