diff --git a/.test/meta-commands/out.sh b/.test/meta-commands/out.sh
index cf8cc9a..4807a46 100644
--- a/.test/meta-commands/out.sh
+++ b/.test/meta-commands/out.sh
@@ -53,6 +53,42 @@ jq '
' temp/index.json > temp/index.json.new
mv temp/index.json.new temp/index.json
#
+#
+build_output=$(
+ docker buildx build --progress=rawjson \
+ --provenance=false \
+ --sbom=generator="$BASHBREW_BUILDKIT_SBOM_GENERATOR" \
+ --tag 'docker:24.0.7-cli' \
+ --tag 'docker:24.0-cli' \
+ --tag 'docker:24-cli' \
+ --tag 'docker:cli' \
+ --tag 'docker:24.0.7-cli-alpine3.18' \
+ --tag 'amd64/docker:24.0.7-cli' \
+ --tag 'amd64/docker:24.0-cli' \
+ --tag 'amd64/docker:24-cli' \
+ --tag 'amd64/docker:cli' \
+ --tag 'amd64/docker:24.0.7-cli-alpine3.18' \
+ --tag 'oisupport/staging-amd64:4b199ac326c74b3058a147e14f553af9e8e1659abc29bd3e82c9c9807b66ee43' \
+ --output '"type=oci","tar=false","dest=sbom"' \
+ - <<<'FROM oisupport/staging-amd64:4b199ac326c74b3058a147e14f553af9e8e1659abc29bd3e82c9c9807b66ee43@sha256:0432a4d379794811b4a2e01d0d3e67a9bcf95d6c2bf71545f03bce3f1d60f401' 2>&1
+)
+attest_manifest_digest=$(
+ echo "$build_output" | jq -rs '
+ .[]
+ | select(.statuses).statuses[]
+ | select((.completed != null) and (.id | startswith("exporting attestation manifest"))).id
+ | sub("exporting attestation manifest "; "")
+ '
+)
+sbom_digest=$(
+ jq -r '
+ .layers[] | select(.annotations["in-toto.io/predicate-type"] == "https://spdx.dev/Document").digest
+ ' "sbom/blobs/${attest_manifest_digest//://}"
+)
+jq -c --arg digest "sha256:0432a4d379794811b4a2e01d0d3e67a9bcf95d6c2bf71545f03bce3f1d60f401" '
+ .subject[].digest |= ($digest | split(":") | {(.[0]): .[1]})
+' "sbom/blobs/${sbom_digest//://}" > sbom.json
+#
#
crane push temp 'oisupport/staging-amd64:4b199ac326c74b3058a147e14f553af9e8e1659abc29bd3e82c9c9807b66ee43'
rm -rf temp
@@ -88,6 +124,48 @@ SOURCE_DATE_EPOCH=1700741054 \
--file 'Dockerfile' \
'https://github.com/docker-library/docker.git#6d541d27b5dd12639e5a33a675ebca04d3837d74:24/windows/windowsservercore-ltsc2022'
#
+#
+build_output=$(
+ docker buildx build --progress=rawjson \
+ --provenance=false \
+ --sbom=generator="$BASHBREW_BUILDKIT_SBOM_GENERATOR" \
+ --tag 'docker:24.0.7-windowsservercore-ltsc2022' \
+ --tag 'docker:24.0-windowsservercore-ltsc2022' \
+ --tag 'docker:24-windowsservercore-ltsc2022' \
+ --tag 'docker:windowsservercore-ltsc2022' \
+ --tag 'docker:24.0.7-windowsservercore' \
+ --tag 'docker:24.0-windowsservercore' \
+ --tag 'docker:24-windowsservercore' \
+ --tag 'docker:windowsservercore' \
+ --tag 'winamd64/docker:24.0.7-windowsservercore-ltsc2022' \
+ --tag 'winamd64/docker:24.0-windowsservercore-ltsc2022' \
+ --tag 'winamd64/docker:24-windowsservercore-ltsc2022' \
+ --tag 'winamd64/docker:windowsservercore-ltsc2022' \
+ --tag 'winamd64/docker:24.0.7-windowsservercore' \
+ --tag 'winamd64/docker:24.0-windowsservercore' \
+ --tag 'winamd64/docker:24-windowsservercore' \
+ --tag 'winamd64/docker:windowsservercore' \
+ --tag 'oisupport/staging-windows-amd64:9b405cfa5b88ba65121aabdb95ae90fd2e1fee7582174de82ae861613ae3072e' \
+ --output '"type=oci","tar=false","dest=sbom"' \
+ - <<<'FROM oisupport/staging-windows-amd64:9b405cfa5b88ba65121aabdb95ae90fd2e1fee7582174de82ae861613ae3072e@sha256:69aba7120e3f4014bfa80f4eae2cfc9698dcb6b8a5d64daf06de4039a19846ce' 2>&1
+)
+attest_manifest_digest=$(
+ echo "$build_output" | jq -rs '
+ .[]
+ | select(.statuses).statuses[]
+ | select((.completed != null) and (.id | startswith("exporting attestation manifest"))).id
+ | sub("exporting attestation manifest "; "")
+ '
+)
+sbom_digest=$(
+ jq -r '
+ .layers[] | select(.annotations["in-toto.io/predicate-type"] == "https://spdx.dev/Document").digest
+ ' "sbom/blobs/${attest_manifest_digest//://}"
+)
+jq -c --arg digest "sha256:69aba7120e3f4014bfa80f4eae2cfc9698dcb6b8a5d64daf06de4039a19846ce" '
+ .subject[].digest |= ($digest | split(":") | {(.[0]): .[1]})
+' "sbom/blobs/${sbom_digest//://}" > sbom.json
+#
#
docker push 'oisupport/staging-windows-amd64:9b405cfa5b88ba65121aabdb95ae90fd2e1fee7582174de82ae861613ae3072e'
#
@@ -174,6 +252,52 @@ done
jq -r --argjson sbomManifestDesc "$sbomManifestDesc" '.manifests += [ $sbomManifestDesc ]' temp/index.json > temp/index.json.new
mv temp/index.json.new temp/index.json
#
+#
+build_output=$(
+ docker buildx build --progress=rawjson \
+ --provenance=false \
+ --sbom=generator="$BASHBREW_BUILDKIT_SBOM_GENERATOR" \
+ --tag 'busybox:1.36.1' \
+ --tag 'busybox:1.36' \
+ --tag 'busybox:1' \
+ --tag 'busybox:stable' \
+ --tag 'busybox:latest' \
+ --tag 'busybox:1.36.1-glibc' \
+ --tag 'busybox:1.36-glibc' \
+ --tag 'busybox:1-glibc' \
+ --tag 'busybox:stable-glibc' \
+ --tag 'busybox:glibc' \
+ --tag 'amd64/busybox:1.36.1' \
+ --tag 'amd64/busybox:1.36' \
+ --tag 'amd64/busybox:1' \
+ --tag 'amd64/busybox:stable' \
+ --tag 'amd64/busybox:latest' \
+ --tag 'amd64/busybox:1.36.1-glibc' \
+ --tag 'amd64/busybox:1.36-glibc' \
+ --tag 'amd64/busybox:1-glibc' \
+ --tag 'amd64/busybox:stable-glibc' \
+ --tag 'amd64/busybox:glibc' \
+ --tag 'oisupport/staging-amd64:191402ad0feacf03daf9d52a492207e73ef08b0bd17265043aea13aa27e2bb3f' \
+ --output '"type=oci","tar=false","dest=sbom"' \
+ - <<<'FROM oisupport/staging-amd64:191402ad0feacf03daf9d52a492207e73ef08b0bd17265043aea13aa27e2bb3f@sha256:4be429a5fbb2e71ae7958bfa558bc637cf3a61baf40a708cb8fff532b39e52d0' 2>&1
+)
+attest_manifest_digest=$(
+ echo "$build_output" | jq -rs '
+ .[]
+ | select(.statuses).statuses[]
+ | select((.completed != null) and (.id | startswith("exporting attestation manifest"))).id
+ | sub("exporting attestation manifest "; "")
+ '
+)
+sbom_digest=$(
+ jq -r '
+ .layers[] | select(.annotations["in-toto.io/predicate-type"] == "https://spdx.dev/Document").digest
+ ' "sbom/blobs/${attest_manifest_digest//://}"
+)
+jq -c --arg digest "sha256:4be429a5fbb2e71ae7958bfa558bc637cf3a61baf40a708cb8fff532b39e52d0" '
+ .subject[].digest |= ($digest | split(":") | {(.[0]): .[1]})
+' "sbom/blobs/${sbom_digest//://}" > sbom.json
+#
#
crane push --index temp 'oisupport/staging-amd64:191402ad0feacf03daf9d52a492207e73ef08b0bd17265043aea13aa27e2bb3f'
rm -rf temp
diff --git a/meta.jq b/meta.jq
index 947531e..6ff7632 100644
--- a/meta.jq
+++ b/meta.jq
@@ -369,6 +369,107 @@ def build_command:
error("unknown/unimplemented Builder: \($builder)")
end
;
+
+# input: "build" object (with "buildId" top level key)
+def image_digest:
+ .build.resolved.manifests[0].digest
+;
+
+# input: "build" object (with "buildId" top level key)
+def image_ref:
+ "\(.build.img)@\(image_digest)"
+;
+
+# input: "build" object (with "buildId" top level key)
+# output: string "command for generating an SBOM from an OCI layout", may be multiple lines, expects to run in Bash with "set -Eeuo pipefail"
+def sbom_command:
+ [
+ "build_output=$(",
+ (
+ [
+ "\tdocker buildx build --progress=rawjson",
+ "--provenance=false",
+ "--sbom=generator=\"$BASHBREW_BUILDKIT_SBOM_GENERATOR\"",
+ (
+ (
+ .source.arches[.build.arch]
+ | .tags[], .archTags[]
+ ),
+ .build.img
+ | "--tag " + @sh
+ ),
+ "--output " + (
+ [
+ "type=oci",
+ "tar=false",
+ "dest=sbom",
+ empty
+ ]
+ | @csv
+ | @sh
+ ),
+ "- <<<" + (
+ [
+ "FROM ",
+ image_ref,
+ empty
+ ]
+ | join("")
+ | @sh
+ ) + " 2>&1",
+ empty
+ ] | join(" \\\n\t")
+ ),
+ ")",
+ # Using the method above assigns the wrong image digest in the SBOM subjects. This replaces it with the correct one
+ # Get the digest of the attestation manifest provided by BuildKit
+ "attest_manifest_digest=$(",
+ (
+ [
+ "\techo \"$build_output\" | jq -rs '",
+ (
+ [
+ "\t.[]",
+ "| select(.statuses).statuses[]",
+ "| select((.completed != null) and (.id | startswith(\"exporting attestation manifest\"))).id",
+ "| sub(\"exporting attestation manifest \"; \"\")",
+ empty
+ ] | join("\n\t\t")
+ ),
+ "'",
+ empty
+ ] | join("\n\t")
+ ),
+ ")",
+ # Find the SBOM digest from the attestation manifest
+ "sbom_digest=$(",
+ (
+ [
+ "\tjq -r '",
+ (
+ [
+ "\t.layers[] | select(.annotations[\"in-toto.io/predicate-type\"] == \"https://spdx.dev/Document\").digest",
+ empty
+ ] | join("\n\t\t")
+ ),
+ "' \"sbom/blobs/${attest_manifest_digest//://}\"",
+ empty
+ ] | join("\n\t")
+ ),
+ ")",
+ # Replace the subjects digests
+ "jq -c --arg digest \"\(image_digest)\" '",
+ (
+ [
+ "\t.subject[].digest |= ($digest | split(\":\") | {(.[0]): .[1]})",
+ empty
+ ] | join("\n\t")
+ ),
+ "' \"sbom/blobs/${sbom_digest//://}\" > sbom.json",
+ empty
+ ] | join("\n")
+;
+
# input: "build" object (with "buildId" top level key)
# output: string "push command" ("docker push ..."), may be multiple lines, expects to run in Bash with "set -Eeuo pipefail"
def push_command:
@@ -398,6 +499,7 @@ def commands:
{
pull: pull_command,
build: build_command,
+ sbom_scan: sbom_command,
push: push_command,
}
;