Meldora

How to generate an SBOM

An SBOM is produced from the final artefact (firmware image, directory, package) or from source code. The simplest route is one command in the pipeline that sends the file to Meldora after every release.

Syft (image, directory, archive)

Linux firmware (Yocto, Buildroot, OpenWrt), container images, any directory with binaries.
syft dir:./rootfs -o cyclonedx-json > sbom.cdx.json
syft dir:./rootfs-unpacked -o cyclonedx-json > sbom.cdx.json   # unpack the firmware image first, e.g. with unblob
Add the product version: syft … --source-name 'Gateway GW-10' --source-version 4.2.1

cdxgen (source code)

npm, Python, Java, .NET, Go, Rust, C/C++ projects with CMake or Conan.
npx @cyclonedx/cdxgen -o sbom.cdx.json --project-name 'Kasomat Panel' --project-version 2.7.5

Yocto / OpenEmbedded

Firmware built with Yocto.
# conf/local.conf
INHERIT += "create-spdx"
SPDX_INCLUDE_SOURCES = "0"
# output: tmp/deploy/spdx/… (SPDX JSON), or run Syft on the image
Meldora accepts SPDX; for CycloneDX run Syft on the rootfs image.

Zephyr RTOS

Zephyr firmware.
west spdx --init
west build -b <board>
west spdx

.NET

.NET applications and services.
dotnet tool install --global CycloneDX
dotnet CycloneDX MyApp.sln -o ./sbom -j

npm / Python

Web applications and tools.
npx @cyclonedx/cyclonedx-npm --output-file sbom.cdx.json
pip install cyclonedx-bom && cyclonedx-py environment -o sbom.cdx.json

Upload from CI

Create the API token in the settings (shown only once) and store it as a secret. The product identifier is in the sample call in the settings.

GitLab CI

sbom:
  stage: release
  image: alpine:3.20
  script:
    - apk add --no-cache curl
    - curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
    - syft dir:./rootfs -o cyclonedx-json --source-version "$CI_COMMIT_TAG" > sbom.cdx.json
    - curl -fsS -X POST "https://meldora.pl/api/products/$MELDORA_PRODUCT/sbom?version=$CI_COMMIT_TAG" -H "Authorization: Bearer $MELDORA_TOKEN" -F "file=@sbom.cdx.json"
  rules:
    - if: $CI_COMMIT_TAG

GitHub Actions

- name: SBOM
  uses: anchore/sbom-action@v0
  with:
    path: ./rootfs
    format: cyclonedx-json
    output-file: sbom.cdx.json
- name: Send to Meldora
  run: curl -fsS -X POST "https://meldora.pl/api/products/${{ vars.MELDORA_PRODUCT }}/sbom?version=${{ github.ref_name }}" -H "Authorization: Bearer ${{ secrets.MELDORA_TOKEN }}" -F "file=@sbom.cdx.json"

SBOM quality

  • Every component should have a version; a component without one is not monitored.
  • Make sure PURLs are present: generators add them, hand-written SBOMs usually do not.
  • Put the product version in the SBOM metadata, so the file lands in the right version by itself.
  • Generate the SBOM from the final artefact, not from the repository before the build: library versions often differ.
  • Include statically linked dependencies (e.g. in C/C++): scanners cannot see them, but the CRA covers them.