Files
clean-architecture-frontend…/scripts/check-supply-chain-provider-fixtures.ts
T

129 lines
3.4 KiB
TypeScript

import { generateKeyPairSync, sign } from "node:crypto";
import { mkdir, writeFile } from "node:fs/promises";
import {
evaluatePromotionEvidence,
providerEvidenceSignaturePayload,
} from "./lib/provider-evidence.ts";
const candidateDistSha256 = "1".repeat(64);
const lockfileSha256 = "2".repeat(64);
const vulnerabilityKeys = generateKeyPairSync("ed25519");
const provenanceKeys = generateKeyPairSync("ed25519");
const trust = {
vulnerabilityTrust: {
keyId: "fixture-vulnerability-key",
publicKey: vulnerabilityKeys.publicKey,
},
provenanceTrust: {
keyId: "fixture-provenance-key",
publicKey: provenanceKeys.publicKey,
},
};
function signedEvidence(
value: Record<string, unknown>,
keyId: string,
privateKey: typeof vulnerabilityKeys.privateKey,
) {
return {
...value,
signature: {
algorithm: "Ed25519",
keyId,
value: sign(
null,
providerEvidenceSignaturePayload(value),
privateKey,
).toString("base64"),
},
};
}
function evidenceFor(distDigest: string) {
return {
vulnerabilityReport: signedEvidence(
{
schemaVersion: 1,
provider: "fixture-vulnerability-provider",
generatedAt: "2026-08-01T00:00:00.000Z",
scannedLockfileSha256: lockfileSha256,
scannedDistSha256: distDigest,
findings: [],
},
"fixture-vulnerability-key",
vulnerabilityKeys.privateKey,
),
provenanceAttestation: signedEvidence(
{
schemaVersion: 1,
provider: "fixture-provenance-provider",
signer: "fixture-workload-identity",
generatedAt: "2026-08-01T00:00:00.000Z",
subject: { name: "dist", digest: { sha256: distDigest } },
},
"fixture-provenance-key",
provenanceKeys.privateKey,
),
};
}
const base = {
candidate: { distSha256: candidateDistSha256, lockfileSha256 },
currentDistSha256: candidateDistSha256,
localStatus: "PASS",
...trust,
};
const validEvidence = evidenceFor(candidateDistSha256);
const fixtures = {
absent: evaluatePromotionEvidence({
...base,
vulnerabilityReport: null,
provenanceAttestation: null,
}),
validImmutable: evaluatePromotionEvidence({ ...base, ...validEvidence }),
wrongDigest: evaluatePromotionEvidence({
...base,
...evidenceFor("3".repeat(64)),
}),
postAttestationMutation: evaluatePromotionEvidence({
...base,
...validEvidence,
currentDistSha256: "4".repeat(64),
}),
};
const passed =
fixtures.validImmutable.status === "PASS" &&
fixtures.absent.status === "FAIL_UNVERIFIED" &&
fixtures.wrongDigest.status === "FAIL_UNVERIFIED" &&
fixtures.postAttestationMutation.status === "FAIL_UNVERIFIED";
await mkdir("artifacts/security", { recursive: true });
await writeFile(
"artifacts/security/supply-chain-provider-fixtures.json",
`${JSON.stringify(
{
schemaVersion: 1,
fixtures: Object.fromEntries(
Object.entries(fixtures).map(([name, result]) => [
name,
{ status: result.status, failures: result.failures },
]),
),
passingFixtureCount: Object.values(fixtures).filter(
(result) => result.status === "PASS",
).length,
status: passed ? "PASS" : "FAIL",
},
null,
2,
)}\n`,
);
if (!passed) {
process.stderr.write("Supply-chain provider fixtures failed closed incorrectly\n");
process.exit(1);
}
process.stdout.write(
"Supply-chain provider fixtures: only the valid immutable fixture PASS\n",
);