refactor: adapter 구현중..

This commit is contained in:
DongHyeonka
2026-08-13 16:02:21 +09:00
parent 30ceac23c1
commit 4dc033cf33
72 changed files with 13370 additions and 1549 deletions
+46
View File
@@ -37,6 +37,16 @@ const candidateSchema = z
})
.strict();
const providerRunSchema = runSchema.extend({ invocationNonce: nonce }).strict();
export const secretScanAttestationSchema = z
.object({
status: z.literal("PASS"),
localEvidenceAssessmentSha256: sha256,
sourceSetSha256: sha256,
policySha256: sha256,
sarifSha256: sha256,
scanInputSha256: sha256,
})
.strict();
const signatureSchema = z
.object({
algorithm: z.literal("Ed25519"),
@@ -60,6 +70,7 @@ export const vulnerabilityProviderReportSchema = z
.object({
...providerCommon,
evidenceType: z.literal("vulnerability-report"),
secretScanAttestation: secretScanAttestationSchema,
findings: z.array(z.record(z.string(), z.json())),
})
.strict();
@@ -95,6 +106,7 @@ const verificationCommon = {
vulnerabilityKeyFingerprint: fingerprint,
provenanceKeyId: nonEmptyString,
provenanceKeyFingerprint: fingerprint,
secretScanAttestation: secretScanAttestationSchema,
})
.strict(),
trustPolicySha256: sha256,
@@ -169,6 +181,7 @@ export type ExpectedPromotionContext = Readonly<{
}>;
vulnerabilityInvocationNonce: string;
provenanceInvocationNonce: string;
secretScanAttestation: z.infer<typeof secretScanAttestationSchema>;
}>;
export type PromotionEvidenceResult = Readonly<{
@@ -211,6 +224,12 @@ export function validateProviderEvidence(input: Readonly<{
now,
failures,
);
if (
JSON.stringify(parsed.data.secretScanAttestation) !==
JSON.stringify(input.expected.secretScanAttestation)
) {
failures.push("vulnerability report secret scan attestation mismatch");
}
if (parsed.data.findings.length > 0) {
failures.push("vulnerability report contains findings");
}
@@ -268,6 +287,7 @@ export function createTrustPolicy(input: Readonly<{
vulnerabilityTrust: ProviderTrust;
provenanceTrust: ProviderTrust;
}>) {
assertDistinctProviderTrust(input);
return Object.freeze({
algorithm: "Ed25519" as const,
vulnerability: Object.freeze({
@@ -283,6 +303,26 @@ export function createTrustPolicy(input: Readonly<{
});
}
export function assertDistinctProviderTrust(input: Readonly<{
vulnerabilityTrust: ProviderTrust;
provenanceTrust: ProviderTrust;
}>): void {
const vulnerabilityFingerprint = providerPublicKeyFingerprint(
input.vulnerabilityTrust.publicKey,
);
const provenanceFingerprint = providerPublicKeyFingerprint(
input.provenanceTrust.publicKey,
);
if (
input.vulnerabilityTrust.keyId === input.provenanceTrust.keyId ||
vulnerabilityFingerprint === provenanceFingerprint ||
input.vulnerabilityTrust.publicKeyFingerprint ===
input.provenanceTrust.publicKeyFingerprint
) {
throw new TypeError("provider trust roles require distinct key identities and DER-SPKI fingerprints");
}
}
export function trustPolicySha256(input: Readonly<{
vulnerabilityTrust: ProviderTrust;
provenanceTrust: ProviderTrust;
@@ -323,6 +363,12 @@ export function evaluatePromotionEvidence(input: Readonly<{
now,
failures,
);
if (
JSON.stringify(vulnerability.data.secretScanAttestation) !==
JSON.stringify(input.expected.secretScanAttestation)
) {
failures.push("vulnerability report secret scan attestation mismatch");
}
if (vulnerability.data.findings.length > 0) {
failures.push("vulnerability report contains findings");
}