Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
eeb4bf1
Init
atomicturtle May 14, 2025
db69a03
Adding SBOM module
atomicturtle May 14, 2025
de300cf
Merge pull request #1 from atomicturtle/sbom-support
atomicturtle May 14, 2025
967abed
Update SBOM generator plugin to v1.2.5
atomicturtle Dec 31, 2025
d77ceb7
Resolve merge conflict in config.py by merging sbom_generator and unbreq
atomicturtle Dec 31, 2025
dc2ae8f
Remove legacy sbom_generator.py from root directory
atomicturtle Dec 31, 2025
f98e9dc
Address PR feedback: standardize imports, logging, versioning, and docs
atomicturtle Dec 31, 2025
bb6da3c
Update license to GPL 2.0 or later
atomicturtle Dec 31, 2025
9e2cb00
docs: Update SBOM plugin availability to 6.7
atomicturtle Jan 7, 2026
7f4ac18
feat: Refactor SBOM generator and add release notes
atomicturtle Jan 7, 2026
8426db1
fix: Use rpm2archive instead of rpm2cpio for source extraction
atomicturtle Jan 7, 2026
ab79130
fix: Refactor SBOM generator to use python-rpm and fix local variable…
atomicturtle Jan 7, 2026
9bb5988
fix: Replace shutil.rmtree with mockbuild.file_util.rmtree for safer …
atomicturtle Jan 7, 2026
8510bfb
fix: Use python-distro to detect chroot distribution
atomicturtle Jan 7, 2026
e0aa256
refactor: Rename _convert_to_chroot_path to from_chroot_path
atomicturtle Jan 7, 2026
3bdbb46
refactor: Remove redundant special-case CPE vendor/product mappings
atomicturtle Jan 7, 2026
98570c1
fix: Replace deprecated datetime.utcnow() with timezone-aware datetim…
atomicturtle Jan 7, 2026
caafc17
Lint revisions
atomicturtle Jan 29, 2026
6753919
Minor refactors
atomicturtle Jan 29, 2026
7899e18
SPDX option support
atomicturtle Jan 29, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
325 changes: 325 additions & 0 deletions docs/Plugin-SBOM.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,325 @@
---
layout: default
title: Plugin SBOM Generator
---

This plugin generates a Software Bill of Materials (SBOM) in CycloneDX format for packages built with Mock. The SBOM provides detailed information about the build environment, source files, and resulting packages, optimized for security use cases.

## Features

* Generates SBOM in CycloneDX 1.5 format (JSON)
* Captures information about:
* Source files and patches from spec files
* Binary RPM metadata with PURL and CPE identifiers
* Complete build toolchain packages
* Runtime dependencies
* File hashes (SHA-256)
* GPG signatures with detailed metadata
* Outputs SBOM as JSON file in the build results directory
* Compatible with security scanners (Grype, Trivy, Snyk)

## Usage

### Basic Usage

The simplest way to use the SBOM generator is to enable it for a single build:

```bash
# Build a package and generate SBOM
mock --enable-plugin=sbom_generator --rebuild package.src.rpm

# Or build from an existing SRPM
mock --enable-plugin=sbom_generator --rebuild ~/rpmbuild/SRPMS/package-1.0-1.fc42.src.rpm

# Specify a chroot configuration
mock --enable-plugin=sbom_generator --rebuild package.src.rpm -r rocky-9-x86_64
```

After the build completes, the SBOM will be available in the build results directory:

```bash
# Find the SBOM file
ls /var/lib/mock/*/result/sbom.cyclonedx.json

# View the SBOM
cat /var/lib/mock/rocky-9-x86_64/result/sbom.cyclonedx.json | jq .

# Get build results directory path
mock --resultdir package.src.rpm
```

### Viewing and Analyzing the SBOM

The generated SBOM can be analyzed using various tools:

```bash
# View basic SBOM information
jq '.metadata.component' sbom.cyclonedx.json
jq '.components | length' sbom.cyclonedx.json
jq '.dependencies | length' sbom.cyclonedx.json

# List all built packages
jq '.components[] | select(.type == "library") | {name, version, purl}' sbom.cyclonedx.json

# List source files used in the build
jq '.components[] | select(.properties[]?.name == "mock:source:type") | {name, hashes}' sbom.cyclonedx.json

# View runtime dependencies for a specific package
jq '.dependencies[] | select(.ref | contains("httpd"))' sbom.cyclonedx.json
```

### Using with Security Scanners

The SBOM can be directly used with security vulnerability scanners:

