chore: initialize from frontend template 4dc033c
This commit is contained in:
@@ -0,0 +1,252 @@
|
||||
import { readFile } from "node:fs/promises";
|
||||
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import {
|
||||
supplyChainVerificationArtifactSchema,
|
||||
vulnerabilityReportArtifactSchema,
|
||||
} from "../../scripts/contracts/release-artifacts.ts";
|
||||
import {
|
||||
compareStoredDependencyEvidence,
|
||||
compareStoredLicenseEvidence,
|
||||
compareStoredLocalVulnerabilityReport,
|
||||
distChecksumsText,
|
||||
recomputeDependencyEvidence,
|
||||
recomputeLicenseEvidence,
|
||||
verifyLocalSupplyChainDefaults,
|
||||
verifyStoredDistChecksums,
|
||||
} from "../../scripts/lib/local-policy-evidence.ts";
|
||||
import {
|
||||
evaluateSecretScan,
|
||||
parseSecretScanPolicy,
|
||||
secretScanSarifSchema,
|
||||
verifyStoredSecretScan,
|
||||
} from "../../scripts/lib/secret-scan-evaluator.ts";
|
||||
import { supplyChainDigest } from "../../scripts/lib/supply-chain.ts";
|
||||
|
||||
const sha512Integrity = `sha512-${Buffer.alloc(64, 7).toString("base64")}`;
|
||||
const dependency = {
|
||||
name: "fixture",
|
||||
version: "1.0.0",
|
||||
direct: true,
|
||||
scope: "production" as const,
|
||||
optional: false,
|
||||
license: "MIT",
|
||||
integrity: sha512Integrity,
|
||||
dependencies: [],
|
||||
};
|
||||
const inventory = {
|
||||
schemaVersion: 2 as const,
|
||||
packageManager: "pnpm@11.17.0",
|
||||
lockfileSha256: "1".repeat(64),
|
||||
dependencyCount: 1,
|
||||
directDependencyCount: 1,
|
||||
dependencies: [dependency],
|
||||
};
|
||||
|
||||
describe("recomputed local promotion evidence", () => {
|
||||
it("rejects a schema-valid dependency report with a forged semantic digest", () => {
|
||||
const baseline = { ...inventory, dependencies: [] };
|
||||
const recomputed = recomputeDependencyEvidence({
|
||||
inventory,
|
||||
baseline,
|
||||
baselineApproval: {
|
||||
schemaVersion: 1,
|
||||
snapshotDigest: supplyChainDigest(baseline),
|
||||
owner: "platform-security",
|
||||
},
|
||||
dependencyChangeEvidence: {
|
||||
changes: [
|
||||
{
|
||||
changeId: "add:fixture@1.0.0",
|
||||
owner: "dependency-owner",
|
||||
reviewer: "security-reviewer",
|
||||
reason: "fixture",
|
||||
rollback: "remove fixture",
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
const tampered = {
|
||||
...recomputed.report,
|
||||
currentDigest: "f".repeat(64),
|
||||
};
|
||||
|
||||
expect(compareStoredDependencyEvidence(recomputed, tampered)).toContain(
|
||||
"stored dependency diff does not match recomputed policy evidence",
|
||||
);
|
||||
});
|
||||
|
||||
it("rejects a schema-valid PASS license report when policy recomputes FAIL", () => {
|
||||
const recomputed = recomputeLicenseEvidence({
|
||||
inventory,
|
||||
policy: {
|
||||
allowedLicenses: ["Apache-2.0"],
|
||||
deniedLicensePatterns: ["MIT"],
|
||||
},
|
||||
});
|
||||
const tampered = {
|
||||
schemaVersion: 1 as const,
|
||||
status: "PASS" as const,
|
||||
dependencyCount: 1,
|
||||
results: [
|
||||
{
|
||||
package: "fixture@1.0.0",
|
||||
license: "MIT",
|
||||
passed: true,
|
||||
reason: null,
|
||||
},
|
||||
],
|
||||
failures: [],
|
||||
};
|
||||
|
||||
expect(compareStoredLicenseEvidence(recomputed, tampered)).toContain(
|
||||
"stored license report does not match recomputed policy evidence",
|
||||
);
|
||||
});
|
||||
|
||||
it("rejects a checksum document that does not exactly describe sorted dist outputs", () => {
|
||||
const outputs = [
|
||||
{
|
||||
path: "dist/z.js",
|
||||
bytes: 1,
|
||||
gzipBytes: 21,
|
||||
sha256: "a".repeat(64),
|
||||
},
|
||||
{
|
||||
path: "dist/a.js",
|
||||
bytes: 1,
|
||||
gzipBytes: 21,
|
||||
sha256: "b".repeat(64),
|
||||
},
|
||||
];
|
||||
expect(distChecksumsText(outputs)).toBe(
|
||||
`${"b".repeat(64)} dist/a.js\n${"a".repeat(64)} dist/z.js\n`,
|
||||
);
|
||||
expect(
|
||||
verifyStoredDistChecksums(outputs, `${"c".repeat(64)} dist/a.js\n`),
|
||||
).toEqual(["stored dist checksums do not match current outputs"]);
|
||||
});
|
||||
|
||||
it("rejects an empty schema-valid SARIF when real fixture source contains secrets", async () => {
|
||||
const rawPolicy: unknown = JSON.parse(
|
||||
await readFile(
|
||||
"tests/fixtures/security/secret-detection/forbidden-policy.json",
|
||||
"utf8",
|
||||
),
|
||||
);
|
||||
const policy = parseSecretScanPolicy(rawPolicy);
|
||||
const inventoryFiles = [
|
||||
"tests/fixtures/security/secret-detection/forbidden/config.json",
|
||||
"tests/fixtures/security/secret-detection/forbidden/dist.ts",
|
||||
"tests/fixtures/security/secret-detection/forbidden/source.ts",
|
||||
];
|
||||
const evaluation = await evaluateSecretScan({
|
||||
policy,
|
||||
inventoryFiles,
|
||||
readText: (file) => readFile(file, "utf8"),
|
||||
now: Date.parse("2026-08-02T00:00:00.000Z"),
|
||||
});
|
||||
const fakeEmptySarif = secretScanSarifSchema.parse({
|
||||
version: "2.1.0",
|
||||
$schema: "https://json.schemastore.org/sarif-2.1.0.json",
|
||||
runs: [
|
||||
{
|
||||
tool: {
|
||||
driver: {
|
||||
name: "ca-frontend-secret-scan",
|
||||
rules: [
|
||||
"private-key",
|
||||
"aws-access-key",
|
||||
"github-token",
|
||||
"assigned-secret",
|
||||
].map((id) => ({
|
||||
id,
|
||||
shortDescription: { text: "Potential credential material" },
|
||||
})),
|
||||
},
|
||||
},
|
||||
results: [],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
expect(evaluation.findings).toHaveLength(3);
|
||||
expect(verifyStoredSecretScan(evaluation, fakeEmptySarif)).toEqual(
|
||||
expect.arrayContaining([
|
||||
"recomputed secret scan contains 3 blocking result(s)",
|
||||
"stored secret scan SARIF does not match recomputed results",
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it("rejects schema-valid verified provider statuses in local supply-chain evidence", () => {
|
||||
const localVerification = {
|
||||
schemaVersion: 1 as const,
|
||||
localStatus: "PASS" as const,
|
||||
promotionStatus: "FAIL_UNVERIFIED" as const,
|
||||
lockfileSha256: "1".repeat(64),
|
||||
sourceSetSha256: "2".repeat(64),
|
||||
distSha256: "3".repeat(64),
|
||||
sbomSha256: "4".repeat(64),
|
||||
dependencyDiff: {
|
||||
added: [],
|
||||
removed: [],
|
||||
changed: [],
|
||||
upgrades: [],
|
||||
},
|
||||
highRiskReview: [],
|
||||
vulnerabilityStatus: "FAIL_UNVERIFIED" as const,
|
||||
provenanceAttestationStatus: "FAIL_UNVERIFIED" as const,
|
||||
failures: [],
|
||||
};
|
||||
const tampered = [
|
||||
{ ...localVerification, promotionStatus: "PASS" as const },
|
||||
{ ...localVerification, vulnerabilityStatus: "PASS" as const },
|
||||
{
|
||||
...localVerification,
|
||||
provenanceAttestationStatus: "PASS" as const,
|
||||
},
|
||||
].map((value) => supplyChainVerificationArtifactSchema.parse(value));
|
||||
|
||||
for (const value of tampered) {
|
||||
expect(verifyLocalSupplyChainDefaults(value)).toEqual([
|
||||
"supply-chain verification provider defaults are not local FAIL_UNVERIFIED",
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
it("rejects every schema-valid drift from the exact local vulnerability report", () => {
|
||||
const currentLockfileSha256 = "1".repeat(64);
|
||||
const localReport = {
|
||||
schemaVersion: 1 as const,
|
||||
provider: "UNCONFIGURED",
|
||||
scannedLockfileSha256: currentLockfileSha256,
|
||||
status: "FAIL_UNVERIFIED" as const,
|
||||
findings: [],
|
||||
exceptionsApplied: [],
|
||||
failures: ["external vulnerability provider report is missing"],
|
||||
blocking: [],
|
||||
};
|
||||
const tampered = [
|
||||
{ ...localReport, provider: "forged-provider" },
|
||||
{ ...localReport, scannedLockfileSha256: "2".repeat(64) },
|
||||
{ ...localReport, status: "PASS" as const },
|
||||
{ ...localReport, findings: [{ id: "forged" }] },
|
||||
{ ...localReport, exceptionsApplied: [{ id: "forged" }] },
|
||||
{ ...localReport, failures: [] },
|
||||
{ ...localReport, blocking: ["forged"] },
|
||||
].map((value) => vulnerabilityReportArtifactSchema.parse(value));
|
||||
|
||||
for (const value of tampered) {
|
||||
expect(
|
||||
compareStoredLocalVulnerabilityReport(
|
||||
currentLockfileSha256,
|
||||
value,
|
||||
),
|
||||
).toEqual([
|
||||
"local vulnerability report does not match exact unconfigured defaults",
|
||||
]);
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user