From 58d7feca41a04338bfa40d96f6dde3f8aa81eae0 Mon Sep 17 00:00:00 2001 From: Robert McConnell Date: Thu, 27 Aug 2026 08:36:59 -0400 Subject: [PATCH 01/13] Generate CycloneDX SBOM with Conan deployer --- .github/workflows/conan_create.yml | 11 ++++++++++ documents/building/sbom.md | 32 ++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 documents/building/sbom.md diff --git a/.github/workflows/conan_create.yml b/.github/workflows/conan_create.yml index 9e4ec651c..b9b1e8245 100644 --- a/.github/workflows/conan_create.yml +++ b/.github/workflows/conan_create.yml @@ -67,6 +67,17 @@ 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 + if: matrix.compiler[0] == 'gcc' + run: | + conan install . -o celix/*:build_all=True --deployer=cyclone_1.6 --deployer-folder=sbom -b missing -o *:shared=True + - name: Upload CycloneDX SBOM + if: matrix.compiler[0] == 'gcc' + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: celix-conan-sbom + path: sbom/sbom-cyclonedx-1.6.json + if-no-files-found: error - name: Dependency Deduction Test env: CC: ${{ matrix.compiler[0] }} diff --git a/documents/building/sbom.md b/documents/building/sbom.md new file mode 100644 index 000000000..e59c8c0f5 --- /dev/null +++ b/documents/building/sbom.md @@ -0,0 +1,32 @@ +--- +title: Software Bill of Materials +--- + + + +# Software Bill of Materials + +The Linux Conan CI build generates a CycloneDX 1.6 Software Bill of Materials +using Conan's built-in `cyclone_1.6` deployer: + +```bash +conan install . -o celix/*:build_all=True --deployer=cyclone_1.6 --deployer-folder=sbom -b missing -o *:shared=True +``` + +The generated `sbom/sbom-cyclonedx-1.6.json` file is published by CI as the +`celix-conan-sbom` artifact. From ce848f475fedfd1b5d1a976b34ab08fd6b0c9eba Mon Sep 17 00:00:00 2001 From: Robert McConnell Date: Thu, 27 Aug 2026 22:48:43 -0400 Subject: [PATCH 02/13] Bind SBOM to deployed Conan package --- .github/workflows/conan_create.yml | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/.github/workflows/conan_create.yml b/.github/workflows/conan_create.yml index b9b1e8245..e97b559ec 100644 --- a/.github/workflows/conan_create.yml +++ b/.github/workflows/conan_create.yml @@ -67,16 +67,30 @@ 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 + - name: Deploy Celix package and generate CycloneDX SBOM if: matrix.compiler[0] == 'gcc' run: | - conan install . -o celix/*:build_all=True --deployer=cyclone_1.6 --deployer-folder=sbom -b missing -o *:shared=True - - name: Upload CycloneDX SBOM + rm -rf release-artifact + conan install --requires=celix/3.0.0 \ + --deployer=full_deploy \ + --deployer=cyclone_1.6 \ + --deployer-folder=release-artifact \ + -b never \ + -pr:b default \ + -pr:h default \ + -s:h build_type=${{ matrix.type }} \ + -o celix/*:build_all=True \ + -o celix/*:enable_ccache=True \ + -o celix/*:celix_cxx17=True \ + -o celix/*:celix_install_deprecated_api=True \ + -o mosquitto/*:broker=True \ + -o *:shared=True + - name: Upload Celix package and CycloneDX SBOM if: matrix.compiler[0] == 'gcc' uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: - name: celix-conan-sbom - path: sbom/sbom-cyclonedx-1.6.json + name: celix-conan-package-and-sbom + path: release-artifact/ if-no-files-found: error - name: Dependency Deduction Test env: @@ -124,7 +138,7 @@ jobs: path: ${{ env.CCACHE_DIR }} key: ${{ runner.os }}-ccache-Release-${{ steps.ccache_cache_timestamp.outputs.timestamp }} restore-keys: | - ${{ runner.os }}-ccache-Release- + ${{ runner.os }}-ccache-Release-${{ matrix.type }}- - name: Create Celix 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:b build_type=Release -s:h build_type=Release -o celix/*:celix_cxx17=True -o celix/*:celix_install_deprecated_api=True -o celix/*:enable_address_sanitizer=True -o mosquitto/*:broker=True -o *:shared=True From a25708b585820e94b02373b2570e656d63033519 Mon Sep 17 00:00:00 2001 From: Robert McConnell Date: Thu, 27 Aug 2026 22:49:08 -0400 Subject: [PATCH 03/13] Preserve existing macOS cache restore key --- .github/workflows/conan_create.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/conan_create.yml b/.github/workflows/conan_create.yml index e97b559ec..7c0a02de0 100644 --- a/.github/workflows/conan_create.yml +++ b/.github/workflows/conan_create.yml @@ -138,7 +138,7 @@ jobs: path: ${{ env.CCACHE_DIR }} key: ${{ runner.os }}-ccache-Release-${{ steps.ccache_cache_timestamp.outputs.timestamp }} restore-keys: | - ${{ runner.os }}-ccache-Release-${{ matrix.type }}- + ${{ runner.os }}-ccache-Release- - name: Create Celix 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:b build_type=Release -s:h build_type=Release -o celix/*:celix_cxx17=True -o celix/*:celix_install_deprecated_api=True -o celix/*:enable_address_sanitizer=True -o mosquitto/*:broker=True -o *:shared=True From e0107b1ad30ef884ee4ebc651f046b065b2c631b Mon Sep 17 00:00:00 2001 From: Robert McConnell Date: Thu, 27 Aug 2026 22:49:18 -0400 Subject: [PATCH 04/13] Document package-bound SBOM artifact --- documents/building/sbom.md | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/documents/building/sbom.md b/documents/building/sbom.md index e59c8c0f5..2b4909cc9 100644 --- a/documents/building/sbom.md +++ b/documents/building/sbom.md @@ -21,12 +21,35 @@ limitations under the License. # Software Bill of Materials -The Linux Conan CI build generates a CycloneDX 1.6 Software Bill of Materials -using Conan's built-in `cyclone_1.6` deployer: +The Linux Conan CI build first creates the `celix/3.0.0` Conan binary package. +For the GCC Release configuration, CI then consumes that package with the same +settings and options and runs Conan's `full_deploy` and `cyclone_1.6` deployers +in the same dependency-graph resolution: ```bash -conan install . -o celix/*:build_all=True --deployer=cyclone_1.6 --deployer-folder=sbom -b missing -o *:shared=True +conan install --requires=celix/3.0.0 \ + --deployer=full_deploy \ + --deployer=cyclone_1.6 \ + --deployer-folder=release-artifact \ + -b never \ + -pr:b default \ + -pr:h default \ + -s:h build_type=Release \ + -o celix/*:build_all=True \ + -o celix/*:enable_ccache=True \ + -o celix/*:celix_cxx17=True \ + -o celix/*:celix_install_deprecated_api=True \ + -o mosquitto/*:broker=True \ + -o *:shared=True ``` -The generated `sbom/sbom-cyclonedx-1.6.json` file is published by CI as the -`celix-conan-sbom` artifact. +`full_deploy` copies the resolved binary packages into `release-artifact`, while +`cyclone_1.6` writes `release-artifact/sbom-cyclonedx-1.6.json` from that same +resolved graph. The `-b never` option ensures this publication step uses the +binary packages already created or resolved by the build instead of silently +building a different package configuration. + +CI publishes the complete `release-artifact/` directory as the +`celix-conan-package-and-sbom` artifact, keeping the deployed Celix package, +its resolved binary dependencies, and the matching CycloneDX 1.6 SBOM +together. From 39a48006022ecb44d4e057a1835f747251ced982 Mon Sep 17 00:00:00 2001 From: Robert McConnell Date: Thu, 3 Sep 2026 22:02:59 -0400 Subject: [PATCH 05/13] Add canonical Conan dependency lockfile --- conan.lock | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 conan.lock diff --git a/conan.lock b/conan.lock new file mode 100644 index 000000000..92d5eb0af --- /dev/null +++ b/conan.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": [] +} From a43af756b865b150166f471a25642b38b7d9f6c7 Mon Sep 17 00:00:00 2001 From: Robert McConnell Date: Thu, 3 Sep 2026 22:03:27 -0400 Subject: [PATCH 06/13] Use committed lockfile for canonical SBOM --- .github/workflows/conan_create.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/conan_create.yml b/.github/workflows/conan_create.yml index 7c0a02de0..647d9b12d 100644 --- a/.github/workflows/conan_create.yml +++ b/.github/workflows/conan_create.yml @@ -67,30 +67,30 @@ 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: Deploy Celix package and generate CycloneDX SBOM + - name: Generate CycloneDX SBOM from canonical Conan lockfile if: matrix.compiler[0] == 'gcc' run: | - rm -rf release-artifact - conan install --requires=celix/3.0.0 \ - --deployer=full_deploy \ + rm -rf sbom + conan install . \ + --lockfile=conan.lock \ --deployer=cyclone_1.6 \ - --deployer-folder=release-artifact \ - -b never \ + --deployer-folder=sbom \ + -b missing \ -pr:b default \ -pr:h default \ -s:h build_type=${{ matrix.type }} \ -o celix/*:build_all=True \ - -o celix/*:enable_ccache=True \ -o celix/*:celix_cxx17=True \ - -o celix/*:celix_install_deprecated_api=True \ -o mosquitto/*:broker=True \ -o *:shared=True - - name: Upload Celix package and CycloneDX SBOM + - 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-package-and-sbom - path: release-artifact/ + name: celix-conan-safe-defaults + path: | + conan.lock + sbom/sbom-cyclonedx-1.6.json if-no-files-found: error - name: Dependency Deduction Test env: From 6a8ab3e689d87f1467082d69f47080f8db48f474 Mon Sep 17 00:00:00 2001 From: Robert McConnell Date: Thu, 3 Sep 2026 22:03:54 -0400 Subject: [PATCH 07/13] Document Conan lockfile as safe defaults --- documents/building/sbom.md | 85 +++++++++++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 19 deletions(-) diff --git a/documents/building/sbom.md b/documents/building/sbom.md index 2b4909cc9..6b394e3c7 100644 --- a/documents/building/sbom.md +++ b/documents/building/sbom.md @@ -21,35 +21,82 @@ limitations under the License. # Software Bill of Materials -The Linux Conan CI build first creates the `celix/3.0.0` Conan binary package. -For the GCC Release configuration, CI then consumes that package with the same -settings and options and runs Conan's `full_deploy` and `cyclone_1.6` deployers -in the same dependency-graph resolution: +Apache Celix provides a committed `conan.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 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. For the +GCC Release configuration it then validates the committed safe-default graph by +running Conan's built-in CycloneDX deployer with `conan.lock`: ```bash -conan install --requires=celix/3.0.0 \ - --deployer=full_deploy \ +conan install . \ + --lockfile=conan.lock \ --deployer=cyclone_1.6 \ - --deployer-folder=release-artifact \ - -b never \ + --deployer-folder=sbom \ + -b missing \ -pr:b default \ -pr:h default \ -s:h build_type=Release \ -o celix/*:build_all=True \ - -o celix/*:enable_ccache=True \ -o celix/*:celix_cxx17=True \ - -o celix/*:celix_install_deprecated_api=True \ -o mosquitto/*:broker=True \ -o *:shared=True ``` -`full_deploy` copies the resolved binary packages into `release-artifact`, while -`cyclone_1.6` writes `release-artifact/sbom-cyclonedx-1.6.json` from that same -resolved graph. The `-b never` option ensures this publication step uses the -binary packages already created or resolved by the build instead of silently -building a different package configuration. +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.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, use the +committed lockfile to reproduce the safe-default graph: + +```bash +conan install . \ + --lockfile=conan.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 +``` -CI publishes the complete `release-artifact/` directory as the -`celix-conan-package-and-sbom` artifact, keeping the deployed Celix package, -its resolved binary dependencies, and the matching CycloneDX 1.6 SBOM -together. +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. From 2f1a53b5e785ba1a4611499e0cb9c65f319b4643 Mon Sep 17 00:00:00 2001 From: Robert McConnell Date: Thu, 3 Sep 2026 22:06:15 -0400 Subject: [PATCH 08/13] Move safe-default lockfile out of Conan auto-discovery --- conan/safe-defaults.lock | 56 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 conan/safe-defaults.lock 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": [] +} From d6da3cb8376f4333acb149ec0735a62f3d20afed Mon Sep 17 00:00:00 2001 From: Robert McConnell Date: Thu, 3 Sep 2026 22:06:20 -0400 Subject: [PATCH 09/13] Avoid implicit Conan lockfile activation --- conan.lock | 56 ------------------------------------------------------ 1 file changed, 56 deletions(-) delete mode 100644 conan.lock diff --git a/conan.lock b/conan.lock deleted file mode 100644 index 92d5eb0af..000000000 --- a/conan.lock +++ /dev/null @@ -1,56 +0,0 @@ -{ - "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": [] -} From 63b6038ce3dc5a6daa7329a8d5e2b29b300ca26a Mon Sep 17 00:00:00 2001 From: Robert McConnell Date: Thu, 3 Sep 2026 22:06:51 -0400 Subject: [PATCH 10/13] Make safe-default lockfile explicit opt-in --- .github/workflows/conan_create.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/conan_create.yml b/.github/workflows/conan_create.yml index 647d9b12d..cb3a8c722 100644 --- a/.github/workflows/conan_create.yml +++ b/.github/workflows/conan_create.yml @@ -72,7 +72,7 @@ jobs: run: | rm -rf sbom conan install . \ - --lockfile=conan.lock \ + --lockfile=conan/safe-defaults.lock \ --deployer=cyclone_1.6 \ --deployer-folder=sbom \ -b missing \ @@ -89,7 +89,7 @@ jobs: with: name: celix-conan-safe-defaults path: | - conan.lock + conan/safe-defaults.lock sbom/sbom-cyclonedx-1.6.json if-no-files-found: error - name: Dependency Deduction Test From 0337d90551745a51219b93209d37aae4ead88552 Mon Sep 17 00:00:00 2001 From: Robert McConnell Date: Thu, 3 Sep 2026 22:07:06 -0400 Subject: [PATCH 11/13] Document explicit opt-in safe-default lockfile --- documents/building/sbom.md | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/documents/building/sbom.md b/documents/building/sbom.md index 6b394e3c7..ebdafd2ad 100644 --- a/documents/building/sbom.md +++ b/documents/building/sbom.md @@ -21,11 +21,17 @@ limitations under the License. # Software Bill of Materials -Apache Celix provides a committed `conan.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 +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, @@ -50,13 +56,14 @@ produce different graphs. ## CI generation -The Linux Conan CI job first performs its normal Celix package build. For the -GCC Release configuration it then validates the committed safe-default graph by -running Conan's built-in CycloneDX deployer with `conan.lock`: +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.lock \ + --lockfile=conan/safe-defaults.lock \ --deployer=cyclone_1.6 \ --deployer-folder=sbom \ -b missing \ @@ -75,17 +82,18 @@ 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.lock` and `sbom/sbom-cyclonedx-1.6.json` together as the +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, use the -committed lockfile to reproduce the safe-default graph: +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.lock \ + --lockfile=conan/safe-defaults.lock \ -b missing \ -pr:b default \ -pr:h default \ From 8377012573ebd2317109f4ac003d9009a086ad73 Mon Sep 17 00:00:00 2001 From: Robert McConnell Date: Thu, 3 Sep 2026 22:08:10 -0400 Subject: [PATCH 12/13] Link SBOM guidance from Celix docs --- documents/README.md | 1 + 1 file changed, 1 insertion(+) 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 From ca060752beef436e74ac9008de0126eff7c04241 Mon Sep 17 00:00:00 2001 From: Robert McConnell Date: Mon, 14 Sep 2026 14:27:18 +0000 Subject: [PATCH 13/13] Use safe-default lockfile across Conan CI Apply the committed dependency baseline to every dependency-resolving Conan CI build. Expand the lockfile to cover CI-only test/build requirements and macOS-specific dependencies, while keeping the published SBOM scoped to the documented Linux/GCC/Release graph. Signed-off-by: Robert McConnell --- .github/workflows/conan_create.yml | 8 ++++---- .github/workflows/containers.yml | 2 +- .github/workflows/coverage.yml | 2 +- .github/workflows/fuzzing.yml | 2 +- .github/workflows/macos.yml | 2 +- .github/workflows/ubuntu.yml | 2 +- conan/safe-defaults.lock | 12 ++++++++++-- documents/building/sbom.md | 25 ++++++++++++++++--------- 8 files changed, 35 insertions(+), 20 deletions(-) diff --git a/.github/workflows/conan_create.yml b/.github/workflows/conan_create.yml index cb3a8c722..663cea344 100644 --- a/.github/workflows/conan_create.yml +++ b/.github/workflows/conan_create.yml @@ -66,7 +66,7 @@ jobs: CC: ${{ matrix.compiler[0] }} 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 + conan create . --lockfile=conan/safe-defaults.lock -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: | @@ -97,7 +97,7 @@ jobs: CC: ${{ matrix.compiler[0] }} CXX: ${{ matrix.compiler[1] }} run: | - conan inspect . | awk 'BEGIN { FS="[\t:]+"; output=0 } /build/ && !/build_all/ { if(output) print $1} /^options/ {output=1} /^options_definitions/ {output=0}' | while read option; do conan build . -c tools.cmake.cmaketoolchain:generator=Ninja -b missing -o celix/*:${option}=True -pr:b default -pr:h default -s:h build_type=${{ matrix.type }} -of ${option}_dir -o celix/*:celix_cxx17=True -o celix/*:enable_ccache=True -o celix/*:celix_install_deprecated_api=True -o mosquitto/*:broker=True -o *:shared=True || exit 1; done + conan inspect . | awk 'BEGIN { FS="[\t:]+"; output=0 } /build/ && !/build_all/ { if(output) print $1} /^options/ {output=1} /^options_definitions/ {output=0}' | while read option; do conan build . --lockfile=conan/safe-defaults.lock -c tools.cmake.cmaketoolchain:generator=Ninja -b missing -o celix/*:${option}=True -pr:b default -pr:h default -s:h build_type=${{ matrix.type }} -of ${option}_dir -o celix/*:celix_cxx17=True -o celix/*:enable_ccache=True -o celix/*:celix_install_deprecated_api=True -o mosquitto/*:broker=True -o *:shared=True || exit 1; done - name: Remove Celix run: | conan remove -c celix/* @@ -141,10 +141,10 @@ jobs: ${{ runner.os }}-ccache-Release- - name: Create Celix 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:b build_type=Release -s:h build_type=Release -o celix/*:celix_cxx17=True -o celix/*:celix_install_deprecated_api=True -o celix/*:enable_address_sanitizer=True -o mosquitto/*:broker=True -o *:shared=True + conan create . --lockfile=conan/safe-defaults.lock -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:b build_type=Release -s:h build_type=Release -o celix/*:celix_cxx17=True -o celix/*:celix_install_deprecated_api=True -o celix/*:enable_address_sanitizer=True -o mosquitto/*:broker=True -o *:shared=True - name: Dependency Deduction Test run: | - conan inspect . | awk 'BEGIN { FS="[\t:]+"; output=0 } /build/ && !/build_all/ && !/build_rsa_remote_service_admin_shm_v2/ && !/build_rsa_discovery_zeroconf/ { if(output) print $1} /^options/ {output=1} /^options_definitions/ {output=0}' | while read option; do conan build . -c tools.cmake.cmaketoolchain:generator=Ninja -b missing -o celix/*:${option}=True -pr:b default -pr:h default -s:b build_type=Release -s:h build_type=Release -of ${option}_dir -o celix/*:celix_cxx17=True -o celix/*:enable_ccache=True -o celix/*:celix_install_deprecated_api=True -o mosquitto/*:broker=True -o *:shared=True || exit 1; done + conan inspect . | awk 'BEGIN { FS="[\t:]+"; output=0 } /build/ && !/build_all/ && !/build_rsa_remote_service_admin_shm_v2/ && !/build_rsa_discovery_zeroconf/ { if(output) print $1} /^options/ {output=1} /^options_definitions/ {output=0}' | while read option; do conan build . --lockfile=conan/safe-defaults.lock -c tools.cmake.cmaketoolchain:generator=Ninja -b missing -o celix/*:${option}=True -pr:b default -pr:h default -s:b build_type=Release -s:h build_type=Release -of ${option}_dir -o celix/*:celix_cxx17=True -o celix/*:enable_ccache=True -o celix/*:celix_install_deprecated_api=True -o mosquitto/*:broker=True -o *:shared=True || exit 1; done - name: Remove Celix run: | conan remove -c celix/* diff --git a/.github/workflows/containers.yml b/.github/workflows/containers.yml index a4c4adae8..2860a119e 100644 --- a/.github/workflows/containers.yml +++ b/.github/workflows/containers.yml @@ -39,7 +39,7 @@ jobs: -v ~/.ccache-container:/bome/celixdev/.ccache \ -v $(pwd):/home/celixdev/workspace apache/celix-conan-build:latest /bin/bash -c \ "cd /home/celixdev/workspace && \ - conan build . -pr:b release -pr:h debug --build=missing \ + conan build . --lockfile=conan/safe-defaults.lock -pr:b release -pr:h debug --build=missing \ --options celix/*:build_all=True --options celix/*:enable_address_sanitizer=True \ --options celix/*:enable_testing=True --options celix/*:enable_ccache=True \ -o mosquitto/*:broker=True -o *:shared=True \ diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 831df12ca..5257e4eec 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -65,7 +65,7 @@ jobs: -o mosquitto/*:broker=True -o *:shared=True run: | - conan build . -pr:b release -pr:h default ${CONAN_BUILD_OPTIONS} -b missing + conan build . --lockfile=conan/safe-defaults.lock -pr:b release -pr:h default ${CONAN_BUILD_OPTIONS} -b missing - name: Test with coverage run: | cd build/Debug diff --git a/.github/workflows/fuzzing.yml b/.github/workflows/fuzzing.yml index 3cce6f245..b5c9876d1 100644 --- a/.github/workflows/fuzzing.yml +++ b/.github/workflows/fuzzing.yml @@ -42,7 +42,7 @@ jobs: -o celix/*:enable_undefined_sanitizer=True -o celix/*:celix_err_buffer_size=5120 -o *:shared=True - run: conan build -c tools.cmake.cmaketoolchain:generator=Ninja ${CONAN_BUILD_OPTIONS} -b missing + run: conan build --lockfile=conan/safe-defaults.lock -c tools.cmake.cmaketoolchain:generator=Ninja ${CONAN_BUILD_OPTIONS} -b missing - name: Set fuzzer run time id: set-runtime run: | diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index cf4420b50..b2b61c366 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -66,7 +66,7 @@ jobs: -o mosquitto/*:broker=True -o *:shared=True run: | - conan build . -c tools.cmake.cmaketoolchain:generator=Ninja -pr:b default -pr:h default -s:b build_type=Release -s:h build_type=Release ${CONAN_BUILD_OPTIONS} -b missing + conan build . --lockfile=conan/safe-defaults.lock -c tools.cmake.cmaketoolchain:generator=Ninja -pr:b default -pr:h default -s:b build_type=Release -s:h build_type=Release ${CONAN_BUILD_OPTIONS} -b missing - name: Test run: ctest --preset conan-release --output-on-failure -j1 diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 42282a7d8..835ba89b0 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -84,7 +84,7 @@ jobs: -o mosquitto/*:broker=True -o *:shared=True run: | - conan build . -c tools.cmake.cmaketoolchain:generator=Ninja -pr:b release -pr:h default ${CONAN_BUILD_OPTIONS} -b missing + conan build . --lockfile=conan/safe-defaults.lock -c tools.cmake.cmaketoolchain:generator=Ninja -pr:b release -pr:h default ${CONAN_BUILD_OPTIONS} -b missing - name: Test env: CONAN_PRESET: ${{ matrix.type == 'Debug' && 'conan-debug' || 'conan-relwithdebinfo' }} diff --git a/conan/safe-defaults.lock b/conan/safe-defaults.lock index 92d5eb0af..3444df113 100644 --- a/conan/safe-defaults.lock +++ b/conan/safe-defaults.lock @@ -13,20 +13,27 @@ "libxml2/2.15.3#3406c6d8d327e9b84c0c894feb859514%1777886326.291", "libuv/1.51.0#ea781dcacf58c65462ab0d3d75e9b002%1764745176.352", "libiconv/1.17#9923bc6dc6f106646d6967e0039a5ada%1774021608.288", + "libgettext/0.22#b09eea019e19b9b9c46d8f1da7d75444%1765809130.834", "libffi/3.4.8#a045c00fb26779635e3bed40e80c5254%1753360042.396", "libcurl/8.21.0#dd94e078c967e162aae33d353142fa31%1786959569.239", "jansson/2.14#7710071716bc129093fec1cc4d19f424%1760696859.73", + "gtest/1.17.0#43201cc96e5d35332662ce8890cceb27%1786446850.202", + "gettext/0.21#b0c966878ab30fc52d80173175a0423c%1765299123.464", "civetweb/1.16#f4a42c8aa0bc0fe4bbe2a2270af0cea2%1750148475.207", - "bzip2/1.0.8#c470882369c2d95c5c77e970c0c7e321%1762886692.465" + "bzip2/1.0.8#c470882369c2d95c5c77e970c0c7e321%1762886692.465", + "benchmark/1.9.5#b885dc73ad67b40a55d45684d1c88ad1%1774363287.434" ], "build_requires": [ + "zstd/1.5.5#a4398ab5244b10fb081eeac217b5ef9f%1760955096.505", "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", + "hiredis/1.1.0#8b3ef72a6cee0e83ddbe0b52da5ceb54%1744279491.095", "gnu-config/cci.20210814#466e9d4d7779e1c142443f7ea44b4284%1762363589.329", "cmake/3.26.4#0b40747e190e755932767f2ec4768ff5%1685461463.385", + "ccache/4.7.4#83eaaa1059cdc33a90eb35249e1df6fb%1689758368.487", "automake/1.16.5#b91b7c384c3deaa9d535be02da14d04f%1755524470.56", "autoconf/2.71#51077f068e61700d65bb05541ea1e4b0%1731054366.86" ], @@ -43,7 +50,8 @@ "openssl/[>=3.2.0 <4]" ], "openssl/[>=3 <4]": [ - "openssl/3.6.3" + "openssl/3.6.3", + "openssl/[>=3.2.0 <4]" ], "zlib/[>=1.3.1 <2]": [ "zlib/1.3.1#cac0f6daea041b0ccf42934163defb20" diff --git a/documents/building/sbom.md b/documents/building/sbom.md index ebdafd2ad..7a5d101e9 100644 --- a/documents/building/sbom.md +++ b/documents/building/sbom.md @@ -21,10 +21,11 @@ limitations under the License. # 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. +Apache Celix provides a committed `conan/safe-defaults.lock` that pins the +recipe revisions used across the Conan CI builds. CI also publishes a +CycloneDX 1.6 SBOM for one documented Linux / GCC / Release 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 @@ -39,13 +40,19 @@ 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: +The canonical SBOM baseline is the Linux / GCC / Release Conan graph with: * `celix/*:build_all=True` * `celix/*:celix_cxx17=True` * `mosquitto/*:broker=True` * `*:shared=True` +The lockfile also contains recipe revisions required by the other supported +Conan CI graphs, including platform-specific macOS dependencies. Those extra +entries make the CI dependency resolution reproducible without changing the +contents of the Linux / GCC / Release SBOM; Conan uses only the entries needed +by the selected graph. + 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. @@ -56,10 +63,10 @@ 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`: +The Conan CI builds explicitly use `conan/safe-defaults.lock` so their +upstream recipe revisions remain reproducible. For the Linux GCC Release +configuration, CI additionally generates the CycloneDX SBOM with Conan's +built-in deployer using the same lockfile: ```bash conan install . \