-
Notifications
You must be signed in to change notification settings - Fork 254
SBOM generator #1682
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
atomicturtle
wants to merge
26
commits into
rpm-software-management:main
Choose a base branch
from
atomicturtle:sbom_generator
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
SBOM generator #1682
Changes from all commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
ef62327
Init
atomicturtle 51ef8c3
Adding SBOM module
atomicturtle 0e6adf4
Update SBOM generator plugin to v1.2.5
atomicturtle 1994dc8
Remove legacy sbom_generator.py from root directory
atomicturtle 2f6e049
Address PR feedback: standardize imports, logging, versioning, and docs
atomicturtle 6425f70
Update license to GPL 2.0 or later
atomicturtle a851a6a
docs: Update SBOM plugin availability to 6.7
atomicturtle dad5c9f
feat: Refactor SBOM generator and add release notes
atomicturtle 0710ab2
fix: Use rpm2archive instead of rpm2cpio for source extraction
atomicturtle 9b9f662
fix: Refactor SBOM generator to use python-rpm and fix local variable…
atomicturtle 32fba57
fix: Replace shutil.rmtree with mockbuild.file_util.rmtree for safer …
atomicturtle ef8c84b
fix: Use python-distro to detect chroot distribution
atomicturtle 97f7c85
refactor: Rename _convert_to_chroot_path to from_chroot_path
atomicturtle 03c63d3
refactor: Remove redundant special-case CPE vendor/product mappings
atomicturtle 8308537
fix: Replace deprecated datetime.utcnow() with timezone-aware datetim…
atomicturtle be45f13
Lint revisions
atomicturtle 09f0448
Minor refactors
atomicturtle 77d45a6
SPDX option support
atomicturtle 110dc73
Refactor: Move from_chroot_path to Buildroot class
atomicturtle 0a1f97f
modernize metadata extraction and fix forensic grouping
atomicturtle e471951
QA fixes:
atomicturtle fee9a68
Update SBOM docs
atomicturtle e45e593
Update the Feature request
atomicturtle 58c437b
Reorganize into separate files
atomicturtle 01b4db0
Bump for build test
atomicturtle 06ccf80
Merge upstream/main from rpm-software-management/mock
atomicturtle File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,320 @@ | ||
| --- | ||
| 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) and SPDX 2.3 format | ||
| * Deep Chroot Integration: | ||
| * Uses the target distribution's own `rpm` binary via `doChroot` for metadata extraction, ensuring 100% version compatibility across different distributions. | ||
| * Correctly handles path mapping between chroot and host environments. | ||
| * Captures detailed information about: | ||
| * Source files and patches from spec files with a resilient regex-based fallback for legacy/strict syntax errors. | ||
| * Binary RPM metadata with standard PURL and CPE identifiers. | ||
| * Complete build toolchain packages with per-package GPG signature metadata. | ||
| * Runtime dependencies. | ||
| * File hashes (SHA-256). | ||
| * Optimized Performance: Consolidated file listing and metadata extraction into a single pass. | ||
| * Outputs SBOM 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 | ||
|
|
||
| ### 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 SBOM Auditor | ||
| sbom-auditor sbom.cyclonedx.json | ||
|
|
||
| # 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` (for CycloneDX) or `<name>-<version>-<release>.spdx.json` (for SPDX) in the build results directory. The SBOM includes: | ||
|
|
||
| * CycloneDX/SPDX 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/package-name@1.0-1.fc42?arch=x86_64", | ||
| "name": "package-name", | ||
| "version": "1.0-1.fc42", | ||
| "purl": "pkg:rpm/fedora/package-name@1.0-1.fc42?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/package-name@1.0-1.fc42", | ||
| "dependsOn": [ | ||
| "pkg:rpm/fedora/glibc@2.38-1.fc42" | ||
| ] | ||
| } | ||
| ] | ||
| } | ||
| ``` | ||
|
|
||
| ## 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 | ||
| * Access to build environment for package information | ||
| * Native `rpm` and `specfile` libraries (recommended) | ||
|
|
||
| ## 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. | ||
| * **Hybrid Analysis**: Uses `doChroot` to analyze artifacts within the buildroot (ensuring compatibility with target RPM versions) and host tools for artifacts already exported to the `result/` directory. | ||
| * **Resilient Parsing**: Includes a regex-based fallback for spec files that fail strict parsing by the `specfile` library (e.g., legacy `%patchN` syntax). | ||
| * **PURL format**: `pkg:rpm/{distro}/{package}@{version}?arch={arch}`. Architecture is always separated into a qualifier, never baked into the version string. | ||
| * Mock-specific metadata is stored in properties with the `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.7. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.