Skip to content

SBOM Generation

This document explains how to generate a Software Bill of Materials (SBOM) in a format we can use.

The 10 seconds guide

Use sbomnix on your project, provide us with the cdx.json output, and tell us the pinned Nixpkgs or Cyberus Linux inputs from which the SBOM was generated.

We should be able to sort it out from there.

Adding SBOM instrumentation to your Nix project

Instead of imperatively generating the SBOM once, hoping you have captured everything in it, you may prefer to add an output to your project to generate the SBOM.

A quick and easy way to get an SBOM for your Nix-built projects is to use the nix-sbom-helper tooling.

If your project follows the conventions from Flakes, using nix-sbom-helper.sbomsForFlakeOutputs should be sufficient. Otherwise amend your expressions to use the buildSbom function on your outputs.

Step-by-step example

Your Cyberus Linux System Configuration

We assume that you have a flake.nix file that defines the Cyberus Linux configuration for your embedded device. A minimal example looks as follows.

{
  description = "Minimal Cyberus Linux system configuration";
  inputs = {
    nixpkgs.url = "https://channels.cyberus-linux.com/channel/cyberus-linux-26.05.tar.xz";
  };
  outputs =
    { self
    , nixpkgs
    , ...
    }:
    let
      system = "x86_64-linux";
    in
    {
      nixosConfigurations = {
        "cyberus-linux-device" = nixpkgs.lib.nixosSystem {
          inherit system;
          modules = [
            ./configuration.nix
          ];
        };
      };
    };
}

Using the instrumentation

Add the nix-sbom-helper flake input and use the sbomsForFlakeOutputs helper in your configuration:

{
  description = "Minimal Cyberus Linux system configuration with SBOM instrumentation";
  inputs = {
    nixpkgs.url = "https://channels.cyberus-linux.com/channel/cyberus-linux-26.05.tar.xz";
    # ➊ Add the `nix-sbom-helper` input.
    nix-sbom-helper.url = "github:cyberus-technology/nix-sbom-helper";
  };
  outputs =
    { self
    , nixpkgs
    , # ➋ Use the `nix-sbom-helper` input.
      nix-sbom-helper
    , ...
    }:
    let
      system = "x86_64-linux";
    in
    {
      nixosConfigurations = {
        "cyberus-linux-device" = nixpkgs.lib.nixosSystem {
          inherit system;
          modules = [
            ./configuration.nix
          ];
        };
      };
      # ➌ Add the `sboms` output.
      sboms = nix-sbom-helper.sbomsForFlakeOutputs self;
    };
}

Building the SBOM

The following shows how the cyberus-linux-device example system's SBOM can be built, from the previous sample.

 $ nix build .#sboms.nixosConfigurations.cyberus-linux-device
[...]
 $ ls -l result/
total 9304
-r--r--r-- 2 root root 3034413 Dec 31  1969 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-nixos-system-cyberus-linux-YY.MM.yyyymmdd.dirty.cdx.json
-r--r--r-- 2 root root 1007169 Dec 31  1969 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-nixos-system-cyberus-linux-YY.MM.yyyymmdd.dirty.csv
-r--r--r-- 2 root root 5482030 Dec 31  1969 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-nixos-system-cyberus-linux-YY.MM.yyyymmdd.dirty.spdx.json

Automatically Generating SBOMs with GitLab CI

If you use GitLab to manage your Cyberus Linux configuration, you can utilize GitLab CI to automatically generate the SBOM. Use the following stage definition as a starting point.

build:sbom:
  stage: build
  interruptible: true
  image: nixos/nix:2.31.0
  script: |
    nix build .#sboms.nixosConfigurations.cyberus-linux-device
    # Move SBOM to a predictable name, used as an artifact.
    cp -v result/*.cdx.json sbom.cdx.json
  artifacts:
    expire_in: 1 week
    paths:
      - sbom.cdx.json