Files
Portfolio/tests/security/release-authority.test.ts

80 lines
2.5 KiB
TypeScript

import { mkdtemp, mkdir, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { describe, expect, test } from "vitest";
import {
canonicalJsonDigest,
canonicalValueBytes,
} from "../../src/security/canonical-digest.ts";
import {
verifySignedRelease,
verifySignedReleaseForTest,
} from "../../scripts/deploy/lib/release-common.mjs";
const h = (c: string) => c.repeat(64);
describe("protected release verification authority", () => {
test("production seam rejects caller-selected verifier, policy path, and time", async () => {
await expect(
verifySignedRelease({
signedManifestPath: "/not-used",
authorityRoot: "/not-used",
verifierModulePath: "/tmp/evil.mjs",
trustPolicyPath: "/tmp/evil.json",
now: "2000-01-01T00:00:00Z",
protectedState: {},
} as never),
).rejects.toThrow(/unknown|caller|production/i);
});
test("test seam still requires the protected trust-policy digest", async () => {
const root = await mkdtemp(join(tmpdir(), "portfolio-release-authority-"));
await mkdir(join(root, ".control"));
const signedManifestPath = join(root, "signed.json");
const trustPolicyPath = join(root, ".control", "release-trust.json");
const trustPolicy = {
schema: "portfolio-trust-policy/v1",
policyVersion: "test",
};
await writeFile(
signedManifestPath,
canonicalValueBytes({ schema: "signed" }),
);
await writeFile(trustPolicyPath, canonicalValueBytes(trustPolicy));
const protectedState = {
latestLedgerHeadHash: h("1"),
latestLedgerRevision: 1,
currentManifestDigest: null,
publisherFence: 0,
releaseTrustPolicyDigest: h("9"),
};
await expect(
verifySignedReleaseForTest({
signedManifestPath,
trustPolicyPath,
protectedState,
now: "2026-09-02T01:00:00Z",
verifySignedReleaseEnvelope: () => {
throw new Error("must not reach verifier");
},
}),
).rejects.toThrow(/trust.policy|authority|digest/i);
protectedState.releaseTrustPolicyDigest = canonicalJsonDigest(
"portfolio-trust-policy/v1",
trustPolicy,
);
await expect(
verifySignedReleaseForTest({
signedManifestPath,
trustPolicyPath,
protectedState,
now: "2026-09-02T01:00:00Z",
verifySignedReleaseEnvelope: () => {
throw new Error("reached-bound-verifier");
},
}),
).rejects.toThrow("reached-bound-verifier");
});
});