CyberMed
← Back to resources

SBOM Generation for Medical Device Software: Practical Setup by Stack

2026-03-04CyberMed

Practical SBOM generation instructions across common software stacks, from embedded C/C++ to cloud containers, with validation and quality gates for FDA submission.

Preparing the Software Bill of Materials (SBOM) for Medical Devices

At CyberMed, we help teams prepare their full cybersecurity package for submission, but one file we don't directly generate is the SBOM.

That's intentional. Your SBOM should be generated inside your regular build cycle so it captures exact dependency data from the repository and release artifact, not a manually reconstructed snapshot.

Preparing the Software Bill of Materials (SBOM) for Medical Devices

This tutorial gives practical SBOM generation instructions across common software stacks. If your team uses a different language, framework, or toolchain, reach out and we can help you map an SBOM process to your environment.

Purpose and scope

This guide covers SBOM generation for:

  • Embedded software
  • Mobile apps
  • Cloud and SaMD workloads
  • Common backend ecosystems

Regulatory objective is to maintain a machine-readable software inventory (CycloneDX or SPDX) that supports FDA premarket cybersecurity documentation expectations for cyber devices and supports IEC 62304 SOUP control evidence used in EU MDR technical documentation.

General operating rules

  1. Automate at build time

    • Generate SBOMs in the CI/CD Build phase so artifacts reflect exact release versions.
  2. Generate a release SBOM from production/runtime dependencies

    • For submission and released-product evidence, exclude dev/test-only packages.
    • Keep a separate internal build/toolchain SBOM when needed for supply-chain investigations.
  3. Include SOUP explicitly

    • Third-party and proprietary components outside package managers still need declaration.
  4. Use immutable inputs

    • Build from lockfiles, pinned tool versions, and immutable image digests.

Toolchain setup by ecosystem

A) Embedded systems (C/C++)

Embedded projects often lack complete package-manager metadata. Filesystem scanning is one input, not the whole picture.

Use a combined method:

  • build-system manifests (CMake/Conan/vcpkg/Yocto/Bazel, as applicable),
  • source and filesystem scan,
  • binary or artifact scan,
  • manual SOUP declaration for vendor/toolchain components.

Tool: cdxgen (OWASP)

npm install -g @cyclonedx/cdxgen@<pinned-version>
# Scan source and include submodules/SDKs
cdxgen -t c -o sbom.json --recurse

B) Rust (safety-critical SaMD)

Rust lockfiles are a good fit for deterministic dependency capture.

Tool: cargo-cyclonedx

cargo install cargo-cyclonedx --version <pinned-version>
# Generate for all workspace members from lockfile-resolved dependencies
cargo cyclonedx --all --format json --output-file sbom.cdx.json

C) Node.js (web-based SaMD)

For release evidence, focus on runtime dependencies and lockfile-resolved versions.

Tool: @cyclonedx/cyclonedx-npm

npm install -g @cyclonedx/cyclonedx-npm@<pinned-version>
# Capture runtime dependencies
cyclonedx-npm --output-format JSON --output-file sbom.json --omit dev

If your version supports lockfile-only mode, enable it in CI.

D) Python (AI/ML components)

Prefer lockfile-driven environments so outputs are reproducible.

Tool: cyclonedx-python (cyclonedx-bom package)

pip install cyclonedx-bom==<pinned-version>
# Poetry workflow (recommended for deterministic builds)
cyclonedx-py poetry -o sbom.json

E) .NET (clinical enterprise software)

Generate at solution scope to capture cross-project dependencies.

Tool: dotnet-CycloneDX

dotnet tool install --global CycloneDX --version <pinned-version>
dotnet-CycloneDX MyMedicalApp.sln -o ./artifacts -f json

F) Mobile apps (Android and iOS)

Track platform SDK and mobile-library dependencies.

Android (Gradle CycloneDX plugin):

id 'org.cyclonedx.bom' version '1.8.1'

Run:

./gradlew cyclonedxBom

iOS (SwiftPM/CocoaPods):

  • Use resolved dependency files (Package.resolved, Podfile.lock) as the source of truth.
  • Generate from built app or archive artifacts when possible, not only raw source.
  • If using Syft, scan built output and document known detection limits.
