R-TF-030-002 Software Bills Of Materials
Purpose
This document describes the Software Bill of Materials (SBOM) generation process for the device. It provides a complete inventory of all software components, libraries, and dependencies that comprise the deployed software, enabling transparency, traceability, and vulnerability management throughout the product lifecycle.
Scope
This document covers:
- The SBOM generation methodology and tooling
- The format and content of generated SBOM artifacts
- Component identification and classification
- Storage and accessibility of SBOM records
- Traceability mechanisms for regulatory compliance
Reference Documents
Regulatory and Standard References
| Reference | Title |
|---|---|
| IEC 81001-5-1:2021 | Health software and health IT systems safety, effectiveness and security — Part 5-1: Security — Activities in the product life cycle |
| FDA Guidance | Cybersecurity in Medical Devices: Quality System Considerations and Content of Premarket Submissions (2023) |
| EU MDR 2017/745 | Regulation on medical devices, Annex I Section 17.2 (Software requirements) |
| NTIA | The Minimum Elements For a Software Bill of Materials (SBOM) |
| CISA | Software Bill of Materials (SBOM) Sharing Lifecycle Report |
Terms and Definitions
| Term | Definition |
|---|---|
| SBOM | Software Bill of Materials — a formal, machine-readable inventory of software components and dependencies |
| CycloneDX | An open standard for SBOM developed by OWASP, designed for use in application security and supply chain analysis |
| PURL | Package URL — a standardized format for identifying software packages across ecosystems |
| CPE | Common Platform Enumeration — a standardized method of naming software applications, operating systems, and hardware |
| OCI | Open Container Initiative — specifications for container image formats and runtime |
| Syft | An open-source tool by Anchore for generating SBOMs from container images and filesystems |
SBOM Format Specification
CycloneDX 1.6
All SBOMs are generated in CycloneDX 1.6 JSON format, an OWASP standard specifically designed for software supply chain security. This format was selected for the following reasons:
- Regulatory Alignment: CycloneDX is explicitly referenced in FDA cybersecurity guidance as an acceptable SBOM format
- Machine Readability: JSON format enables automated processing and integration with vulnerability databases
- Comprehensive Schema: Version 1.6 supports detailed component metadata including licensing, provenance, and cryptographic hashes
- Tooling Ecosystem: Broad support across security scanning tools, CI/CD pipelines, and regulatory submission platforms
Schema Compliance
Generated SBOMs conform to the official CycloneDX 1.6 JSON schema:
http://cyclonedx.org/schema/bom-1.6.schema.json
Each SBOM includes:
- Serial Number: Unique UUID for the SBOM instance
- Metadata: Generation timestamp, tool information, and subject component details
- Components Array: Complete inventory of all discovered software components
Generation Tool
Syft
SBOM generation is performed using Syft, an open-source SBOM generator maintained by Anchore. Syft is a widely adopted tool in the software supply chain security ecosystem, used by organizations including the U.S. Department of Defense and major cloud providers.
| Attribute | Value |
|---|---|
| Tool Name | Syft |
| Vendor | Anchore, Inc. |
| License | Apache License 2.0 |
| Version Used | 1.40.1 |
| Repository | https://github.com/anchore/syft |
Catalogers
Syft employs multiple catalogers to discover components across different package ecosystems:
| Cataloger | Description | Component Types Discovered |
|---|---|---|
dpkg-db-cataloger | Scans Debian package database | Operating system packages (.deb) |
python-installed-package-cataloger | Scans Python site-packages | Python libraries and dependencies |
pe-binary-package-cataloger | Scans PE binary metadata | Windows executables and DLLs |
go-module-binary-cataloger | Scans Go binaries | Go modules compiled into binaries |
file-metadata-cataloger | Extracts file-level metadata | Configuration files, scripts |
Generation Methodology
Container Image Scanning
SBOMs are generated by scanning the deployed container images rather than source code. This approach captures the complete runtime software stack as it exists in the production environment, including:
- Base Image Components: Operating system packages from the container base image
- Language Runtime: Python interpreter and standard library
- Application Dependencies: All Python packages installed via uv/pip
- Build Artifacts: Compiled binaries and bundled resources
This methodology ensures the SBOM accurately reflects what is deployed, not merely what is declared in dependency manifests.
Execution Process
The generation process is executed using an automated tool that:
- Discovers Targets: Reads the service registry (
services.yaml) to identify all microservices - Scans Container Images: Executes Syft against each container image on the build infrastructure
- Generates Artifacts: Produces individual SBOM JSON files for each service
- Creates Metadata: Generates cumulative tracking metadata with run history
- Produces Summary Report: Creates an HTML summary for human review
- Uploads to Storage: Stores all artifacts in centralized S3 storage
Command Reference
The following command generates SBOMs for all device services:
uv run sbom scan --scan-mode container --upload
| Parameter | Description |
|---|---|
--scan-mode container | Scan container images (vs. source directories) |
--upload | Upload artifacts to S3 after generation |
--version | Software version being documented (inferred from context) |
Component Identification
Package URL (PURL)
Each component is identified using a Package URL (PURL), a standardized format that uniquely identifies software packages across different ecosystems. PURLs follow the format:
pkg:<type>/<namespace>/<name>@<version>?<qualifiers>#<subpath>
Examples from the device SBOMs:
| Component | PURL |
|---|---|
| FastAPI (Python) | pkg:pypi/fastapi@0.119.1 |
| NumPy (Python) | pkg:pypi/numpy@2.2.2 |
| OpenSSL (Debian) | pkg:deb/debian/openssl@3.0.15-1~deb12u1?arch=amd64&distro=debian-12 |
| libcurl (Debian) | pkg:deb/debian/libcurl4@7.88.1-10+deb12u8?arch=amd64&distro=debian-12 |
Common Platform Enumeration (CPE)
Components also include CPE identifiers where applicable, enabling correlation with vulnerability databases such as the National Vulnerability Database (NVD). CPE format:
cpe:2.3:<part>:<vendor>:<product>:<version>:<update>:<edition>:<language>:<sw_edition>:<target_sw>:<target_hw>:<other>
Example:
cpe:2.3:a:fastapi:fastapi:0.119.1:*:*:*:*:*:*:*
Component Metadata
Each component entry includes:
| Field | Description | Example |
|---|---|---|
bom-ref | Unique reference within the SBOM | pkg:pypi/fastapi@0.119.1 |
type | Component classification | library, application, framework |
name | Package name | fastapi |
version | Exact version string | 0.119.1 |
purl | Package URL | pkg:pypi/fastapi@0.119.1 |
cpe | CPE identifier | cpe:2.3:a:fastapi:fastapi:0.119.1:*:*:*:*:*:*:* |
licenses | License information | [{"license": {"id": "MIT"}}] |
properties | Extended metadata | Cataloger source, file locations, layer IDs |
Component Categories
The device software stack comprises components from multiple ecosystems. The following categories are captured in the SBOMs:
Operating System Packages
Debian packages from the base container image, including:
- Core Libraries: glibc, openssl, libcurl, zlib
- System Utilities: coreutils, bash, adduser
- Security Components: ca-certificates, gnupg
These components are identified by the dpkg-db-cataloger and have PURLs of type pkg:deb/debian/.
Python Packages
Application dependencies managed by pip/uv, including:
- Web Framework: FastAPI, Starlette, Uvicorn
- Data Processing: NumPy, Pandas, Pillow
- ML/AI Libraries: PyTorch, TensorFlow, ONNX Runtime
- AWS Integration: boto3, aioboto3
- Validation: Pydantic
These components are identified by the python-installed-package-cataloger and have PURLs of type pkg:pypi/.
Binary Artifacts
Compiled executables and libraries discovered through binary analysis:
- Python Interpreters: CPython runtime
- Native Extensions: Compiled C/C++ extensions for Python packages
- Utility Binaries: pip vendor utilities, build tools
Generated Artifacts
Per-Service SBOM Files
For each microservice, a JSON SBOM file is generated with the naming convention:
sbom_{timestamp}_{git_commit_short}.json
Example: sbom_2026-01-26_10-48-04_a1a904d.json
The filename encodes:
- Timestamp: UTC date and time of generation run
- Git Commit: Short hash of the source code version
SBOM Structure
Each SBOM file contains:
{
"$schema": "http://cyclonedx.org/schema/bom-1.6.schema.json",
"bomFormat": "CycloneDX",
"specVersion": "1.6",
"serialNumber": "urn:uuid:...",
"version": 1,
"metadata": {
"timestamp": "2026-01-26T10:55:00Z",
"tools": {
"components": [
{
"type": "application",
"author": "anchore",
"name": "syft",
"version": "1.40.1"
}
]
},
"component": {
"type": "container",
"name": "service-name",
"version": "sha256:..."
}
},
"components": [
// Array of all discovered components
]
}
Cumulative Metadata File
A metadata.json file tracks the generation history across all services:
{
"last_updated": "2026-01-26T10:55:00+00:00",
"version": "1.1.0.0",
"sbom_format": "CycloneDX",
"sbom_spec_version": "1.6",
"scanner_tool": "Syft",
"scanner_version": "1.40.1",
"python_version": "3.12.8",
"total_services": 60,
"services": {
"api-gateway": {
"name": "api-gateway",
"last_generated": "2026-01-26T10:55:00+00:00",
"total_runs": 1,
"successful_runs": 1,
"failed_runs": 0,
"runs": [
{
"target_type": "container",
"timestamp": "2026-01-26T10:55:00+00:00",
"git_commit": "a1a904d...",
"git_branch": "main",
"sbom_file": "sbom_2026-01-26_10-48-04_a1a904d.json",
"component_count": 487,
"duration_seconds": 45.2,
"success": true,
"error": null
}
]
}
}
}
HTML Summary Report
A human-readable summary.html report provides:
- Overall generation status and statistics
- Per-service status with component counts
- Links to individual SBOM files
- Generation metadata (tool version, timestamp, git commit)
Storage Location
S3 Artifact Repository
All SBOM artifacts are stored in Amazon S3 with the following structure:
s3://legit-health-plus/software-sbom/
└── 1.1.0.0/
├── metadata.json
├── summary.html
└── reports/
├── api-gateway/
│ └── sbom_2026-01-26_10-48-04_a1a904d.json
├── control-plane/
│ └── sbom_2026-01-26_10-48-04_a1a904d.json
└── ... (60 service directories)
Retention
SBOM artifacts are retained for the lifetime of the product version plus the post-market surveillance period, in accordance with regulatory record-keeping requirements.
Traceability
Generation Traceability
Every SBOM generation run is traceable through the following attributes recorded in the metadata:
| Attribute | Description | Example |
|---|---|---|
| Version | Software release version | 1.1.0.0 |
| Timestamp | UTC time of generation | 2026-01-26T10:55:00+00:00 |
| Git Commit | Full SHA of source code | a1a904d567890... |
| Git Branch | Source branch | main |
| Scanner Tool | SBOM generation tool | Syft |
| Scanner Version | Tool version | 1.40.1 |
| Target Type | What was scanned | container |
Reproducibility
SBOM generation can be reproduced by:
- Checking out the specific git commit from the source repository
- Building the container images using the same build configuration
- Running the SBOM generation tool with identical parameters
The resulting SBOMs will contain the same components (modulo any non-determinism in container layer ordering).
Standards Compliance
NTIA Minimum Elements
The generated SBOMs satisfy all NTIA minimum elements for SBOM:
| NTIA Element | Compliance | Implementation |
|---|---|---|
| Supplier Name | ✓ | Included in component metadata where available |
| Component Name | ✓ | name field in each component |
| Version | ✓ | version field in each component |
| Unique Identifier | ✓ | PURL and/or CPE for each component |
| Dependency Relationship | ✓ | Implicit through inclusion in container image |
| Author of SBOM Data | ✓ | Tool information in metadata |
| Timestamp | ✓ | Generation timestamp in metadata |
CycloneDX Specification
SBOMs conform to CycloneDX 1.6 specification requirements:
- Valid JSON schema structure
- Proper
bomFormatandspecVersiondeclarations - Unique
serialNumber(UUID) per SBOM - Complete component enumeration with required fields
FDA Cybersecurity Guidance
The SBOM documentation approach aligns with FDA recommendations:
- Complete Inventory: All third-party components enumerated
- Machine-Readable Format: CycloneDX JSON for automated processing
- Version Identification: Exact versions for all components
- Update Capability: SBOMs regenerated for each release to reflect current state
SBOM Inventory
The device comprises 60 microservices, each with an independently generated SBOM. The table below consolidates the SBOM generation results for all services, providing the key metrics required for regulatory review and vulnerability management.
Column Definitions
| Column | Description |
|---|---|
| Service | Microservice identifier as defined in the deployment registry |
| Components | Total number of software components identified in the container image |
| Status | SBOM generation outcome: ✓ (success) or ✗ (failed) |
| SBOM File | Filename of the generated CycloneDX JSON artifact |
Consolidated SBOM Results
| Service name | Components | Status | SBOM File |
|---|---|---|---|
| acneiform-detector | 2,882 | ✓ | reports/acneiform-detector/sbom_2026-01-26_10-48-04_a1a904d.json |
| api-gateway | 3,545 | ✓ | reports/api-gateway/sbom_2026-01-26_10-48-04_a1a904d.json |
| awosi-classifier | 2,854 | ✓ | reports/awosi-classifier/sbom_2026-01-26_10-48-04_a1a904d.json |
| body-surface-segmenter | 2,854 | ✓ | reports/body-surface-segmenter/sbom_2026-01-26_10-48-04_a1a904d.json |
| condition-classifier | 2,947 | ✓ | reports/condition-classifier/sbom_2026-01-26_10-48-04_a1a904d.json |
| control-plane | 3,469 |