Skip to content

SBOM Generation

CTRL-OS inherits a rich package set from Nixpkgs. Keeping the whole set maintained would be prohibitively hard, especially since it is likely your projects require only a small subset of packages.

Our customers may provide a Software Bill of Materials (SBOM) for projects built using Nixpkgs or CTRL-OS, which allows us to identify the CTRL-OS packages you depend on.

This document explains strategies to generate an SBOM a format we can use.

Note

If for any reason this strategy does not work out for you, get in touch. We can help you get us the required information in other ways.

The 10 seconds guide

Use sbomnix on your project, provide us with the cdx.json output, and tell us the pinned Nixpkgs or CTRL-OS 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 CTRL-OS System Configuration

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

{
  description = "Minimal CTRL-OS system configuration";
  inputs = {
    nixpkgs.url = "https://channels.ctrl-os.com/channel/ctrlos-24.05.tar.xz";
  };
  outputs =
    { self
    , nixpkgs
    , ...
    }:
    let
      system = "x86_64-linux";
    in
    {
      nixosConfigurations = {
        "ctrlos-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 CTRL-OS system configuration with SBOM instrumentation";
  inputs = {
    nixpkgs.url = "https://channels.ctrl-os.com/channel/ctrlos-24.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 = {
        "ctrlos-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 ctrlos-device example system's SBOM can be built, from the previous sample.

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

Automatically Generating SBOMs with GitLab CI

If you use GitLab to manage your CTRL-OS 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.ctrlos-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