fix: bind final release authority and expiry
This commit is contained in:
@@ -7,7 +7,7 @@ import { describe, expect, it } from 'vitest';
|
||||
import { canonicalValueBytes } from '../../src/security/canonical-digest.ts';
|
||||
|
||||
// @ts-expect-error The production release checker is an executable ESM module.
|
||||
import { verifySupplyChainEvidence } from '../../scripts/supply-chain-check.mjs';
|
||||
import { verifySupplyChainEvidence, verifySupplyChainEvidenceForTest } from '../../scripts/supply-chain-check.mjs';
|
||||
|
||||
const sha256 = (value: string | Buffer) => createHash('sha256').update(value).digest('hex');
|
||||
|
||||
@@ -87,10 +87,11 @@ async function evidenceFixture(overrides: Record<string, unknown> = {}) {
|
||||
}
|
||||
|
||||
const verifyFixture = (fixture: Awaited<ReturnType<typeof evidenceFixture>>, extra: Record<string, unknown> = {}) =>
|
||||
verifySupplyChainEvidence({
|
||||
verifySupplyChainEvidenceForTest({
|
||||
projectRoot: fixture.root,
|
||||
evidenceDir: fixture.evidence,
|
||||
toolTrustPolicyPath: fixture.trustPolicyPath,
|
||||
expectedCommitSha: 'b'.repeat(40),
|
||||
requireTrackedTriage: false,
|
||||
...extra,
|
||||
});
|
||||
@@ -151,4 +152,15 @@ describe('supply-chain evidence', () => {
|
||||
} });
|
||||
await expect(verifyFixture(unscanned)).rejects.toThrow(/repository|secret/u);
|
||||
});
|
||||
|
||||
it('keeps production authority and time non-caller-selectable', async () => {
|
||||
const fixture = await evidenceFixture();
|
||||
await expect(verifySupplyChainEvidence({
|
||||
projectRoot: fixture.root,
|
||||
evidenceDir: fixture.evidence,
|
||||
toolTrustPolicyPath: fixture.trustPolicyPath,
|
||||
now: '2026-09-02T12:00:00Z',
|
||||
today: '2026-09-02',
|
||||
})).rejects.toThrow(/production supply-chain request|unknown fields/u);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -252,6 +252,24 @@ describe("fenced atomic Nginx release transaction", () => {
|
||||
await expect(lstat(join(root, "current"))).rejects.toThrow();
|
||||
});
|
||||
|
||||
test("rechecks trusted time at the final pointer publication boundary", async () => {
|
||||
const { fixture, root, archive } = await setup(
|
||||
"portfolio-final-expiry-",
|
||||
);
|
||||
const input = transactionInput(root, archive, "tx-a", fixture);
|
||||
await prepareReleaseForTest(input);
|
||||
const times = ["2026-09-02T01:00:00Z", fixture.expiresAt];
|
||||
await expect(
|
||||
activateReleaseForTest({
|
||||
...input,
|
||||
expectedCurrentManifestDigest: null,
|
||||
expectedFence: 1,
|
||||
testClock: () => times.shift() ?? fixture.expiresAt,
|
||||
}),
|
||||
).rejects.toThrow(/expired.*publication/i);
|
||||
await expect(lstat(join(root, "current"))).rejects.toThrow();
|
||||
});
|
||||
|
||||
test("rollback requires a fresh signed manifest that binds the selected old artifact closure", async () => {
|
||||
const { temp, fixture, root, archive } = await setup("portfolio-rollback-");
|
||||
const inputA = transactionInput(root, archive, "tx-a", fixture);
|
||||
|
||||
Reference in New Issue
Block a user