```bash
# Scan with Grype
grype sbom:./sbom.cyclonedx.json

# Scan with Trivy
trivy sbom sbom.cyclonedx.json

# Export to other formats if needed
syft convert sbom.cyclonedx.json -o spdx-json > sbom.spdx.json
```

## Configuration

### Enabling the Plugin

The plugin is disabled by default. You can enable it in several ways:

**Option 1: Command line (recommended for one-off builds)**
```bash
mock --enable-plugin=sbom_generator --rebuild package.src.rpm
```

**Option 2: Configuration file (for persistent enablement)**

Add to your Mock configuration file (e.g., `/etc/mock/fedora-rawhide-x86_64.cfg`):

```python
config_opts['plugin_conf']['sbom_generator_enable'] = True
config_opts['plugin_conf']['sbom_generator_opts'] = {
'generate_sbom': True
}
```

**Option 3: User configuration**

Add to `~/.config/mock/mock.cfg`:

```python
config_opts['plugin_conf']['sbom_generator_enable'] = True
```

### Configuration Options

The plugin supports several configuration options to control SBOM generation:

```python
config_opts['plugin_conf']['sbom_generator_opts'] = {
'generate_sbom': True, # Enable SBOM generation (default: True)
'include_file_components': True, # Include file-level components (default: True)
'include_file_dependencies': False, # Include file-to-package dependencies (default: False)
'include_debug_files': False, # Include debug files in file components (default: False)
'include_man_pages': True, # Include man pages in file components (default: True)
'include_toolchain_dependencies': False, # Include build toolchain in dependencies (default: False)
}
```

**Configuration Options Explained:**

- `include_file_components`: When enabled, creates individual file components for each file in built packages, including hashes, permissions, and ownership information.
- `include_file_dependencies`: Creates dependency relationships showing which files belong to which packages.
- `include_debug_files`: Filters out debug files (`.debug`, files in `/usr/lib/debug`) from file components.
- `include_man_pages`: Filters out man pages from file components.
- `include_toolchain_dependencies`: Adds build toolchain packages to the dependencies array (useful for complete build provenance, but can make dependency graphs very large).

## Output

The plugin generates a file named `<name>-<version>-<release>.sbom` in the build results directory (typically `/var/lib/mock/fedora-42-x86_64/result/`). The SBOM includes:

* CycloneDX document metadata
* Build timestamp
* Tool information (Mock SBOM Generator)
* Mock-specific build properties (host, distribution, chroot, config)
* RPM header metadata surfaced at the document level (buildhost, buildtime, source RPM, group, epoch, distribution, manufacture/vendor)
* Components array containing:
* Built packages (type: "library" or "application")
* Package name, version, and PURL
* CPE identifiers for vulnerability matching
* License information plus RPM summary as description
* RPM file SHA-256 hash
* Vendor, packager, buildhost, buildtime, source RPM, group, epoch, distribution metadata
* Upstream/project URLs and source RPM links via `externalReferences`
* GPG signature details
* Note: Source tarballs and patches are represented as separate file components in the components array with their own BOM refs for traceability
* Build toolchain packages (type: "library")
* All packages installed in the build environment
* Signature information
* Marked with `mock:role: "build-toolchain"` property
* Source files (type: "file")
* Source and patch files from spec
* SHA-256 hashes
* Signature information if available
* Dependencies array
* Runtime dependencies for built packages (libraries/RPMs the package depends on)
* Dependency relationships modeled using bom-refs
* Note: Source code relationships are represented in component properties and the components array, not in the dependencies section (source code is a build input, not a runtime dependency)

## Example SBOM Structure

