Software Bill of Materials
Every Ceedling release publishes a Software Bill of Materials. The documents list what a Ceedling gem contains and what it depends on. They exist so you can assess your own exposure without reading Ceedling’s packaging by hand.
Two documents accompany each release. One is CycloneDX and one is SPDX. Both are generated from a single description of the gem, so neither can state a fact the other contradicts.
What these documents cover
The documents describe the Ceedling gem as distributed. They do not describe the C code Ceedling builds for you. Your own source, your generated test runners and mocks, and your compiler toolchain are all outside their scope.
Scope
The documents describe one artifact, the published Ceedling gem. All else is out of scope:
Your build output is not described. Ceedling generates C for your project. Test runners, mocks, and Partials are all produced from your source at build time. None of that is part of Ceedling’s own distribution, so none of it appears in the SBOM.
Plugin tool requirements are not described. An enabled plugin may need external tools that Ceedling never ships. For example, the Gcov, Valgrind, Bullseye, and Cppcheck plugins all work this way. Which tools an installation actually needs depends on which plugins it enables, so a project-level document cannot state it. Each plugin documents its own requirements under Plugins.
Where to find them
The documents are attached to each release on GitHub. Look for two assets beside
the .gem file.
A gem’s own metadata also carries a pointer. The sbom_uri key names the CycloneDX
document for that exact version.
The documents are release assets and are never committed to the repository.
A version-specific link is the reliable one
releases/latest/download/ resolves only to the most recent full release, and
never to a pre-release. Because each filename carries a version, such a link
stops working as soon as a newer release exists. Link to a version’s individual
release page instead.
What the documents include
Three kinds of component appear. Each is identified by a Package URL (PURL).
Ruby dependencies
The gem’s declared runtime dependencies appear with the version the release build resolved. The declared constraint is recorded alongside as a component property. Ceedling bounds its dependencies rather than pinning them, and recording only a resolved version would imply otherwise.
Licenses for these come from a curated list rather than from the Gem lockfile. A lockfile records no license at all, and a gem’s own metadata is not reliable. Depenencies can have messy licensing and records. The curated list of licenses that feeds SBOM generation solves this problem. Tooling helps ensure the curated list is reviewed upon changed to dependencies.
Vendored C components
Unity, CMock, and CException ship inside the gem. Each is identified by the commit it is pinned at, not by a version string. A header version appears as well, for readers.
A commit is the identifier because a version string cannot always tell two copies apart. CMock vendors its own Unity, so a Ceedling gem carries two Unity source trees that may report the same version as different commits.
CException also ships twice, and both copies sit at the same commit. They therefore share a Package URL. Each occurrence still appears separately, with its own reference and its own path. A Package URL names a package. It does not name a location.
The fff plugin
The fff plugin is a modified descendant of an earlier project, and the documents say
so. Its lineage appears as CycloneDX pedigree and as an SPDX VARIANT_OF
relationship.
The plugin layer carries no Package URL of its own. Having been modified, it is no longer the package it descends from. Pointing an identifier at that package would invite a scanner to match advisories against code that differs.
The FFF framework itself is a separate component vendored inside the Ceedling plugin built around it. It began as a snapshot of upstream FFF v1.1.
That origin is recorded here rather than in the SBOM. Nothing in the vendored source
records a version. There is no version macro and no version file. And the vendored
fff.h is not byte-identical to any upstream release, being a generated file that
was regenerated rather than copied. Naming a release in the document would therefore
assert more than the source supports, so the component is identified without a
version.
What the documents exclude
Development and test dependencies are excluded. RSpec, RuboCop, SimpleCov and the rest never reach a published gem, so describing them would misstate what a user installs. The documents name the exclusion rather than leaving it to be inferred.
Upstream fff’s own test apparatus is excluded, because the gem no longer carries it. That tree included Google Test, which is BSD-3-Clause. Leaving it out keeps every file in the gem MIT.
Verifying an attestation
Each document is signed against the gem it describes. Verification establishes that Ceedling’s own release workflow produced that document for that artifact.
> gh attestation verify ceedling-<version>.gem \
--repo ThrowTheSwitch/Ceedling \
--predicate-type https://cyclonedx.org/bom
Name the predicate type
gh attestation verify looks for SLSA provenance unless told otherwise, and
reports a 404 when it finds none. Pass --predicate-type to verify an SBOM.
Use https://cyclonedx.org/bom for CycloneDX and
https://spdx.dev/Document/v2.3 for SPDX.
GitHub’s own export
GitHub generates an SPDX document from its dependency graph, reachable under Insights. It is a reasonable fallback, but it is not equivalent to these documents.
That export sees Ceedling’s Ruby manifests and nothing else. Unity, CMock, CException, DIY, and fff are all absent from it, because none of them arrives as a Ruby dependency. Those are the components most likely to matter to a C project.