CRA Desk
Every generate step

Generating an SBOM for PHP (Composer)

The step below writes a CycloneDX JSON file in your own pipeline. The CRA Desk scan reads that file and turns it into a readiness report - it never generates one for you.

Run in CI:

composer require --dev cyclonedx/cyclonedx-php-composer
composer CycloneDX:make-sbom --output-format=JSON --output-file=sbom.json
Produces:
sbom.json
Format:
CycloneDX JSON
Generator documentation

The whole CI job

GitHub Actions

- uses: actions/checkout@v4
- run: composer require --dev cyclonedx/cyclonedx-php-composer
- run: composer CycloneDX:make-sbom --output-format=JSON --output-file=sbom.json
- uses: mmalinowski/cradesk-action@v1
  with:
    sbom-path: sbom.json

GitLab CI/CD

generate-sbom:
  script:
    - composer require --dev cyclonedx/cyclonedx-php-composer
    - composer CycloneDX:make-sbom --output-format=JSON --output-file=sbom.json

include:
  - component: gitlab.com/cradesk/scan/readiness@1
    inputs:
      sbom_path: sbom.json

Only the first step changes with your stack - the CRA Desk step after it is identical everywhere.

What goes wrong here

Without --output-format=JSON the plugin writes XML, which the scan detects and refuses rather than mis-parsing. Add --omit=dev to leave development packages out.

What CRA Desk does with the result

Components from this build carry pkg:composer package URLs, which the watch matches against OSV's Packagist advisories when the SBOM arrives and again as new advisories land. Matching runs on every plan; e-mail alerts and the full match list are what a paid plan adds.

A generator that runs is not the same as coverage. Components with no purl, no version, or from an ecosystem outside the nine we watch are counted as gaps in every report rather than reported as clean.