Skip to content

S19.02: SBOM signing and release-asset attachment #196

Description

@DavidCozens

Parent epic: #155
Builds on: #194 (S19.01 — template + on-demand generation)

Goal

Extend the SBOM workflow from S19.01 so every GitHub Release created by Release Please automatically gets an SBOM + signature + source-tarball hash + signature attached as Release assets. Signing uses sigstore/cosign keyless mode via the repository's GitHub OIDC identity — no long-lived keys, no secrets in the repo.

workflow_dispatch stays as the rehearsal trigger and continues to emit a workflow artifact (not a Release asset) — two paths, one workflow.

Deliverables

.github/workflows/sbom.yml extensions

  • Add release: published as a second trigger alongside workflow_dispatch.
  • Add permissions: id-token: write at the job level (cosign keyless needs the OIDC token).
  • Generate a source-tarball hash artifact at sbom/source-sha256.txt — single line: <sha256> solid-syslog-<version>.tar.gz. Uses the same git archive Core/ Platform/ source tree as the SBOM so the hash in the file equals the solidsyslog:source-hash-sha256 property inside the SBOM.
  • Install cosign via sigstore/cosign-installer pinned by SHA.
  • Sign both files with cosign sign-blob --yes --output-signature <file>.sig:
    • sbom/sbom.cdx.jsonsbom/sbom.cdx.json.sig
    • sbom/source-sha256.txtsbom/source-sha256.txt.sig
  • On release: published only, upload sbom.cdx.json, sbom.cdx.json.sig, source-sha256.txt, source-sha256.txt.sig as Release assets (via gh release upload). The workflow_dispatch path continues to produce the workflow artifact only.
  • Signing steps marked continue-on-error: true on initial rollout per E19 guidance — a signing failure should not block a release, tighten after proven stable.
  • Existing validation step (cyclonedx validate … --fail-on-errors) stays non-advisory — the SBOM itself must be valid either way.

docs/security/sbom.md additions

  • New section "Verifying a signed SBOM" with a minimal local recipe:
    cosign verify-blob \
      --signature sbom.cdx.json.sig \
      --certificate-identity "https://github.com/DavidCozens/solid-syslog/.github/workflows/sbom.yml@refs/tags/v<version>" \
      --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
      sbom.cdx.json
  • Note on how the certificate identity pins the signer to "this specific workflow in this specific repo at this specific tag" — the mechanism a client uses to tell apart "the right SolidSyslog SBOM" from "someone else's SBOM also claiming to be SolidSyslog".
  • Pointer to Sigstore's Rekor transparency log for third-party audit.

docs/security/release-verification.md (new)

Short standalone doc aimed at a downstream integrator: "you have a SolidSyslog release on disk, here's how to verify it". Covers both the source-tarball hash and the SBOM signature, in the order a cautious integrator would actually run them.

DEVLOG.md

Entry covering: the keyless signing choice (no repo secrets to rotate), the continue-on-error rollout posture, the dual-trigger design (why workflow_dispatch stays), and the certificate-identity convention.

Out of scope

  • Signing the container images we use in CI — separate concern, lives with the container image repo.
  • SLSA provenance attestation. cosign attest is a natural follow-on but expands scope; defer to another E19 story.
  • Backfilling signatures for old releases. The repo has no prior releases (manifest is 0.0.0); nothing to backfill. If that changes, separate chore.
  • Publishing verification status on a badge / CI dashboard. Nice-to-have, not required.
  • Binary artefact signing. The project does not ship binaries — source-only, per docs/security/sbom.md.

Acceptance

  • A release: published event — simulated by cutting a draft release from the Actions UI on main — triggers the workflow and results in four assets attached to the Release: sbom.cdx.json, sbom.cdx.json.sig, source-sha256.txt, source-sha256.txt.sig.
  • workflow_dispatch runs continue to produce a workflow artifact containing the SBOM, unchanged in shape from S19.01 (so the rehearsal UX is preserved).
  • cosign verify-blob with the documented certificate-identity + OIDC-issuer flags succeeds against each signed file.
  • docs/security/sbom.md gets the verification section; docs/security/release-verification.md exists.
  • The continue-on-error: true rollout guard is present on signing/upload steps and explicitly noted as a first-pass posture in the DEVLOG.
  • DEVLOG entry recorded.

Dependencies / prerequisites

Rehearsal plan (not a deliverable, just how we'll exercise it)

Before flipping the continue-on-error off, we'll:

  1. Cut a pre-release tag on main (e.g. v0.0.1-sbom-test) via a throwaway release.
  2. Confirm all four assets attach and cosign verify-blob succeeds against each.
  3. Delete the throwaway release; keep the workflow posture advisory.

After the first real release (v0.1.0) shows the same behaviour, flip continue-on-error: false in a follow-up chore: PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    storyStory issue

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions