chore: initialize from frontend template 4dc033c
This commit is contained in:
@@ -0,0 +1,206 @@
|
||||
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<string, unknown>;
|
||||
|
||||
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<typeof diffDependencyInventories> = Object.freeze({
|
||||
added: Object.freeze([]),
|
||||
removed: Object.freeze([]),
|
||||
changed: Object.freeze([]),
|
||||
upgrades: Object.freeze([]),
|
||||
});
|
||||
let review: ReturnType<typeof validateDependencyReview> = 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<typeof recomputeDependencyEvidence>,
|
||||
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<typeof recomputeLicenseEvidence>,
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user