How to Generate an SBOM for CRA Compliance

The EU Cyber Resilience Act requires manufacturers to create and maintain a Software Bill of Materials (SBOM) for every product with digital elements. If you have never generated an SBOM before, this guide walks you through the process step by step.

What Is an SBOM?

A Software Bill of Materials is a machine-readable inventory of every software component in your product. This includes your own code, third-party libraries, open source dependencies, and transitive dependencies — the dependencies of your dependencies.

Think of it as a nutrition label for software. Just as a food label lists every ingredient, an SBOM lists every software component, its version, and where it came from.

The CRA requires SBOMs to be in a commonly used, machine-readable format. The two accepted standards are CycloneDX and SPDX.

CycloneDX vs. SPDX: Which Format Should You Use?

CycloneDX is maintained by OWASP and designed specifically for security use cases. It has first-class support for vulnerability information (VEX), dependency graphs, and security advisories. If your primary goal is CRA compliance and vulnerability management, CycloneDX is the better choice.

SPDX is maintained by the Linux Foundation and is an ISO/IEC standard (ISO/IEC 5962:2021). It has broader scope covering licensing, provenance, and supply chain metadata. If you also need to track license compliance alongside security, SPDX covers both.

For CRA compliance specifically, we recommend CycloneDX JSON as the default choice. It is easier to parse, better supported by security tools, and more compact.

Method 1: Generate SBOM from a Package Manager Lock File

This is the most reliable method. Lock files contain the exact resolved dependency tree, including transitive dependencies with pinned versions.

Node.js (package-lock.json or yarn.lock): npx @cyclonedx/cyclonedx-npm --output-file sbom.cdx.json

Python (requirements.txt, poetry.lock, or pipenv): cyclonedx-py requirements -o sbom.cdx.json

Go (go.mod and go.sum): syft dir:. -o cyclonedx-json=sbom.cdx.json

Rust (Cargo.lock): syft dir:. -o cyclonedx-json=sbom.cdx.json

Java/Maven (pom.xml): mvn org.cyclonedx:cyclonedx-maven-plugin:makeAggregateBom

Method 2: Generate SBOM from a Container Image

If you ship container images, generate the SBOM from the final built image rather than from source code. This captures everything actually shipped, including OS packages.

Using Syft: syft your-image:latest -o cyclonedx-json=sbom.cdx.json

Using Trivy: trivy image your-image:latest --format cyclonedx --output sbom.cdx.json

This approach is especially valuable because it catches components that source-level analysis might miss, such as system libraries installed via apt or apk.

Method 3: Generate SBOM from Source Directory

If you do not have lock files or container images, you can scan a source directory. This is less precise but still useful as a starting point.

Using Syft: syft dir:/path/to/project -o cyclonedx-json=sbom.cdx.json

Syft will attempt to identify package manifests, lock files, and binary artifacts in the directory.

What Should Your SBOM Include?

At minimum, each component entry should have:

  • A name (the package or library name)

  • A version (the exact version used)

  • A Package URL or purl (a standardized identifier like pkg:npm/express@4.18.2)

  • A type (library, framework, application, or operating-system)

  • A license (the declared license, ideally using SPDX license identifiers)

The more metadata you include, the more useful the SBOM is for vulnerability matching and compliance assessment.

Automating SBOM Generation

An SBOM is only useful if it stays current. Generate it automatically as part of your CI/CD pipeline so that every release has an up-to-date SBOM.

In GitHub Actions, add a step after your build: run Syft or CycloneDX against the build output and upload the SBOM as a build artifact. You can also combine this with cra-scanner to automatically assess CRA readiness on every pull request.

Validating Your SBOM

After generating an SBOM, validate that it is well-formed and useful. Check that:

  • The component count is reasonable (not zero, not suspiciously low)

  • Versions are present for all components (not empty strings)

  • The format parses correctly (use cyclonedx-cli validate for CycloneDX)

  • Package URLs are present for as many components as possible

You can use cra-scanner to assess your SBOM quality as part of an overall CRA readiness check.

Next Steps

Once you have an SBOM, you can match its components against vulnerability databases (NVD, OSV.dev, CISA KEV) to identify known vulnerabilities, track your CRA readiness score over time, and generate ENISA reports when actively exploited vulnerabilities are discovered.

For a complete preparation plan, see our CRA compliance checklist.

Complaro automates this entire workflow — from SBOM analysis to vulnerability intelligence to ENISA reporting. Join the waitlist to get started.