UNPKG

snyk-docker-plugin

Version:
170 lines 8.95 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.parseProvenanceAttestations = void 0; const Debug = require("debug"); const dockerfile_1 = require("../dockerfile"); const debug = Debug("snyk"); const MAX_ATTESTATIONS_PER_IMAGE = 10; function getDecodedDockerfileContents(infos, dockerfileName) { const match = infos === null || infos === void 0 ? void 0 : infos.find((info) => info.filename === dockerfileName); if (!(match === null || match === void 0 ? void 0 : match.data)) { return null; } return Buffer.from(match.data, "base64").toString("utf8"); } async function analyseDecodedDockerfile(infos, dockerfileName) { const contents = getDecodedDockerfileContents(infos, dockerfileName); if (contents === null) { return null; } return (0, dockerfile_1.analyseDockerfile)(contents); } function getConfigSourceCommit(digest) { var _a; if (!digest) { return null; } const [algorithm, value] = (_a = Object.entries(digest)[0]) !== null && _a !== void 0 ? _a : []; if (!algorithm || !value) { return null; } return `${algorithm}:${value}`; } async function extractFieldsSlsaV0_2(predicate, attestedManifestDigest, attestationManifestDigest) { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l; const buildTimestamp = ((_a = predicate.metadata) === null || _a === void 0 ? void 0 : _a.buildStartedOn) || null; const buildkitMeta = (_b = predicate.metadata) === null || _b === void 0 ? void 0 : _b["https://mobyproject.org/buildkit@v1#metadata"]; const remoteCommit = getConfigSourceCommit((_d = (_c = predicate.invocation) === null || _c === void 0 ? void 0 : _c.configSource) === null || _d === void 0 ? void 0 : _d.digest); const localCommit = (_e = buildkitMeta === null || buildkitMeta === void 0 ? void 0 : buildkitMeta.vcs) === null || _e === void 0 ? void 0 : _e.revision; const buildConfigDigest = remoteCommit || localCommit || null; const buildConfigDigestSource = remoteCommit ? "remote" : localCommit ? "local" : null; const buildConfigSourceUri = ((_g = (_f = predicate.invocation) === null || _f === void 0 ? void 0 : _f.configSource) === null || _g === void 0 ? void 0 : _g.uri) || null; const builderId = ((_h = predicate.builder) === null || _h === void 0 ? void 0 : _h.id) || ""; const buildType = predicate.buildType || ""; const dockerfileName = ((_k = (_j = predicate.invocation) === null || _j === void 0 ? void 0 : _j.configSource) === null || _k === void 0 ? void 0 : _k.entryPoint) || "Dockerfile"; const dockerfileAnalysis = await analyseDecodedDockerfile((_l = buildkitMeta === null || buildkitMeta === void 0 ? void 0 : buildkitMeta.source) === null || _l === void 0 ? void 0 : _l.infos, dockerfileName); return { buildTimestamp, buildConfigDigest, buildConfigDigestSource, attestedManifestDigest, attestationManifestDigest, buildConfigSourceUri, builderId, buildType, dockerfileMetadata: { name: dockerfileName, analysis: dockerfileAnalysis, }, }; } async function extractFieldsSlsaV1_0(predicate, attestedManifestDigest, attestationManifestDigest) { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p; const runDetails = predicate.runDetails; const buildDefinition = predicate.buildDefinition; const buildTimestamp = ((_a = runDetails === null || runDetails === void 0 ? void 0 : runDetails.metadata) === null || _a === void 0 ? void 0 : _a.startedOn) || null; const remoteCommit = getConfigSourceCommit((_c = (_b = buildDefinition === null || buildDefinition === void 0 ? void 0 : buildDefinition.externalParameters) === null || _b === void 0 ? void 0 : _b.configSource) === null || _c === void 0 ? void 0 : _c.digest); const localCommit = (_f = (_e = (_d = runDetails === null || runDetails === void 0 ? void 0 : runDetails.metadata) === null || _d === void 0 ? void 0 : _d.buildkit_metadata) === null || _e === void 0 ? void 0 : _e.vcs) === null || _f === void 0 ? void 0 : _f.revision; const buildConfigDigest = remoteCommit || localCommit || null; const buildConfigDigestSource = remoteCommit ? "remote" : localCommit ? "local" : null; const buildConfigSourceUri = ((_h = (_g = buildDefinition === null || buildDefinition === void 0 ? void 0 : buildDefinition.externalParameters) === null || _g === void 0 ? void 0 : _g.configSource) === null || _h === void 0 ? void 0 : _h.uri) || null; const builderId = ((_j = runDetails === null || runDetails === void 0 ? void 0 : runDetails.builder) === null || _j === void 0 ? void 0 : _j.id) || ""; const buildType = (buildDefinition === null || buildDefinition === void 0 ? void 0 : buildDefinition.buildType) || ""; const dockerfileName = ((_l = (_k = buildDefinition === null || buildDefinition === void 0 ? void 0 : buildDefinition.externalParameters) === null || _k === void 0 ? void 0 : _k.configSource) === null || _l === void 0 ? void 0 : _l.path) || "Dockerfile"; const dockerfileAnalysis = await analyseDecodedDockerfile((_p = (_o = (_m = runDetails === null || runDetails === void 0 ? void 0 : runDetails.metadata) === null || _m === void 0 ? void 0 : _m.buildkit_metadata) === null || _o === void 0 ? void 0 : _o.source) === null || _p === void 0 ? void 0 : _p.infos, dockerfileName); return { buildTimestamp, buildConfigDigest, buildConfigDigestSource, attestedManifestDigest, attestationManifestDigest, buildConfigSourceUri, builderId, buildType, dockerfileMetadata: { name: dockerfileName, analysis: dockerfileAnalysis, }, }; } function getAttestedManifestDigest(statement) { var _a, _b, _c; const digest = (_b = (_a = statement.subject) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.digest; if (!digest) { return null; } const [algorithm, value] = (_c = Object.entries(digest)[0]) !== null && _c !== void 0 ? _c : []; if (!algorithm || !value) { return null; } return `${algorithm}:${value}`; } function getSlsaProvenanceVersion(predicateType) { switch (predicateType) { case "https://slsa.dev/provenance/v0.2": case "https://slsa.dev/provenance/v1": return predicateType; default: return null; } } async function parseStatement(statement, attestationManifestDigest, attestedManifestDigest) { const predicate = statement.predicate; if (!predicate) { debug("[provenance] No predicate found in in-toto statement"); return null; } const resolvedAttestedManifestDigest = attestedManifestDigest || getAttestedManifestDigest(statement); if (!resolvedAttestedManifestDigest) { debug("[provenance] Could not determine the attested manifest digest"); return null; } const predicateType = statement.predicateType; const version = getSlsaProvenanceVersion(predicateType); if (version === null) { debug(`[provenance] Unsupported SLSA predicate type: ${predicateType}`); return null; } switch (version) { case "https://slsa.dev/provenance/v0.2": return extractFieldsSlsaV0_2(predicate, resolvedAttestedManifestDigest, attestationManifestDigest); case "https://slsa.dev/provenance/v1": return extractFieldsSlsaV1_0(predicate, resolvedAttestedManifestDigest, attestationManifestDigest); default: { const _exhaustiveCheck = version; return _exhaustiveCheck; } } } async function parseProvenanceAttestations(attestationManifests) { const results = []; const sortedManifests = [...attestationManifests].sort((a, b) => a.manifestDigest.localeCompare(b.manifestDigest)); for (const attestation of sortedManifests) { const sortedLayers = [...attestation.manifest.layers].sort((a, b) => a.digest.localeCompare(b.digest)); for (const layer of sortedLayers) { if (results.length >= MAX_ATTESTATIONS_PER_IMAGE) { debug(`[provenance] Reached max attestation limit (${MAX_ATTESTATIONS_PER_IMAGE}), skipping remaining`); return results; } const inTotoStatement = attestation.inTotoStatements[layer.digest]; if (!inTotoStatement) { continue; } const parsed = await parseStatement(inTotoStatement, attestation.manifestDigest, attestation.attestedManifestDigest); if (parsed) { results.push(parsed); } } } return results; } exports.parseProvenanceAttestations = parseProvenanceAttestations; //# sourceMappingURL=provenance-parser.js.map