Docs / MMCRA Toolkit / Generate a CycloneDX SBOM

Generate a CycloneDX SBOM

Generate a CycloneDX SBOM

The SBOM (Software Bill of Materials) is a machine-readable inventory of every dependency that ships with your plugin. The EU Cyber Resilience Act Annex II makes it mandatory. MM CRA Toolkit produces CycloneDX 1.6 JSON — the format ENISA references most often.

Two flows

The SBOM page has two ways to build an SBOM:

  1. Installed plugin — pick from a dropdown of every WordPress plugin on this site. The toolkit reads wp-content/plugins/<slug>/composer.lock and wp-content/plugins/<slug>/package-lock.json and emits a CycloneDX document. Use this for plugins you publish from this WordPress install.
  1. Uploaded zip (Advanced, collapsed by default) — drag any plugin zip onto the form. The toolkit unzips it to a scratch directory, runs the same scan, then deletes the scratch dir. Use this for auditing third-party plugins or building SBOMs for plugins you don't publish from this site.

What gets included

Each SBOM lists:

  • Root component — your plugin itself, with pkg:wordpress-plugin/<slug>@<version> purl
  • Composer dependencies — every entry in packages and packages-dev from composer.lock. Dev dependencies are tagged with a cdx:composer:scope=dev property
  • npm dependencies — every entry in package-lock.json (both lockfile v1 and v2/3 layouts), with cdx:npm:scope=dev for devDependencies
  • License info — SPDX-canonical when recognizable, otherwise the raw name string
  • Supplier metadata — your company identity from Settings
  • Generator — MasseyMedia / MM CRA Toolkit with version
  • License fingerprint — embedded in metadata.properties as mmcra:license-fingerprint for traceability

Output

SBOM files write to wp-content/uploads/mmcra/sboms/<slug>-YYYYMMDD-HHMMSS.cdx.json. The directory has a .htaccess that denies direct web access — files only serve through the toolkit's signed admin download handler.

Every SBOM logs an entry in the audit log with the SHA-256 hash of the JSON content. That hash is your evidence of when the SBOM was generated and what was in it.

Component count

The success banner shows how many components were found. Zero components is normal for plugins with no composer.lock or package-lock.json — the SBOM still ships with just the root component and is a valid CycloneDX document. The Vulnerability Check page can run against an empty-components SBOM, it just won't find anything.

License-gated

SBOM generation requires an active license (or a license within the 14-day grace window). If your license has lapsed and grace has expired, the page surfaces a "License required" error. See License activation.

Watermark traceability

Every SBOM has a mmcra:license-fingerprint property in its metadata. This is the first 16 hex characters of sha256(license_key + '|' + lowercased_home_url). If your SBOM ends up on a pirated-plugin mirror, the fingerprint maps deterministically back to your license.

Re-generating

SBOMs are timestamped, not overwritten. Generate a new one any time — the Dashboard compliance grid always shows the most recent. Old SBOMs stay in the uploads directory as historical evidence of what shipped at what time.