Skip to content

feat(ci): add BST-native SBOM, keyless cosign signing, and SLSA attes…#187

Open
castrojo wants to merge 2 commits intoprojectbluefin:mainfrom
castrojo:upstream-pr/sbom-signing
Open

feat(ci): add BST-native SBOM, keyless cosign signing, and SLSA attes…#187
castrojo wants to merge 2 commits intoprojectbluefin:mainfrom
castrojo:upstream-pr/sbom-signing

Conversation

@castrojo
Copy link
Copy Markdown
Contributor

Ok so we can't use syft for sboms since it's expecting RPMs, found this: https://gitlab.com/BuildStream/buildstream-sbom

https://fosdem.org/2026/schedule/event/P9FNH3-buildstream-sbom/

Confirmed this worked locally:

❯ jq '.packages[] | select(.name == "ghostty" and .versionInfo == "1.3.1")' sbom.json
{
  "SPDXID": "SPDXRef-bluefin-ghostty.bst-0",
  "filesAnalyzed": false,
  "name": "ghostty",
  "downloadLocation": "https://release.files.ghostty.org/1.3.1/ghostty-1.3.1.tar.gz",
  "versionInfo": "1.3.1",
  "sourceInfo": "tar",
  "externalRefs": [
    {
      "referenceCategory": "OTHER",
      "referenceType": "bst-element",
      "referenceLocator": "bluefin/ghostty.bst"
    }
  ]
}
❯   jq -r '.packages[] | select(.versionInfo != null and .versionInfo != "unknown") | "\(.name)  \(.versionInfo)"' sbom.json \
    | grep -iE "gnome-shell|gtk4 |systemd |ghostty|tailscale|podman|bootc" | head -15
ghostty  1.3.1
ghostty-themes-release  14200bb86a0c814ab69609d500b280b396b6d2eb835edf0676de4a789c0aa8fd
gnome-shell-extension-appindicator  c934adc6c97363b8e6bb161ca8d1ac62d1da3d63
gnome-shell-extension-caffeine  be31208d8ab74cfae215354f242d8703ec3792a4
gnome-shell-extension-gsconnect  7fd41b0719c4eafe519e90f28e937dd935db4a63
tailscale  1.96.4
gtk4  0.11.0
podman  5.8.0
systemd  257.10
libsystemd  0.7.0
systemd  259.2
systemd  0.10.1
gtk4  0.8.2
gnome-shell  50.0
gnome-shell  c9372e733d75cf3c5197a0dd29f8a4a422e2dddb9020cab3c179a6f3df03d4be

Agent notes:

  • SBOM: uses buildstream-sbom (pinned to 0706fec3) to generate SPDX 2.3 JSON directly from BST element metadata. Captures the full ~8300 package dep tree including GNOME/GTK/systemd from junctions — unlike syft which can only fingerprint binaries in the rootfs and misses source-built packages. Mounts ~/.config/buildstream-generate as a persistent volume so the gnome-build-meta secureboot key generation (generated.py plugin) is cached across container runs; a prime step ensures cold-cache builds work in one pass.

  • Signing: keyless cosign via Sigstore OIDC (no private key, no SIGNING_SECRET). Signature bound to the GitHub Actions identity, recorded in Rekor.

  • SBOM attachment: ORAS attaches sbom.json as an OCI referrer (type application/vnd.spdx+json), then signs the referrer keylessly.

  • Provenance: SLSA build provenance via actions/attest v4.1.0.

  • Local targets: just sbom generates the SPDX 2.3 SBOM locally; just verify checks cosign signature, SBOM referrer, and SLSA attestation against a pushed image.

Action versions (cross-checked against ublue-os/bazzite):
sigstore/cosign-installer v4.1.1 (cosign v2.6.1)
oras-project/setup-oras v2.0.0
actions/attest v4.1.0

