Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
38 changes: 31 additions & 7 deletions test/openclaw-integrity-pin-suite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { describe, expect, it } from "vitest";
import { parseAuditExceptionRegistry } from "../scripts/lib/reviewed-npm-audit.mts";
import { createBuiltInChannelManifestRegistry } from "../src/lib/messaging";
import { reviewedOpenClawPluginIntegrityByPackageSpec } from "../src/lib/messaging/applier/build/messaging-build-applier.mts";

Expand Down Expand Up @@ -77,12 +78,20 @@ const MCPORTER_LOCKFILE = path.join(
"package-lock.json",
);
const NPM_AUDIT_EXCEPTION_FILE = path.join(REPO_ROOT, "ci", "npm-audit-exceptions.json");
const NPM_AUDIT_EXCEPTION_POLICY = fs.readFileSync(NPM_AUDIT_EXCEPTION_FILE, "utf-8");
const PINNED_MCPORTER_LOCK_SHA256 = createHash("sha256")
.update(fs.readFileSync(MCPORTER_LOCKFILE))
.digest("hex");
const NPM_AUDIT_EXCEPTION_POLICY_SHA256 = createHash("sha256")
.update(fs.readFileSync(NPM_AUDIT_EXCEPTION_FILE))
.update(NPM_AUDIT_EXCEPTION_POLICY)
.digest("hex");
const MCPORTER_AUDIT_EXCEPTIONS = parseAuditExceptionRegistry(NPM_AUDIT_EXCEPTION_POLICY)
.exceptions.filter((entry) => entry.graph === "mcporter-runtime")
.map((entry) => entry.advisory)
.sort();
const MCPORTER_AUDIT_EXCEPTION_LIST = MCPORTER_AUDIT_EXCEPTIONS.join(",") || "none";
const MCPORTER_AUDIT_STATUS =
MCPORTER_AUDIT_EXCEPTIONS.length > 0 ? "accepted-exceptions" : "clean";
const PINNED_OPENCLAW_DIAGNOSTICS_OTEL_INTEGRITY =
"sha512-XXhMifYWTgoR6yFN4T3JkHxdPvQCe8k1cNZjVIgXNmk1svCdBWuALfQQicmpemlmWwauIQuHYgBURY6k63e+rw==";
const PINNED_OPENCLAW_DIAGNOSTICS_OTEL_TARBALL =
Expand Down Expand Up @@ -122,9 +131,9 @@ function openClawBaseProvenance(
sha256: string;
status: "accepted-exceptions" | "clean";
}> = {
exceptions: "none",
exceptions: MCPORTER_AUDIT_EXCEPTION_LIST,
sha256: NPM_AUDIT_EXCEPTION_POLICY_SHA256,
status: "clean",
status: MCPORTER_AUDIT_STATUS,
},
): string {
const lockSha256 =
Expand Down Expand Up @@ -247,6 +256,16 @@ function runInstallBlock(
const auditExceptionPolicySha256 = createHash("sha256")
.update(auditExceptionPolicy)
.digest("hex");
const auditExceptionsByGraph: Record<string, string[]> = {};
for (const entry of (
JSON.parse(auditExceptionPolicy) as {
exceptions?: Array<{ advisory?: string; graph?: string }>;
}
).exceptions ?? []) {
if (!entry.advisory || !entry.graph) continue;
(auditExceptionsByGraph[entry.graph] ??= []).push(entry.advisory);
}
for (const advisories of Object.values(auditExceptionsByGraph)) advisories.sort();
fs.mkdirSync(path.dirname(mcporterBin), { recursive: true });
fs.mkdirSync(openclawRuntime, { recursive: true });
fs.mkdirSync(mcporterRuntime, { recursive: true });
Expand Down Expand Up @@ -313,7 +332,10 @@ function runInstallBlock(
"const value = (name) => args[args.indexOf(name) + 1];",
"const counts = { info: 0, low: 0, moderate: 0, high: 0, critical: 0 };",
"const report = { auditReportVersion: 2, vulnerabilities: {}, metadata: { vulnerabilities: counts } };",
`const policy = { schemaVersion: 1, graph: value("--graph"), blockingThreshold: value("--threshold"), exceptionPolicySha256: ${JSON.stringify(auditExceptionPolicySha256)}, reported: counts, status: "clean", acceptedAdvisories: [], unacceptedBlockingAdvisories: [] };`,
`const acceptedByGraph = ${JSON.stringify(auditExceptionsByGraph)};`,
'const graph = value("--graph");',
"const acceptedAdvisories = acceptedByGraph[graph] ?? [];",
`const policy = { schemaVersion: 1, graph, blockingThreshold: value("--threshold"), exceptionPolicySha256: ${JSON.stringify(auditExceptionPolicySha256)}, reported: counts, status: acceptedAdvisories.length > 0 ? "accepted-exceptions" : "clean", acceptedAdvisories, unacceptedBlockingAdvisories: [] };`,
'if (args.includes("--report")) fs.writeFileSync(value("--report"), `${JSON.stringify(report)}\\n`);',
'if (args.includes("--result")) fs.writeFileSync(value("--result"), `${JSON.stringify(policy)}\\n`);',
"console.log(`npm audit policy ${policy.graph}: clean`);",
Expand Down Expand Up @@ -1170,16 +1192,18 @@ export function registerOpenClawIntegrityPinTests(group: OpenClawIntegrityPinTes
"wrong mcporter audit status",
{
baseProvenance: openClawBaseProvenance().replace(
"mcporter-audit-status=clean",
"mcporter-audit-status=accepted-exceptions",
`mcporter-audit-status=${MCPORTER_AUDIT_STATUS}`,
`mcporter-audit-status=${
MCPORTER_AUDIT_STATUS === "clean" ? "accepted-exceptions" : "clean"
}`,
),
},
],
[
"wrong mcporter audit exceptions",
{
baseProvenance: openClawBaseProvenance().replace(
"mcporter-audit-exceptions=none",
`mcporter-audit-exceptions=${MCPORTER_AUDIT_EXCEPTION_LIST}`,
"mcporter-audit-exceptions=GHSA-aaaa-bbbb-cccc",
),
},
Expand Down
5 changes: 3 additions & 2 deletions test/reviewed-npm-audit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ const CONFIG = JSON.parse(
) as {
severityThreshold: "info" | "low" | "moderate" | "high" | "critical";
};
const EMPTY_POLICY = parseAuditExceptionRegistry(
const CHECKED_IN_POLICY = parseAuditExceptionRegistry(
fs.readFileSync(path.join(REPO_ROOT, "ci", "npm-audit-exceptions.json"), "utf-8"),
);
const EMPTY_POLICY: AuditExceptionRegistry = { schemaVersion: 1, exceptions: [] };
const NOW = new Date("2026-07-21T12:00:00Z");

function withInstalledGraph(
Expand Down Expand Up @@ -119,7 +120,7 @@ function exceptionPolicy(

describe("reviewed npm audit gate", () => {
it("uses an empty exception registry by default", () => {
expect(EMPTY_POLICY).toEqual({ schemaVersion: 1, exceptions: [] });
expect(CHECKED_IN_POLICY).toEqual(EMPTY_POLICY);
});

it("fails at high or critical findings while retaining lower severities", () => {
Expand Down
Loading