A comprehensive SBOM (Software Bill of Materials) generator for systems running both Ubuntu and Nix packages. Generates SPDX 2.3 compliant JSON documents.
- Ubuntu SBOM Generation: Scans dpkg-installed packages on Ubuntu/Debian systems
- Nix SBOM Generation: Uses sbomnix to analyze Nix derivations
- Merged SBOM: Combines both Ubuntu and Nix packages into a single unified SBOM
- SPDX 2.3 Compliant: Generates valid SPDX JSON documents
- License Detection: Extracts license information from package metadata
- Package URLs (purl): Includes purl references for both deb and nix packages
- Nix with flakes enabled
- Ubuntu/Debian system (for Ubuntu SBOM generation)
- Access to dpkg and package metadata
Clone the repository and enter the development shell:
git clone <repository-url>
cd ubuntu-nix-sbom
nix developThe project provides several Nix flake apps for different use cases:
Generate a merged SBOM containing both Ubuntu and Nix packages:
nix run .#sbom-generator -- --nix-target /nix/store/xxx-system --output merged-sbom.jsonOr use the alias:
nix run .#sbom-combined -- --nix-target /nix/store/xxx-system --output merged-sbom.jsonOptions:
--nix-target <path>: Required. Path to the Nix derivation to analyze--output <file>: Output file path (default: merged-sbom.spdx.json)--include-files: Include file checksums for Ubuntu packages (slower)--progress: Show progress indicators (default: true)--no-progress: Disable progress indicators
Example:
nix run .#sbom-generator -- \
--nix-target /nix/var/nix/profiles/system \
--output my-system-sbom.json \
--include-files \
--no-progressGenerate SBOM for Ubuntu/Debian packages only:
nix run .#sbom-ubuntu -- --output ubuntu-sbom.jsonOptions:
--output <file>: Output file path (default: ubuntu-sbom.spdx.json)--include-files: Include file checksums (slower but more detailed)--progress: Show progress indicators (default: true)--no-progress: Disable progress indicators
Generate SBOM for Nix packages only:
nix run .#sbom-nix -- /nix/store/xxx-derivation --output nix-sbom.jsonOptions:
--output <file>: Output file path (default: nix-sbom.spdx.json)
The derivation path is required as the first positional argument.
Validate an SBOM file against the SPDX 2.3 specification:
nix run .#validate-spdx -- my-sbom.spdx.jsonThis uses the official spdx-tools to verify compliance.
| App | Description |
|---|---|
sbom-generator |
Generate combined Ubuntu + Nix SBOM (default app) |
sbom-combined |
Alias for sbom-generator |
sbom-ubuntu |
Generate Ubuntu-only SBOM |
sbom-nix |
Generate Nix-only SBOM using sbomnix |
validate-spdx |
Validate SBOM against SPDX 2.3 specification |
- Queries dpkg for all installed packages
- Extracts metadata (version, architecture, maintainer, homepage)
- Reads license information from
/usr/share/doc/<package>/copyright - Optionally calculates SHA256 checksums of package files
- Generates SPDX 2.3 JSON with purl references (
pkg:deb/ubuntu/...)
- Uses sbomnix to analyze the specified derivation
- Extracts all dependencies and their metadata
- Generates SPDX 2.3 JSON with purl references (
pkg:nix/...)
- Loads both Ubuntu and Nix SPDX documents
- Creates a new document with a single "SPDXRef-System" root package
- Renames package SPDXIDs to avoid conflicts:
- Ubuntu packages:
SPDXRef-Ubuntu-Package-* - Nix packages:
SPDXRef-Nix-Package-*
- Ubuntu packages:
- Preserves all package metadata and relationships
- Combines creator information from both sources
- Adds merger tool to the creator list
SPDXRef-DOCUMENT (describes) → SPDXRef-System
├── (contains) SPDXRef-Ubuntu-Package-1-bash
├── (contains) SPDXRef-Ubuntu-Package-2-curl
├── (contains) SPDXRef-Nix-Package-1-nixpkgs-...
└── (contains) SPDXRef-Nix-Package-2-...
Duplicate packages (same software in both Ubuntu and Nix) are kept separate and identified by:
- Different SPDXIDs (Ubuntu vs Nix prefix)
- Different purl external references:
- Ubuntu:
pkg:deb/ubuntu/bash@5.1-6ubuntu1?arch=amd64 - Nix:
pkg:nix/nixpkgs/bash@5.1-...
- Ubuntu:
{
"spdxVersion": "SPDX-2.3",
"dataLicense": "CC0-1.0",
"SPDXID": "SPDXRef-DOCUMENT",
"name": "Ubuntu-Nix-System-SBOM-2025-11-05",
"documentNamespace": "https://sbom.ubuntu-nix.system/...",
"creationInfo": {
"created": "2025-11-05T12:00:00Z",
"creators": [
"Tool: ubuntu-sbom-generator-1.0",
"Tool: sbomnix-...",
"Tool: ubuntu-nix-sbom-merger-1.0"
],
"licenseListVersion": "3.20"
},
"packages": [
{
"SPDXID": "SPDXRef-System",
"name": "Ubuntu-Nix-System",
"downloadLocation": "NOASSERTION",
"filesAnalyzed": false,
"licenseConcluded": "NOASSERTION",
"licenseDeclared": "NOASSERTION",
"copyrightText": "NOASSERTION",
"description": "Combined Ubuntu and Nix package system"
},
...
],
"relationships": [
{
"spdxElementId": "SPDXRef-DOCUMENT",
"relatedSpdxElement": "SPDXRef-System",
"relationshipType": "DESCRIBES"
},
...
]
}The project includes GitHub Actions workflows for automated testing and releases:
On every pull request to main:
- Nix Flake Check: Runs
nix flake check --all-systemsto validate the flake - Formatting: Checks code formatting with
nix fmt --fail-on-change - SPDX Validation:
- Builds the Ubuntu SBOM generator
- Generates a test SBOM
- Validates the output against SPDX 2.3 specification using
spdx-tools - Tests conversion to other SPDX formats (tag-value, XML, YAML)
- Uploads test SBOM as artifact
On every pull request and push to main:
- Dynamic Package Discovery: Uses
nix flake showto discover all Supabase Postgres packages - Runtime Dependencies: Generates SBOMs with accurate runtime dependencies using sbomnix
- SPDX Validation: Validates every generated SBOM against SPDX 2.3 specification
- CPE Fixing: Automatically fixes invalid CPE references from upstream tools
- Concurrency Control: Cancels previous runs when new commits are pushed
The workflow dynamically discovers and validates SBOMs for all packages except:
- Extension packages (
psql_*/exts/*- already included inpsql_*/bin) - Documentation packages (require network access to build)
On every merge to main:
- Builds the ARM64 static binary on an ARM Linux runner
- Tests the binary and validates SPDX output
- Automatically increments the patch version (semver)
- Creates a GitHub release with:
- Changelog from commits since last release
- ARM64 static binary as downloadable asset
- SHA256 checksum file
- Installation and verification instructions
- Binary size
The release workflow uses semantic versioning (e.g., v1.2.3) and automatically tags releases.
For Ubuntu/Debian systems without Nix, a static binary is available that generates Ubuntu-only SBOMs.
The ubuntu-sbom binary is a standalone executable with no dependencies:
# Download from GitHub release
curl -LO https://github.com/YOUR_ORG/ubuntu-nix-sbom/releases/latest/download/ubuntu-sbom-arm64
chmod +x ubuntu-sbom-arm64
# Generate Ubuntu SBOM
./ubuntu-sbom-arm64 --output my-system.spdx.jsonOptions:
--output <file>: Output file path (default: ubuntu-sbom.spdx.json)--include-files: Include SHA256 checksums of all package files (slower)--progress: Show progress indicators (default: true)--no-progress: Disable progress indicators
Example with all options:
./ubuntu-sbom-arm64 \
--output detailed-sbom.json \
--include-files \
--no-progressThis binary only scans dpkg-installed packages and does not require Nix.
The flake includes static binary builds that can be distributed to Ubuntu users:
nix build .#ubuntu-sbom-static-arm64 -o result-arm64The binary will be at result-arm64/bin/ubuntu-sbom (~2.4MB, statically linked).
nix build .#ubuntu-sbom-static -o result-static# Build the binary
nix build .#ubuntu-sbom-static-arm64 -o result-arm64
# Create a GitHub release
gh release create v1.0.0 \
result-arm64/bin/ubuntu-sbom#ubuntu-sbom-arm64 \
--title "v1.0.0" \
--notes "Ubuntu SBOM Generator v1.0.0"Users can then download and run directly on Ubuntu ARM64 systems:
# Download from GitHub release (use -L to follow redirects)
curl -LO https://github.com/YOUR_ORG/ubuntu-nix-sbom/releases/download/v1.0.0/ubuntu-sbom-arm64
chmod +x ubuntu-sbom-arm64
# Run without Nix
./ubuntu-sbom-arm64 --output my-sbom.jsonThe project uses the official spdx-tools to validate SPDX 2.3 compliance.
pip install spdx-tools# Generate an SBOM
nix run .#sbom-ubuntu -- --output my-sbom.spdx.json
# Validate it against SPDX 2.3 specification
pyspdxtools -i my-sbom.spdx.json --validate# Convert to SPDX tag-value format
pyspdxtools -i my-sbom.spdx.json -o my-sbom.spdx --output-format tag-value
# Convert to SPDX XML format
pyspdxtools -i my-sbom.spdx.json -o my-sbom.spdx.xml --output-format xml
# Convert to SPDX YAML format
pyspdxtools -i my-sbom.spdx.json -o my-sbom.spdx.yaml --output-format yamlBoth the PR check and release workflows automatically validate SPDX output:
- PR workflow: Validates test SBOMs and uploads them as artifacts
- Release workflow: Validates SPDX output before creating releases
Enter the development shell:
nix developThis provides:
- Go toolchain
- gopls (Go language server)
- sbomnix
- SPDX validation tools (spdx-tools)
- Formatting tools (nixfmt, shellcheck, shfmt, gofmt)
- Pre-commit hooks (automatically installed)
Build the Go binaries manually:
# Build the Ubuntu-only static binary
go build -o ubuntu-sbom main.go
# Build the full sbom tool with all subcommands
go build -o sbom ./cmd/sbomThe project uses treefmt to format code automatically. Formatters are configured for:
- Nix files:
nixfmt-rfc-style - Shell scripts:
shellcheckandshfmt - Go code:
gofmt - Dead code removal:
deadnix
Format all files:
nix fmtCheck formatting without modifying files:
nix flake checkPre-commit hooks are automatically installed when entering the dev shell. They will:
- Run
treefmton all staged files before each commit - Ensure code is properly formatted
To manually run the pre-commit checks:
nix flake checkThe hooks will automatically format your code when you commit changes.
Apache-2.0
This project is licensed under the Apache License, Version 2.0 - see the LICENSE file for details.
The Apache-2.0 license is compatible with sbomnix (also Apache-2.0), which this project integrates with for Nix SBOM generation.
Contributions welcome! Please open issues or pull requests.