Skip to main content
Plans: Every plan. Who: an owner or admin creates the API token; a project maintainer adds the CI/CD variable and the job.
This job runs when you push a Git tag. It installs Syft, generates a CycloneDX JSON SBOM of the repository and sends it to Pharus, with the tag as the product version.

Before you start

1

Create a token

In Pharus, go to Settings → API tokens and create a token for the product family. See create a token.
2

Store it as a CI/CD variable

In GitLab, open the project’s Settings → CI/CD → Variables and add a variable with the key PHARUS_TOKEN and the token as its value. Mask it, so it doesn’t show in job logs.
If you also mark the variable as protected, GitLab only passes it to pipelines on protected branches and tags. Protect the tags the job runs on, or leave the variable unprotected.

The job

Add this job to .gitlab-ci.yml:
What it does:
  • Trigger: rules: - if: $CI_COMMIT_TAG runs the job only in pipelines for a Git tag.
  • Generate: the job installs curl and Syft in a small Alpine image, and Syft writes sbom.cdx.json from the repository.
  • Version: the tag, such as v4.2, becomes the product version in Pharus.
  • Send: the last command gzips the file and posts it to POST /api/v1/sboms. The X-Pharus-* headers fill in the Pipeline card on the SBOM’s page, with a link to the job.
  • Fail loudly: --fail-with-body fails the job on any error and prints Pharus’ message in the log.
The job uses the deploy stage, one of GitLab’s default stages. If your .gitlab-ci.yml lists its own stages, use one of those.
Pharus has no source label for GitLab, so these SBOMs show API as their Source. The Pipeline card still links to the GitLab job.

Variations

Use syft dir:. -o spdx-json=sbom.spdx.json and gzip sbom.spdx.json in the last command. Pharus reads SPDX JSON 2.2 and 2.3.
Replace dir:. with the image reference, for example registry.gitlab.com/acme/gateway-g3:4.2. For a private registry, give Syft credentials as Syft’s documentation describes.
Use rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH, and send your release version in X-Pharus-Version in place of $CI_COMMIT_TAG. Without a version, Pharus uses the version inside the SBOM, if it has one.

Check that it worked

The job log shows Pharus’ answer, with "status":"parsed" for a new SBOM and "duplicate":true when Pharus already had the file. In Pharus, the SBOM appears under SBOMs, and the token’s Last used time changes under Settings → API tokens. All codes are listed under errors.

Upload an SBOM

API introduction

GitHub Actions

Azure Pipelines