Skip to content

Commit 662d724

Browse files
Generate SBOM for the oci-builder
1 parent a32081e commit 662d724

File tree

2 files changed

+82
-3
lines changed

2 files changed

+82
-3
lines changed

.test/meta-commands/out.sh

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,42 @@ jq -s '
137137
)
138138
' temp/index.json > temp/index.json.new
139139
mv temp/index.json.new temp/index.json
140+
# SBOM
141+
originalImageManifest="$(jq -r '.manifests[0].digest' temp/index.json)"
142+
SOURCE_DATE_EPOCH=1709081058 \
143+
docker buildx build --progress=plain \
144+
--load=false \
145+
--provenance=false \
146+
--build-arg BUILDKIT_DOCKERFILE_CHECK=skip=all \
147+
--sbom=generator="$BASHBREW_BUILDKIT_SBOM_GENERATOR" \
148+
--output 'type=oci,tar=false,dest=sbom' \
149+
--platform 'linux/amd64' \
150+
--build-context "fake=oci-layout://$PWD/temp@$originalImageManifest" \
151+
- <<<'FROM fake'
152+
sbomIndex="$(jq -r '.manifests[0].digest' sbom/index.json)"
153+
shell="$(jq -r --arg originalImageManifest "$originalImageManifest" '
154+
first(
155+
.manifests[]
156+
| select(.annotations["vnd.docker.reference.type"] == "attestation-manifest")
157+
) as $attDesc
158+
| @sh "sbomManifest=\($attDesc.digest)",
159+
@sh "sbomManifestDesc=\(
160+
$attDesc
161+
| .annotations["vnd.docker.reference.digest"] = $originalImageManifest
162+
| tojson
163+
)"
164+
' "sbom/blobs/${sbomIndex/://}")"
165+
eval "$shell"
166+
shell="$(jq -r '
167+
"copyBlobs=( \([ .config.digest, .layers[].digest | @sh ] | join(" ")) )"
168+
' "sbom/blobs/${sbomManifest/://}")"
169+
eval "$shell"
170+
copyBlobs+=( "$sbomManifest" )
171+
for blob in "${copyBlobs[@]}"; do
172+
cp "sbom/blobs/${blob/://}" "temp/blobs/${blob/://}"
173+
done
174+
jq -r --argjson sbomManifestDesc "$sbomManifestDesc" '.manifests += [ $sbomManifestDesc ]' temp/index.json > temp/index.json.new
175+
mv temp/index.json.new temp/index.json
140176
# </build>
141177
# <push>
142178
crane push --index temp 'oisupport/staging-amd64:191402ad0feacf03daf9d52a492207e73ef08b0bd17265043aea13aa27e2bb3f'

meta.jq

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -319,9 +319,52 @@ def build_command:
319319

320320
# TODO consider / check what "crane validate" does and if it would be appropriate here
321321

322-
# TODO generate SBOM? ... somehow
323-
324-
empty
322+
if build_should_sbom then
323+
# we'll trick BuildKit into generating an SBOM for us, then inject it into our OCI layout
324+
"# SBOM",
325+
"originalImageManifest=\"$(jq -r '.manifests[0].digest' temp/index.json)\"",
326+
(
327+
[
328+
@sh "SOURCE_DATE_EPOCH=\(.source.entry.SOURCE_DATE_EPOCH)",
329+
"docker buildx build --progress=plain",
330+
"--load=false", "--provenance=false", # explicitly disable a few features we want to avoid
331+
"--build-arg BUILDKIT_DOCKERFILE_CHECK=skip=all", # disable linting (https://github.com/moby/buildkit/pull/4962)
332+
"--sbom=generator=\"$BASHBREW_BUILDKIT_SBOM_GENERATOR\"",
333+
"--output 'type=oci,tar=false,dest=sbom'",
334+
# TODO also add appropriate "--tag" lines (which would give us a mostly correct "subject" block in the generated SBOM, but we'd then need to replace instances of ${sbomImageManifest#*:} with ${originalImageManifest#*:} for their values to be correct)
335+
@sh "--platform \(.source.arches[.build.arch].platformString)",
336+
"--build-context \"fake=oci-layout://$PWD/temp@$originalImageManifest\"",
337+
"- <<<'FROM fake'", # note: "<<<" is a bashism (so this output must be invoked via bash)
338+
empty
339+
] | join(" \\\n\t")
340+
),
341+
"sbomIndex=\"$(jq -r '.manifests[0].digest' sbom/index.json)\"",
342+
@sh "shell=\"$(jq -r --arg originalImageManifest \"$originalImageManifest\" \("
343+
# https://docs.docker.com/build/attestations/attestation-storage/
344+
first(
345+
.manifests[]
346+
| select(.annotations[\"vnd.docker.reference.type\"] == \"attestation-manifest\")
347+
) as $attDesc
348+
| @sh \"sbomManifest=\\($attDesc.digest)\",
349+
@sh \"sbomManifestDesc=\\(
350+
$attDesc
351+
| .annotations[\"vnd.docker.reference.digest\"] = $originalImageManifest
352+
| tojson
353+
)\"
354+
" | unindent_and_decomment_jq(4)) \"sbom/blobs/${sbomIndex/://}\")\"",
355+
"eval \"$shell\"",
356+
@sh "shell=\"$(jq -r \("
357+
\"copyBlobs=( \\([ .config.digest, .layers[].digest | @sh ] | join(\" \")) )\"
358+
" | unindent_and_decomment_jq(4)) \"sbom/blobs/${sbomManifest/://}\")\"",
359+
"eval \"$shell\"",
360+
"copyBlobs+=( \"$sbomManifest\" )",
361+
"for blob in \"${copyBlobs[@]}\"; do",
362+
"\tcp \"sbom/blobs/${blob/://}\" \"temp/blobs/${blob/://}\"",
363+
"done",
364+
"jq -r --argjson sbomManifestDesc \"$sbomManifestDesc\" '.manifests += [ $sbomManifestDesc ]' temp/index.json > temp/index.json.new",
365+
"mv temp/index.json.new temp/index.json",
366+
empty
367+
else empty end
325368
] | join("\n")
326369
else
327370
error("unknown/unimplemented Builder: \($builder)")

0 commit comments

Comments
 (0)