7.21. SBOM architecture
Up: 7. Developer guide
Prev: 7.20. Resource management
Next: 7.22. File handling
Sections:
- Overview
- Current status
- The SBOM package
- The SBOM CLI
- Package modules
- External tools
- How the server uses the package
- The SBOM report
- Related documentation
Overview
This page describes how ATR's SBOM support is put together, for developers working on ATR itself. For a release manager's view of what the SBOM features do and how to use them, see SBOM workflows.
ATR works with SBOMs in the CycloneDX format, stored as .cdx.json files (and other suffixes) that sit beside the artifact they describe. A project-supplied SBOM is always preferred. Most of the SBOM logic lives in its own package, atr/sbom/, which the ATR server drives through a set of background tasks. Only the read-only report is currently exposed in the UI; see Current status.
Current status
Only the read-only SBOM report is currently reachable from the UI. A file that is a CycloneDX JSON SBOM gets a View SBOM button in a release's checks (atr/get/checks.py), which opens the report described below.
The other workflows, generation, conversion, OSV scanning, and augmentation, are present in the code, as task handlers in atr/tasks/sbom.py and as routes in atr/post/draft.py and atr/post/sbom.py, but nothing in the UI triggers them, so they are dormant. The intention is to build these into external tooling rather than the server, which is what the package's own command line (below) is a step toward. The rest of this page describes the whole toolkit, dormant paths included, since the code is all present.
The SBOM package
atr/sbom/ is its own package with its own command line, so the SBOM operations can be driven directly, not only through the server. The standalone entry point is python -m atr.sbom (__main__.py just calls cli.main()), and cli.py's setup_cli_logging wires the shared logging up to stderr, so a bare CLI run produces the same diagnostics as the in-server code.
That standalone use is why part of the package reads differently from the rest of the codebase. The modules on the CLI path refer to each other with relative, direct-name imports, for example from .cyclonedx import validate_cli, rather than the absolute, module-only style, import atr.x as x, that ATR uses everywhere else. The package also holds some server-only modules (heatmap, observations, streaming, and maintenance, used by the SBOM tasks and the catalog site, not by the CLI). Those keep ATR's ordinary house style, since the standalone rationale does not apply to them.
The package is not fully decoupled from ATR, though. Its core imports atr.util (in utilities.py and osv.py) alongside atr.log and atr.loggers, and its heatmap and observations modules also pull in atr.metadata and atr.models.results. It is standalone in the sense of having a working command line, not in the sense of having no ATR dependencies.
The SBOM CLI
cli.py is the standalone command line. It takes a command and an SBOM path:
python -m atr.sbom <command> <sbom-path>
The commands map onto the package's operations:
license- list the license warnings (Category B) and errors (Category X).missingandwhere- list, and locate within the document, the NTIA 2021 fields an SBOM is missing.osv- scan the components against OSV.outdated- report an SBOM written by a known-outdated tool.patch-ntiaandpatch-vuln- emit the JSON patch that would add the missing NTIA metadata, or the OSV findings.merge- apply the NTIA patch and print the resulting document.scores- print the sbomqs score, before and after an NTIA merge.validate-cliandvalidate-py- validate the document, through the CycloneDX CLI and through the CycloneDX Python library respectively.
Package modules
Each command is a thin wrapper over a module that does the work, and the ATR server calls those same modules directly:
cyclonedx.pyvalidates a document two ways:validate_clishells out to the externalcyclonedxbinary, andvalidate_pyuses the CycloneDX Python library.conformance.pychecks a document against the NTIA 2021 minimum data fields.licenses.pyplaces each declared license into an ASF policy category.sbomqs.pyruns the sbomqs scorer.osv.pylooks components up in OSV.tool.pydetects an SBOM written by an outdated tool version.utilities.pyloads a file into aBundle, builds the NTIA and vulnerability patches, applies them, and writes documents back out.components.pyreads a document into the component breakdown the report renders.models/holds the typed models the rest of the package passes around, includingbundle,conformance,licenses, andcomponents.
The package also carries maven.py, which maps a date to the Maven plugin version current at that time, spdx.py, an SPDX license-expression parser, and a constants subpackage.
External tools
The package, and the tasks around it, drive several external tools:
- syft generates a CycloneDX SBOM from an artifact. This runs in the task layer (
atr/tasks/sbom.py) under the sandbox, not in the package. Generation is currently dormant (see Current status). - the CycloneDX CLI (
cyclonedx) validates documents, throughcyclonedx.py'svalidate_cli. - sbomqs scores documents, through
sbomqs.py. - OSV supplies vulnerability data, through
osv.py.
The CycloneDX Python library is a direct dependency too, used for validation and for writing documents out.
How the server uses the package
The ATR server wraps the package's operations as background tasks:
atr/tasks/sbom.pyholds the task handlers. It runs syft for generation, and calls intoatr/sbom/for conversion, scoring, scanning, and augmentation. The task types includeSBOM_GENERATE_CYCLONEDX,SBOM_CONVERT,SBOM_TOOL_SCORE,SBOM_QS_SCORE,SBOM_OSV_SCAN, andSBOM_AUGMENT.atr/storage/writers/sbom.pyqueues those tasks as the acting committee member.atr/post/draft.pyholds the generation and conversion routes (each would land its output as a new revision), andatr/post/sbom.pyholds the report's scan and augment routes. None of these is currently triggered from the UI (see Current status).atr/analysis.pyclassifies files, withis_cyclonedx_jsonandis_cyclonedx_xmlgating which operations apply to a given file.
The SBOM report
atr/get/sbom.py builds the report programmatically with atr/htm.py rather than a template. The quality handler serves /sbom/quality/<project>/<version>/<file> and is reached from a file's check row (see atr/get/checks.py and check-selected-path-table.html).
The page reads the most recent SBOM_TOOL_SCORE task for the file at the release's latest revision, and reads the component breakdown straight from the SBOM through atr/sbom/components.py. It deliberately does not render a single headline score: it surfaces the component list, license categories, declared vulnerabilities, and the conformance, outdated-tool, and CycloneDX CLI findings, so a reader sees the underlying issues rather than a number.
Related documentation
- SBOM workflows is the user-facing counterpart to this page.
- Tasks explains the background task system these operations run on.
- Checks covers the wider check pipeline the SBOM report is reached from.