import { dependencyDiffArtifactSchema, dependencyInventoryArtifactSchema, licenseReportArtifactSchema, supplyChainVerificationArtifactSchema, vulnerabilityReportArtifactSchema, } from "../contracts/release-artifacts.ts"; import type { DistOutput } from "./release-candidate.ts"; import { diffDependencyInventories, supplyChainDigest, validateDependencyReview, validateLicensePolicy, } from "./supply-chain.ts"; type Document = Record; export const LOCAL_SUPPLY_CHAIN_UNVERIFIED_DEFAULTS = Object.freeze({ promotionStatus: "FAIL_UNVERIFIED" as const, vulnerabilityStatus: "FAIL_UNVERIFIED" as const, provenanceAttestationStatus: "FAIL_UNVERIFIED" as const, }); export function verifyLocalSupplyChainDefaults(stored: unknown): string[] { const parsed = supplyChainVerificationArtifactSchema.safeParse(stored); if ( !parsed.success || parsed.data.promotionStatus !== LOCAL_SUPPLY_CHAIN_UNVERIFIED_DEFAULTS.promotionStatus || parsed.data.vulnerabilityStatus !== LOCAL_SUPPLY_CHAIN_UNVERIFIED_DEFAULTS.vulnerabilityStatus || parsed.data.provenanceAttestationStatus !== LOCAL_SUPPLY_CHAIN_UNVERIFIED_DEFAULTS.provenanceAttestationStatus ) { return [ "supply-chain verification provider defaults are not local FAIL_UNVERIFIED", ]; } return []; } export function createLocalVulnerabilityReport(lockfileSha256: string) { return vulnerabilityReportArtifactSchema.parse({ schemaVersion: 1, provider: "UNCONFIGURED", scannedLockfileSha256: lockfileSha256, status: "FAIL_UNVERIFIED", findings: [], exceptionsApplied: [], failures: ["external vulnerability provider report is missing"], blocking: [], }); } export function compareStoredLocalVulnerabilityReport( lockfileSha256: string, stored: unknown, ): string[] { const parsed = vulnerabilityReportArtifactSchema.safeParse(stored); if ( !parsed.success || supplyChainDigest(parsed.data) !== supplyChainDigest(createLocalVulnerabilityReport(lockfileSha256)) ) { return [ "local vulnerability report does not match exact unconfigured defaults", ]; } return []; } export function recomputeDependencyEvidence(input: Readonly<{ inventory: unknown; baseline: unknown; baselineApproval: unknown; dependencyChangeEvidence: unknown; skipBaseline?: boolean; }>) { const inventory = dependencyInventoryArtifactSchema.parse(input.inventory); const baseline = asDocument(input.baseline); const approval = asDocument(input.baselineApproval); const dependencyChangeEvidence = asDocument(input.dependencyChangeEvidence); const failures: string[] = []; const skipBaseline = input.skipBaseline === true; let diff: ReturnType = Object.freeze({ added: Object.freeze([]), removed: Object.freeze([]), changed: Object.freeze([]), upgrades: Object.freeze([]), }); let review: ReturnType = Object.freeze({ passed: skipBaseline, highRisk: Object.freeze([]), failures: Object.freeze( skipBaseline ? [] : ["dependency baseline unavailable"], ), }); const baselineDigest = baseline ? supplyChainDigest(baseline) : null; if (baseline && approval) { diff = diffDependencyInventories(baseline, inventory); review = validateDependencyReview( diff, inventory, dependencyChangeEvidence ?? {}, ); if ( approval.schemaVersion !== 1 || approval.snapshotDigest !== baselineDigest || typeof approval.owner !== "string" || approval.owner.trim().length === 0 ) { failures.push("dependency baseline approval digest mismatch"); } } else if (!skipBaseline) { failures.push("dependency baseline and approval are required"); } failures.push(...review.failures); const report = dependencyDiffArtifactSchema.parse({ schemaVersion: 2, baselineDigest, currentDigest: supplyChainDigest(inventory), ...diff, highRisk: review.highRisk, reviewFailures: review.failures, }); return Object.freeze({ report, dependencyDiff: diff, highRisk: review.highRisk, failures: Object.freeze(failures), }); } export function compareStoredDependencyEvidence( recomputed: ReturnType, stored: unknown, ): string[] { const parsed = dependencyDiffArtifactSchema.safeParse(stored); if ( !parsed.success || supplyChainDigest(parsed.data) !== supplyChainDigest(recomputed.report) ) { return ["stored dependency diff does not match recomputed policy evidence"]; } return [...recomputed.failures]; } export function recomputeLicenseEvidence(input: Readonly<{ inventory: unknown; policy: unknown; }>) { const inventory = dependencyInventoryArtifactSchema.parse(input.inventory); const policy = asDocument(input.policy) ?? {}; const result = validateLicensePolicy(inventory, policy); const report = licenseReportArtifactSchema.parse({ schemaVersion: 1, status: result.passed ? "PASS" : "FAIL", dependencyCount: inventory.dependencyCount, results: result.results, failures: result.failures, }); return Object.freeze({ report, failures: result.failures, }); } export function compareStoredLicenseEvidence( recomputed: ReturnType, stored: unknown, ): string[] { const parsed = licenseReportArtifactSchema.safeParse(stored); if ( !parsed.success || supplyChainDigest(parsed.data) !== supplyChainDigest(recomputed.report) ) { return ["stored license report does not match recomputed policy evidence"]; } return [...recomputed.failures]; } export function distChecksumsText(outputs: readonly DistOutput[]): string { return `${[...outputs] .sort((left, right) => left.path.localeCompare(right.path)) .map((output) => `${output.sha256} ${output.path}`) .join("\n")}\n`; } export function verifyStoredDistChecksums( outputs: readonly DistOutput[], stored: string, ): string[] { return stored === distChecksumsText(outputs) ? [] : ["stored dist checksums do not match current outputs"]; } function asDocument(value: unknown): Document | null { return value !== null && typeof value === "object" && !Array.isArray(value) ? (value as Document) : null; }