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