Software Bill of Materials (SBOM)¶
SolidSyslog publishes a CycloneDX 1.5 SBOM for the shipped library. SBOMs come in three flavours that answer three different questions; this document is only concerned with the first.
| Flavour | Question it answers | Status here |
|---|---|---|
| Product SBOM | "What am I linking against in my deployment?" | Covered by this workflow (see below). |
| Build / dev-env SBOM | "What tools, containers, and test harnesses were used to produce the release?" | Not yet — deferred to a separate story. Container image SHAs are tracked in docs/containers.md for now. |
| Source SBOM | "What third-party source code is embedded in the product?" | Empty — SolidSyslog vendors no third-party source. |
Product SBOM scope¶
In scope:
Core/: Tier 1 (full support, stable API).Platform/: Tier 2 (supported; API may evolve per target).- Root
CMakeLists.txt+CMakePresets.json: the build contract an integrator invokes directly. Tampering here affects the built library. - Root
LICENSE.md: the licence text we are legally bound by and that downstream integrators inherit. Tampering here is a compliance issue.
Out of scope:
Tests/,Bdd/: test harnesses (Bdd/Targets/holds the BDD-driven binaries, test infrastructure, not product).ci/,docs/,.devcontainer/,.github/,.vscode/: dev/CI infrastructure.sbom/: the SBOM template itself (meta; including it would be self-referential).scripts/: utility scripts not consumed by the integrator.- Other root-level meta files (
CLAUDE.md,SKILL.md,README.md,CHANGELOG.md,.clang-format,.clang-tidy,.gitattributes,.gitignore,.release-please-manifest.json). Informational / agent-facing / git configuration, not library source.
Runtime dependencies we declare but do not bundle:
- OpenSSL: optional, only when
SOLIDSYSLOG_OPENSSL=ON. Listed as a CycloneDX component withscope: optional. No version pinned; integrators select their own OpenSSL and capture it in their own SBOM alongside the specific licence terms of the version they ship.
Runtime dependencies we document as environment (not components):
- POSIX libc / Winsock / POSIX message queues: host OS APIs, not
shipped software. Recorded as
metadata.propertiesrather than components.
What the SBOM says¶
The SBOM is a single-component document. Core/ is a pure-C library with no
runtime dependencies, so the subject (metadata.component) is SolidSyslog
itself, and the top-level components array is empty. Runtime facts that a
deployer must supply (a POSIX or Windows host, optionally a TLS library
implementing the Stream abstraction) are documented as properties, not as
components: they are requirements on the deployment, not shipped software.
Key fields worth reading:
| Field | Meaning |
|---|---|
metadata.component.name |
SolidSyslog. |
metadata.component.version |
The value from .release-please-manifest.json at the time of generation. Pre-release: 0.0.0. |
metadata.component.purl |
Package URL keyed to the exact commit SHA — unambiguous pointer back to the source. |
metadata.component.supplier.name |
COSOSO (Cozens Software Solutions Limited). |
metadata.component.licenses[0].license.id |
PolyForm-Noncommercial-1.0.0 — SPDX identifier. |
metadata.properties[solidsyslog:source-tree-sha256] |
Content-tree hash: SHA-256 of a sorted list of <content-sha256> <path> lines for every tracked file in Core/ and Platform/ at the commit. Reproducible byte-for-byte from any clone, with no dependency on git archive output format or git version. |
How to generate one (rehearsal)¶
Each run produces a CycloneDX 1.5 JSON file, validated against the spec by
cyclonedx-cli, and uploaded as
a workflow artifact.
- Open the Actions tab.
- Select the Generate SBOM workflow.
- Click Run workflow, pick the ref (usually
mainor a release tag), and Run workflow. - When the run completes, scroll to Artifacts at the bottom of the run
page and download
sbom-cyclonedx-<version>. - Unzip; the file inside is
sbom.cdx.json.
The workflow uses only the default GITHUB_TOKEN: no repo secrets required.
Sanity-check a generated SBOM¶
cyclonedx validate --input-file sbom.cdx.json --input-format json --input-version v1_5 --fail-on-errors
The CI workflow already runs this; the command is useful if you've fetched the artifact locally and want to re-verify independently.
Verifying a signed SBOM¶
Every GitHub Release created by Release Please gets four assets attached:
| Asset | Contents |
|---|---|
sbom.cdx.json |
The SBOM itself. |
sbom.cdx.json.bundle |
sigstore/cosign signature bundle — signature + ephemeral signing certificate + Rekor inclusion proof, in a single JSON blob. |
source-tree-sha256.txt |
The content-tree SHA-256 with a human-readable header. Reproducible from any clone at the SBOM's commit with git ls-tree + git show + sha256sum + sort. |
source-tree-sha256.txt.bundle |
cosign bundle for the above. |
Signing is keyless via GitHub OIDC: no private keys live in this repo.
The signature commits to the specific workflow run (sbom.yml in this repo
at the tagged commit) that produced the SBOM; a verifier checks the
certificate identity against an expected workflow identity to tell "this
SBOM" apart from any other CycloneDX document.
To verify a downloaded asset set:
cosign verify-blob \
--bundle sbom.cdx.json.bundle \
--certificate-identity "https://github.com/cososo-ltd/solid-syslog/.github/workflows/sbom.yml@refs/tags/v<version>" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
sbom.cdx.json
The same pattern verifies source-tree-sha256.txt.bundle against source-tree-sha256.txt.
Every cosign signature is also logged to Rekor, Sigstore's public transparency log. Anyone can look up the signature entry by its hash and confirm it was issued at the stated time, independent of whether GitHub, Sigstore, or this project still exist at the time of audit.
For a step-by-step verification guide aimed at downstream integrators, see
release-verification.md.
Deferred¶
- Signed SLSA provenance attestation.
cosign atteston top ofsign-blobis a natural next step: it produces an attestation statement that says "this SBOM was produced by this workflow from these inputs" rather than just "this SBOM was signed by this workflow." - Binary-artefact signing. The project is source-only; nothing to sign beyond the SBOM and content-tree hash.
- Flip the signing/attach steps off
continue-on-error: true. The initial rollout keeps those steps advisory so a signing infrastructure outage doesn't block a release. Tighten to hard-fail after the first real release has demonstrated the pipeline works.