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, 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", );