Skip to content

Commit 167b6d4

Browse files
authored
feat(publish-image): Attest SPDX SBOM alongside CycloneDX (#114)
1 parent 1a0aa5b commit 167b6d4

2 files changed

Lines changed: 26 additions & 3 deletions

File tree

publish-image/README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ following work:
99
`image-repository`.
1010
2. Push the container image to the specified registry.
1111
3. Sign the container image (which pushes the signature to the specified registry).
12-
4. Generate an SBOM via a syft scan.
13-
5. Attest an image with the SBOM as a predicate (which pushes the attestation to the specified
14-
registry).
12+
4. Generate a CycloneDX SBOM via a syft scan and merge its components.
13+
5. Convert the merged CycloneDX SBOM to SPDX (normalising deprecated license ids).
14+
6. Attest the image with both the CycloneDX and SPDX SBOMs as predicates (which pushes the
15+
attestations to the specified registry).
1516

1617
## Inputs and Outputs
1718

publish-image/action.yaml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,3 +193,25 @@ runs:
193193
--predicate sbom.merged.json \
194194
--type cyclonedx \
195195
"${IMAGE_REPOSITORY_DIGEST}"
196+
197+
# Derive an SPDX SBOM from the merged CycloneDX SBOM. We only generate
198+
# CycloneDX, SPDX is produced by conversion so both formats describe the
199+
# same merged, deduplicated inventory.
200+
syft convert sbom.merged.json --output spdx-json=sbom.spdx.raw.json
201+
202+
# Normalise deprecated SPDX license identifiers that strict validators and
203+
# some consumers reject. syft still emits the deprecated standalone form
204+
# "GPL-2.0-with-classpath-exception"; rewrite it to the valid WITH
205+
# expression. Extend the `fix` chain if further deprecated ids show up.
206+
jq '
207+
def fix: gsub("GPL-2.0-with-classpath-exception"; "GPL-2.0-only WITH Classpath-exception-2.0");
208+
(.. | .licenseDeclared? // empty) |= (if type == "string" then fix else . end)
209+
| (.. | .licenseConcluded? // empty) |= (if type == "string" then fix else . end)
210+
' sbom.spdx.raw.json > sbom.spdx.json
211+
212+
# Attest the SPDX SBOM to the image
213+
"$GITHUB_ACTION_PATH/../.scripts/actions/retry.sh" cosign attest \
214+
--yes \
215+
--predicate sbom.spdx.json \
216+
--type spdxjson \
217+
"${IMAGE_REPOSITORY_DIGEST}"

0 commit comments

Comments
 (0)