# Example: scan built artifact, not just repo root
syft /path/to/MyApp.app -o cyclonedx-json > sbom.json

Cloud and containerized environments

For cloud/SaMD workloads in containers, include OS-layer packages, not only app-level libraries.

Tool: Syft (Anchore)

# Scan immutable release image digest (not mutable tags)
syft <image_name>@sha256:<digest> -o spdx-json > sbom.spdx.json

Post-generation controls (do not skip)

Generating an SBOM file is step one. You still need validation and governance.

  1. Validate schema and quality fields
# CycloneDX validation example
cyclonedx-cli validate --input-file sbom.json

If you emit SPDX, run SPDX-compatible validation with your selected validator as part of CI.

  1. Enforce quality gates

Require at least:

  • component name and version,
  • supplier,
  • cryptographic hashes,
  • dependency relationships,
  • identifiers (purl, and cpe where applicable).
  1. Centralize and monitor

Store SBOMs in a central system (for example, Dependency-Track) for ongoing vulnerability monitoring.

  1. Handle VEX

If a vulnerability exists in a component but is not reachable in your deployed architecture, document exploitability context in VEX.

Reference table

Environment Primary Tool Target File
C/C++ cdxgen Makefile / CMakeLists.txt
Rust cargo-cyclonedx Cargo.lock
Node.js cyclonedx-npm package-lock.json
Python cyclonedx-py poetry.lock / requirements.txt
.NET dotnet-cyclonedx .csproj / .sln
Java cyclonedx-maven pom.xml
Go cyclonedx-go go.mod

Manual and proprietary SOUP handling

When components are outside package managers (for example .lib, .dll, or vendor binaries), add them manually.

Capture at minimum:

  • Supplier (organization/legal entity)
  • Component name and version
  • Identifier (purl and/or cpe where applicable)
  • SHA-256 (or stronger) hash of shipped artifact
  • Dependency scope and usage context
  • Source/provenance reference (vendor advisory, release note, or controlled evidence)

Manual component template (manual-soup.json)

{
  "bomFormat": "CycloneDX",
  "specVersion": "1.5",
  "components": [
    {
      "bom-ref": "vendor-proprietary-algorithm-4.2.0",
      "type": "library",
      "supplier": {
        "name": "Vendor Name"
      },
      "publisher": "Vendor Name",
      "name": "Proprietary-Algorithm-Library",
      "version": "4.2.0",
      "purl": "pkg:generic/proprietary-algorithm-library@4.2.0",
      "hashes": [
        {
          "alg": "SHA-256",
          "content": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
        }
      ],
      "scope": "required",
      "externalReferences": [
        {
          "type": "website",
          "url": "https://vendor.com/docs"
        }
      ]
    }
  ]
}

Then merge manual entries into your generated SBOM using your CycloneDX toolchain for the exact CLI version pinned in CI.

Implementation sequence for medtech teams

Use this rollout order:

  1. Select canonical SBOM format(s) per release stream (CycloneDX and/or SPDX).
  2. Generate SBOMs in CI from immutable inputs (lockfiles, image digests, pinned tools).
  3. Bind SBOM artifact to release artifact/version (build ID, commit SHA, provenance record).
  4. Produce release/runtime SBOM and retain internal build/toolchain SBOM as needed.
  5. Add manual SOUP declaration workflow with explicit ownership and review.
  6. Enforce validation + quality gates + central retention/monitoring.
  7. Integrate SBOM and VEX outputs into risk management and postmarket response.

Important limits to state internally

  • An SBOM is an inventory. It doesn't prove exploitability by itself.
  • Regenerate SBOMs on every release, hotfix, and critical dependency change.
  • Normalize identifiers consistently (purl first, cpe where high-confidence).

Final takeaway

Keep SBOM generation operational and traceable.

If your team can show how SBOM artifacts map to release versions, vulnerability review, and risk decisions, reviewers can move through your package faster and postmarket response becomes easier to defend.

Need help with your full cybersecurity submission package? See how CyberSprint works →