Note: artifact-metadata: write is org-only; personal forks will show startup_failure here (expected). Full pipeline runs on projectbluefin org.

…tations

Adds supply-chain security to the dakota CI pipeline:

- SBOM: uses buildstream-sbom (pinned to 0706fec3) to generate SPDX 2.3 JSON
  directly from BST element metadata. Captures the full ~8300 package dep tree
  including GNOME/GTK/systemd from junctions — unlike syft which can only
  fingerprint binaries in the rootfs and misses source-built packages.
  Mounts ~/.config/buildstream-generate as a persistent volume so the
  gnome-build-meta secureboot key generation (generated.py plugin) is cached
  across container runs; a prime step ensures cold-cache builds work in one pass.

- Signing: keyless cosign via Sigstore OIDC (no private key, no SIGNING_SECRET).
  Signature bound to the GitHub Actions identity, recorded in Rekor.

- SBOM attachment: ORAS attaches sbom.json as an OCI referrer
  (type application/vnd.spdx+json), then signs the referrer keylessly.

- Provenance: SLSA build provenance via actions/attest v4.1.0.

- Local targets: `just sbom` generates the SPDX 2.3 SBOM locally;
  `just verify` checks cosign signature, SBOM referrer, and SLSA attestation
  against a pushed image.

Action versions (cross-checked against ublue-os/bazzite):
  sigstore/cosign-installer v4.1.1 (cosign v2.6.1)
  oras-project/setup-oras v2.0.0
  actions/attest v4.1.0

Note: artifact-metadata: write is org-only; personal forks will show
startup_failure here (expected). Full pipeline runs on projectbluefin org.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces new Justfile recipes for generating a BuildStream-native SBOM and verifying supply-chain security using Cosign, ORAS, and SLSA. Feedback highlights opportunities to reduce duplication in container configurations, improve the efficiency of the SBOM tool installation by avoiding repeated Git clones, and resolve redundant logic and variable naming inconsistencies in the image verification script.

Comment thread Justfile
Comment on lines +604 to +612
podman run --rm \
--privileged \
--device /dev/fuse \
--network=host \
-v "{{justfile_directory()}}:/src:rw" \
-v "${HOME}/.cache/buildstream:/root/.cache/buildstream:rw" \
-v "${HOME}/.config/buildstream-generate:/root/.config/buildstream-generate:rw" \
-w /src \
"{{bst2_image}}" \
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The podman run configuration (flags and volume mounts) is duplicated multiple times within this recipe and also matches the bst recipe. This duplication makes the Justfile harder to maintain and prone to errors when updating volume mounts or container settings. Consider defining the common flags in a global just variable to ensure consistency across all recipes that invoke the BuildStream container.

Comment thread Justfile
Comment on lines +614 to +615
pip install --quiet \
git+https://gitlab.com/BuildStream/buildstream-sbom.git@0706fec3bedf6f73bd9d2fed32c2aed585feef8d
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Installing buildstream-sbom from Git on every execution of the sbom recipe is inefficient and makes the process dependent on external network availability. Since the container is run with --rm, the installation is not persisted. Consider using a container image that already includes the tool or caching the installation via a persistent volume mount for the Python environment.

Comment thread Justfile
Comment on lines +641 to +642
IMAGE="${1:-$IMAGE_REGISTRY/$IMAGE_NAME:latest}"
IMAGE="${image_ref:-${IMAGE_REGISTRY:-ghcr.io/projectbluefin}/{{image_name}}:{{image_tag}}}"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The assignment to IMAGE on line 641 is redundant as it is immediately overwritten by the logic on line 642. Additionally, line 641 references $IMAGE_NAME, but the variable exported at the top of the file is image_name (lowercase).

    IMAGE="${image_ref:-${IMAGE_REGISTRY:-ghcr.io/projectbluefin}/{{image_name}}:{{image_tag}}}"

@hanthor hanthor enabled auto-merge April 16, 2026 05:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants