mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-14 08:26:46 +02:00
Integrate Node 24 security pin policy repair
Co-Authored-By: Paperclip <noreply@paperclip.ing> * codex/runner-cursor-acp: fix(ci): accept exact Node 24 security image pins
This commit is contained in:
commit
ac785ba09f
3 files changed
+24
-1
No files matched your search
@@ -1,6 +1,7 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { isNode24ImageTag } from "./node-image-policy.mjs";
|
||||
|
||||
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
||||
const expectedEngine = ">=24.11.0";
|
||||
@@ -48,7 +49,7 @@ walk(repoRoot, (filePath) => {
|
||||
if (!path.basename(filePath).startsWith("Dockerfile")) return;
|
||||
const source = fs.readFileSync(filePath, "utf8");
|
||||
for (const match of source.matchAll(/^\s*FROM\s+node:([^\s]+)/gm)) {
|
||||
if (!match[1].startsWith("24-")) failures.push(`${relative(filePath)}: Node base image must use the Node 24 major, found node:${match[1]}`);
|
||||
if (!isNode24ImageTag(match[1])) failures.push(`${relative(filePath)}: Node base image must use the Node 24 major, found node:${match[1]}`);
|
||||
}
|
||||
for (const match of source.matchAll(/^\s*ARG\s+NODE_(?:MAJOR|VERSION)=([^\s]+)/gm)) {
|
||||
if (match[1] !== "24") failures.push(`${relative(filePath)}: Node build argument must be 24, found ${match[1]}`);
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
// Accept the existing major tags and exact patch pins, with a required image variant.
|
||||
// A digest, when present, must be a complete SHA-256 pin.
|
||||
export function isNode24ImageTag(tag) {
|
||||
return /^24(?:\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*))?-[a-z0-9][a-z0-9._-]*(?:@sha256:[a-f0-9]{64})?$/.test(tag);
|
||||
}
|
||||
@@ -2,6 +2,23 @@ import assert from "node:assert/strict";
|
||||
import { createHash } from "node:crypto";
|
||||
import test from "node:test";
|
||||
import { standardImageDigest, resolveStandardImageDigest } from "./standard-image-contract.mjs";
|
||||
import { isNode24ImageTag } from "./node-image-policy.mjs";
|
||||
|
||||
test("Node image policy accepts Node 24 major tags and exact security pins", () => {
|
||||
for (const tag of ["24-trixie-slim", "24-bookworm-slim", "24-alpine3.23", "24.21.0-bookworm",
|
||||
`24.21.0-bookworm@sha256:${"a".repeat(64)}`, `24-bookworm@sha256:${"0".repeat(64)}`]) {
|
||||
assert.equal(isNode24ImageTag(tag), true, tag);
|
||||
}
|
||||
});
|
||||
|
||||
test("Node image policy rejects other majors, partial versions and malformed pins", () => {
|
||||
for (const tag of ["240-bookworm", "25.21.0-bookworm", "v24.21.0-bookworm", "latest",
|
||||
"24.21-bookworm", "24.21.0", "24.21.0-", "24..21.0-bookworm", "24.021.0-bookworm",
|
||||
"24.21.0-bookworm@sha256:short", `24.21.0-bookworm@@sha256:${"a".repeat(64)}`,
|
||||
`24.21.0-bookworm@sha256:${"a".repeat(64)}junk`, "${NODE_VERSION}-bookworm", "24-$(whoami)"]) {
|
||||
assert.equal(isNode24ImageTag(tag), false, tag);
|
||||
}
|
||||
});
|
||||
const descriptor = architecture => ({ platform: { os: "linux", architecture }, digest: `sha256:${"a".repeat(64)}`, size: 100 });
|
||||
const index = manifests => Buffer.from(JSON.stringify({ schemaVersion: 2, mediaType: "application/vnd.oci.image.index.v1+json", manifests }));
|
||||
test("signs the exact registry bytes, including both supported platforms", () => {
|
||||
|
||||
Reference in new issue
Block a user