diff --git a/.github/workflows/conan_create.yml b/.github/workflows/conan_create.yml index 9e4ec651c..cb3a8c722 100644 --- a/.github/workflows/conan_create.yml +++ b/.github/workflows/conan_create.yml @@ -67,6 +67,31 @@ jobs: CXX: ${{ matrix.compiler[1] }} run: | conan create . -c tools.cmake.cmaketoolchain:generator=Ninja -b missing -o celix/*:build_all=True -o celix/*:enable_ccache=True -pr:b default -pr:h default -s:h build_type=${{ matrix.type }} -o celix/*:celix_cxx17=True -o celix/*:celix_install_deprecated_api=True -o mosquitto/*:broker=True -o *:shared=True + - name: Generate CycloneDX SBOM from canonical Conan lockfile + if: matrix.compiler[0] == 'gcc' + run: | + rm -rf sbom + conan install . \ + --lockfile=conan/safe-defaults.lock \ + --deployer=cyclone_1.6 \ + --deployer-folder=sbom \ + -b missing \ + -pr:b default \ + -pr:h default \ + -s:h build_type=${{ matrix.type }} \ + -o celix/*:build_all=True \ + -o celix/*:celix_cxx17=True \ + -o mosquitto/*:broker=True \ + -o *:shared=True + - name: Upload canonical Conan lockfile and CycloneDX SBOM + if: matrix.compiler[0] == 'gcc' + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: celix-conan-safe-defaults + path: | + conan/safe-defaults.lock + sbom/sbom-cyclonedx-1.6.json + if-no-files-found: error - name: Dependency Deduction Test env: CC: ${{ matrix.compiler[0] }} diff --git a/conan/safe-defaults.lock b/conan/safe-defaults.lock new file mode 100644 index 000000000..92d5eb0af --- /dev/null +++ b/conan/safe-defaults.lock @@ -0,0 +1,56 @@ +{ + "version": "0.5", + "requires": [ + "zstd/1.5.7#b68ca8e3de04ba5957761751d1d661f4%1760955092.069", + "zlib/1.3.1#cac0f6daea041b0ccf42934163defb20%1765284699.337", + "xz_utils/5.8.3#a8432fead347c69d8b2737c35f936132%1775752656.4", + "util-linux-libuuid/2.41.2#3ba347c98172dadfe417700cf399adac%1781172622.732", + "rapidjson/1.1.0#9f5e39d1f4a6b67d48c6a343c4592f32%1705070241.006", + "openssl/3.6.3#a81313131c78c6414f25b5fe0a83204b%1783446193.901", + "mosquitto/2.0.22#2800cdcc6c3ad3fcfe274c905a73a853%1765786795.688", + "mdnsresponder/1310.140.1#5116b98dc767ebb2ea48a2a584a365b4%1686542086.05", + "libzip/1.11.4#cf55b90c94be0184eae424ce54e71247%1778489193.132", + "libxml2/2.15.3#3406c6d8d327e9b84c0c894feb859514%1777886326.291", + "libuv/1.51.0#ea781dcacf58c65462ab0d3d75e9b002%1764745176.352", + "libiconv/1.17#9923bc6dc6f106646d6967e0039a5ada%1774021608.288", + "libffi/3.4.8#a045c00fb26779635e3bed40e80c5254%1753360042.396", + "libcurl/8.21.0#dd94e078c967e162aae33d353142fa31%1786959569.239", + "jansson/2.14#7710071716bc129093fec1cc4d19f424%1760696859.73", + "civetweb/1.16#f4a42c8aa0bc0fe4bbe2a2270af0cea2%1750148475.207", + "bzip2/1.0.8#c470882369c2d95c5c77e970c0c7e321%1762886692.465" + ], + "build_requires": [ + "pkgconf/2.5.1#93c2051284cba1279494a43a4fcfeae2%1757684701.089", + "ninja/1.13.2#c8c5dc2a52ed6e4e42a66d75b4717ceb%1764096931.974", + "meson/1.10.2#9d2d10681fe7fe61c788c58626c89b25%1775558003.754", + "m4/1.4.19#1727f439cf74e83826ec96d0b4904eee%1784541921.659", + "libtool/2.4.7#14e7739cc128bc1623d2ed318008e47e%1755679003.847", + "gnu-config/cci.20210814#466e9d4d7779e1c142443f7ea44b4284%1762363589.329", + "cmake/3.26.4#0b40747e190e755932767f2ec4768ff5%1685461463.385", + "automake/1.16.5#b91b7c384c3deaa9d535be02da14d04f%1755524470.56", + "autoconf/2.71#51077f068e61700d65bb05541ea1e4b0%1731054366.86" + ], + "python_requires": [], + "overrides": { + "openssl/[>=3.2.0 <4]": [ + "openssl/3.6.3" + ], + "zlib/[>=1.2.11 <2]": [ + "zlib/1.3.1" + ], + "openssl/[>=1.1 <4]": [ + "openssl/3.6.3#a81313131c78c6414f25b5fe0a83204b", + "openssl/[>=3.2.0 <4]" + ], + "openssl/[>=3 <4]": [ + "openssl/3.6.3" + ], + "zlib/[>=1.3.1 <2]": [ + "zlib/1.3.1#cac0f6daea041b0ccf42934163defb20" + ], + "openssl/[>=1 <4]": [ + "openssl/3.6.3#a81313131c78c6414f25b5fe0a83204b" + ] + }, + "config_requires": [] +} diff --git a/documents/README.md b/documents/README.md index c633e7d11..b04ea7b8a 100644 --- a/documents/README.md +++ b/documents/README.md @@ -81,6 +81,7 @@ bundles contains binaries depending on the stdlibc++ library. * Building * [Building and Installing Apache Celix](building/README.md) + * [Software Bill of Materials](building/sbom.md) * C Patterns * [Apache Celix C Patterns](c_patterns.md) * Utils diff --git a/documents/building/sbom.md b/documents/building/sbom.md new file mode 100644 index 000000000..ebdafd2ad --- /dev/null +++ b/documents/building/sbom.md @@ -0,0 +1,110 @@ +--- +title: Software Bill of Materials +--- + + + +# Software Bill of Materials + +Apache Celix provides a committed `conan/safe-defaults.lock` and a matching +CycloneDX 1.6 SBOM for one documented Conan configuration. Together they +provide a reproducible **safe-default dependency baseline** for development and +vulnerability review. + +The lockfile is intentionally not named `conan.lock` at the repository root. +Conan automatically discovers a root `conan.lock` for ordinary commands, which +would make the baseline an implicit constraint on unrelated builds. Keeping the +safe-default lockfile at an explicit path means users opt in to it with +`--lockfile=conan/safe-defaults.lock`. + +The lockfile is not a repository-wide dependency mandate. Celix users remain +free to build without the lockfile, override dependency versions, or maintain a +lockfile for their own application configuration. When those inputs change, +the resulting dependency graph and SBOM can change as well. + +## Canonical safe-default configuration + +The committed lockfile represents the Linux / GCC / Release Conan graph with: + +* `celix/*:build_all=True` +* `celix/*:celix_cxx17=True` +* `mosquitto/*:broker=True` +* `*:shared=True` + +The CI-only `enable_ccache` option is intentionally not part of this baseline; +ccache accelerates compilation but should not define the dependency policy +presented to downstream Celix users. + +This baseline does not claim to describe every possible Celix build. Different +platforms, build types, option sets, or user-selected dependency overrides can +produce different graphs. + +## CI generation + +The Linux Conan CI job first performs its normal Celix package build without an +implicit lockfile. For the GCC Release configuration it then explicitly +validates the committed safe-default graph by running Conan's built-in +CycloneDX deployer with `conan/safe-defaults.lock`: + +```bash +conan install . \ + --lockfile=conan/safe-defaults.lock \ + --deployer=cyclone_1.6 \ + --deployer-folder=sbom \ + -b missing \ + -pr:b default \ + -pr:h default \ + -s:h build_type=Release \ + -o celix/*:build_all=True \ + -o celix/*:celix_cxx17=True \ + -o mosquitto/*:broker=True \ + -o *:shared=True +``` + +Using the lockfile means the SBOM is generated from the exact recipe revisions +selected by the committed baseline rather than whatever dependency revisions +happen to be newest when CI runs. If the lockfile no longer satisfies the Celix +recipe, the CI step fails instead of silently generating evidence for a +different graph. + +CI publishes `conan/safe-defaults.lock` and +`sbom/sbom-cyclonedx-1.6.json` together as the +`celix-conan-safe-defaults` workflow artifact. + +## Using the baseline locally + +After creating a Conan profile compatible with the configuration above, opt in +to the committed lockfile to reproduce the safe-default graph: + +```bash +conan install . \ + --lockfile=conan/safe-defaults.lock \ + -b missing \ + -pr:b default \ + -pr:h default \ + -s:h build_type=Release \ + -o celix/*:build_all=True \ + -o celix/*:celix_cxx17=True \ + -o mosquitto/*:broker=True \ + -o *:shared=True +``` + +Applications may intentionally choose newer or different dependencies instead. +In that case, generate and retain a lockfile and SBOM for that application +configuration rather than treating the Celix safe-default files as evidence for +a graph they do not describe.