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.json → sbom/sbom.cdx.json.sig
sbom/source-sha256.txt → sbom/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:
- Cut a pre-release tag on main (e.g.
v0.0.1-sbom-test) via a throwaway release.
- Confirm all four assets attach and
cosign verify-blob succeeds against each.
- 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.
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_dispatchstays as the rehearsal trigger and continues to emit a workflow artifact (not a Release asset) — two paths, one workflow.Deliverables
.github/workflows/sbom.ymlextensionsrelease: publishedas a second trigger alongsideworkflow_dispatch.permissions: id-token: writeat the job level (cosign keyless needs the OIDC token).sbom/source-sha256.txt— single line:<sha256> solid-syslog-<version>.tar.gz. Uses the samegit archive Core/ Platform/source tree as the SBOM so the hash in the file equals thesolidsyslog:source-hash-sha256property inside the SBOM.cosignviasigstore/cosign-installerpinned by SHA.cosign sign-blob --yes --output-signature <file>.sig:sbom/sbom.cdx.json→sbom/sbom.cdx.json.sigsbom/source-sha256.txt→sbom/source-sha256.txt.sigrelease: publishedonly, uploadsbom.cdx.json,sbom.cdx.json.sig,source-sha256.txt,source-sha256.txt.sigas Release assets (viagh release upload). Theworkflow_dispatchpath continues to produce the workflow artifact only.continue-on-error: trueon initial rollout per E19 guidance — a signing failure should not block a release, tighten after proven stable.cyclonedx validate … --fail-on-errors) stays non-advisory — the SBOM itself must be valid either way.docs/security/sbom.mdadditionsdocs/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.mdEntry covering: the keyless signing choice (no repo secrets to rotate), the
continue-on-errorrollout posture, the dual-trigger design (whyworkflow_dispatchstays), and the certificate-identity convention.Out of scope
cosign attestis a natural follow-on but expands scope; defer to another E19 story.docs/security/sbom.md.Acceptance
release: publishedevent — simulated by cutting a draft release from the Actions UI onmain— 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_dispatchruns continue to produce a workflow artifact containing the SBOM, unchanged in shape from S19.01 (so the rehearsal UX is preserved).cosign verify-blobwith the documented certificate-identity + OIDC-issuer flags succeeds against each signed file.docs/security/sbom.mdgets the verification section;docs/security/release-verification.mdexists.continue-on-error: truerollout guard is present on signing/upload steps and explicitly noted as a first-pass posture in the DEVLOG.Dependencies / prerequisites
v0.1.0.Rehearsal plan (not a deliverable, just how we'll exercise it)
Before flipping the
continue-on-erroroff, we'll:v0.0.1-sbom-test) via a throwaway release.cosign verify-blobsucceeds against each.After the first real release (
v0.1.0) shows the same behaviour, flipcontinue-on-error: falsein a follow-upchore:PR.