```json
{
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"serialNumber": "urn:uuid:...",
"version": 1,
"metadata": {
"timestamp": "2024-01-19T15:20:00Z",
"tools": [
{
"vendor": "Mock",
"name": "mock-sbom-generator",
"version": "1.0"
}
],
"properties": [
{ "name": "mock:build:host", "value": "build.example.com" },
{ "name": "mock:build:distribution", "value": "Fedora 42" },
{ "name": "mock:build:chroot", "value": "/var/lib/mock/fedora-42-x86_64/root" },
{ "name": "mock:rpm:buildhost", "value": "builder.fedora.example.org" },
{ "name": "mock:rpm:buildtime", "value": "2024-01-19T15:15:00+00:00" },
{ "name": "mock:rpm:sourcerpm", "value": "package-name-1.0-1.fc42.src.rpm" },
{ "name": "mock:rpm:group", "value": "System Environment/Libraries" },
{ "name": "mock:rpm:epoch", "value": "1" }
],
"manufacture": {
"name": "Fedora Project"
},
"component": {
"type": "application",
"name": "package-name",
"version": "1.0-1.fc42",
"bom-ref": "build-output:package-name",
"description": "Package summary (build output containing 3 package(s))",
"licenses": [
{
"license": {
"id": "MIT"
}
}
],
"externalReferences": [
{ "type": "distribution", "url": "package-name-1.0-1.fc42.src.rpm" },
{ "type": "website", "url": "https://example.com/package-name" }
]
}
},
"components": [
{
"type": "library",
"bom-ref": "pkg:rpm/fedora/[email protected]?arch=x86_64",
"name": "package-name",
"version": "1.0-1.fc42",
"purl": "pkg:rpm/fedora/[email protected]?arch=x86_64",
"externalReferences": [
{
"type": "other",
"comment": "CPE 2.3",
"url": "cpe:2.3:a:fedora:package-name:1.0:*:*:*:*:*:*:*:*"
},
{
"type": "website",
"url": "https://src.fedoraproject.org/rpms/package-name"
},
{
"type": "distribution",
"url": "package-name-1.0-1.fc42.src.rpm"
}
],
"licenses": [
{
"license": {
"id": "MIT"
}
}
],
"hashes": [
{
"alg": "SHA-256",
"content": "..."
}
],
"properties": [
{
"name": "mock:rpm:vendor",
"value": "Fedora Project"
},
{
"name": "mock:rpm:buildhost",
"value": "builder.fedora.example.org"
},
{
"name": "mock:rpm:buildtime",
"value": "2024-01-19T15:15:00+00:00"
},
{
"name": "mock:rpm:sourcerpm",
"value": "package-name-1.0-1.fc42.src.rpm"
},
{
"name": "mock:signature:type",
"value": "GPG"
}
]
}
],
"dependencies": [
{
"ref": "pkg:rpm/fedora/[email protected]",
"dependsOn": [
"pkg:rpm/fedora/[email protected]"
]
}
]
}
```

## Security Tool Compatibility

The generated CycloneDX SBOM is compatible with popular security scanners:

* **Grype**: `grype sbom:./sbom.cyclonedx.json`
* **Trivy**: `trivy sbom sbom.cyclonedx.json`
* **Snyk**: Supports CycloneDX format for vulnerability scanning

The SBOM includes PURL (Package URL) and CPE identifiers for accurate vulnerability matching.

## Requirements

* Python 3.x
* RPM tools for package metadata extraction
* Access to build environment for package information

## Notes

* The plugin runs in the `postbuild` hook, after the build completes
* SBOM generation is skipped if no RPM, source RPM, or spec file is found
* The plugin is designed to work with both source and binary RPM builds
* Build environment information is collected using `rpm -qa` command
* All build toolchain packages are captured, providing complete build provenance
* PURL format: `pkg:rpm/{distro}/{package}@{version}?arch={arch}`
* Mock-specific metadata is stored in component and metadata properties with `mock:` prefix

## Competitive Advantages

This SBOM generator leverages Mock's unique build environment visibility:

* **Complete Build Toolchain**: Captures every package installed in the build chroot, not just declared dependencies
* **Build-Time Provenance**: Records the exact build environment, including tool versions and signatures
* **RPM-Native Intelligence**: Deep integration with RPM metadata, spec files, and package signatures
* **Reproducible Build Context**: Complete build environment fingerprinting for reproducibility verification

Available since version 6.1.
12 changes: 11 additions & 1 deletion mock/py/mockbuild/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
'lvm_root', 'compress_logs', 'sign', 'pm_request',
'hw_info', 'procenv', 'showrc', 'rpkg_preprocessor',
'rpmautospec', 'buildroot_lock', 'export_buildroot_image',
'unbreq']
'sbom_generator', 'unbreq']

def nspawn_supported():
"""Detect some situations where the systemd-nspawn chroot code won't work"""
Expand Down Expand Up @@ -254,6 +254,16 @@ def setup_default_config_opts():
},
'export_buildroot_image_enable': False,
'export_buildroot_image_opts': {},
'sbom_generator_enable': False,
'sbom_generator_opts': {
'generate_sbom': True,
'include_file_components': True,
'include_file_dependencies': False,
'include_debug_files': False,
'include_man_pages': True,
'include_source_dependencies': True,
'include_toolchain_dependencies': False,
},
'unbreq_enable': False,
'unbreq_opts': {
'exclude_accessed_files': []
Expand Down
Loading
Loading