Automagically build CycloneDX Software Bills of Materials (SBOMs) for Nix packages!
Bombon generates CycloneDX v1.5 SBOMs which aim to be compliant with:
If you find that they aren't compliant in any way, please open an issue!
nix flake init -t github:nikstur/bombon
Or manually copy this to flake.nix
in your repository:
# file: flake.nix
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
bombon.url = "github:nikstur/bombon";
bombon.inputs.nixpkgs.follows = "nixpkgs";
};
outputs = { self, nixpkgs, bombon }:
let
system = "x86_64-linux";
pkgs = import nixpkgs { inherit system; };
in
{
packages.${system}.default = bombon.lib.${system}.buildBom pkgs.hello { };
};
}
niv init
niv add nikstur/bombon
# file: default.nix
let
sources = import ./nix/sources.nix { };
pkgs = import sources.nixpkgs { };
bombon = import sources.bombon { inherit pkgs; };
in
bombon.buildBom pkgs.hello { }
Some language ecosystems in Nixpkgs (most notably Rust and Go) vendor
dependencies. This means that not every dependency is its own derivation and
thus bombon cannot record their information as it does with "normal" Nix
dependencies. However, bombon can automatically read SBOMs generated by other
tools (like cargo-cyclonedx
) for the vendored dependencies from a passthru
derivation called bombonVendoredSbom
.
You can use the passthruVendoredSbom.rust
function to add the
bombonVendoredSbom
passthru derivation to a Rust package:
myPackageWithSbom = bombon.passthruVendoredSbom.rust myPackage { inherit pkgs; };
Or using Flakes:
myPackageWithSbom = bombon.lib.${system}.passthruVendoredSbom.rust myPackage { inherit pkgs; };
An SBOM built from this new derivation will now include the vendored dependencies.
buildBom
accepts options as an attribute set. All attributes are optional:
extraPaths
: a list of store paths to also consider for the SBOM. This is
useful when you build images that discard their references (e.g. with
unsafeDiscardReferences
but you still want their contents to appear in the SBOM. The extraPaths
will appear as components of the main derivation.includeBuildtimeDependencies
: boolean flag to include buildtime dependencies in output.excludes
: a list of regex patterns of store paths to exclude from the final
SBOM.Example:
bombon.lib.${system}.buildBom pkgs.hello {
extraPaths = [ pkgs.git ];
includeBuildtimeDependencies = true;
excludes = [ "service" ];
}
passthruVendoredSbom.rust
also accepts includeBuildtimeDependencies
as an optional attribute.
Example:
myPackageWithSbom = bombon.passthruVendoredSbom.rust myPackage { inherit pkgs; includeBuildtimeDependencies = true; };
During development, the Nix Repl is a convenient and quick way to test changes. Start the repl, loading your local version of nixpkgs.
nix repl <nixpkgs>
Inside the repl, load the bombon flake and build the BOM for a package you are interested in.
:l .
:b lib.x86_64-linux.buildBom python3 { }
Remember to re-load the bombon flake every time you made changes to any of the source code.
The way dependencies are retrieved using Nix is heavily influenced by this blog article from Nicolas Mattia.