Safeguard
Developer Tools•

Run the Safeguard CLI in GitLab CI and keep the results

A GitLab CI job that installs the Safeguard CLI, scans the repository and saves the output as job artifacts, with notes on retention and exit codes.

Safeguard Security Team
4 min read

In GitLab CI, add a job that installs curl and the Safeguard CLI, runs safeguard scan on the working directory with an output folder, and saves that folder with artifacts paths. The scan exits zero when it ran, so the job will not fail on findings by itself.

The job

Safeguard's CI/CD documentation describes a job called safeguard-scan in the test stage, on an Ubuntu 24.04 image. It installs curl, installs the CLI, runs scan on the current directory and stores the results folder as an artifact. A version of that, with the pinning you should add:

safeguard-scan:
  stage: test
  image: ubuntu:24.04
  variables:
    SAFEGUARD_VERSION: "<version from the download page>"
  before_script:
    - apt-get update && apt-get install -y curl ca-certificates
    - curl -fsSL https://cli.safeguard.sh/install | bash
  script:
    - safeguard scan --dir . --output safeguard-results
  artifacts:
    when: always
    expire_in: 2 weeks
    paths:
      - safeguard-results/

The output folder holds the SBOM and per component result files such as vuln.json and license.json, according to the CLI documentation.

The scanner prerequisite

The documentation says safeguard scan runs syft and grype, and a fresh CI runner does not have them. Install both onto the PATH before the scan step, or point the TOOLS_DIR variable at a folder that contains them. If your scan step errors out about missing scanners, this is the first place to look. It also exits with code 2 in the case where results were written but the vulnerability scan did not run, so do not ignore a 2.

Retention and when artifacts upload

GitLab's artifacts keywords matter here. The expire_in keyword sets how long artifacts are kept and overrides the instance default, which can differ on GitLab.com. The documentation page on report artifacts also notes that artifacts under a reports key upload whether or not the job succeeded. For plain paths artifacts, set when to always if you want results from failed jobs. That is how you keep evidence from a run that broke for another reason.

Who can see the output

Job artifacts are visible to people with access to the pipeline. The SBOM lists every dependency you ship, so treat it as internal. Shorten the expiry if you do not need the history, or keep long term copies in the platform instead.

Gating

The CLI does not fail the job on severity. Use platform policy gates, or read the vuln.json file yourself in a later step. The pattern is in the gate post.

Making the job optional at first

When you add a new scanner job, set allow_failure on it for the first week or two. That lets the team see output without a red pipeline blocking unrelated work. Remove the setting once the noise is understood. Remember that the CLI does not fail on findings anyway, so the only red you will see early is from setup problems such as a missing tool, which is useful to surface.

Use rules to limit the job to merge requests and the default branch, so it does not run on every push to every feature branch.

Quick check

Which GitLab keyword saves the scan folder?

The artifacts keyword with paths listing the output folder. Add expire_in to control retention.

Does a failed scan fail the pipeline?

Only if the command itself fails. Exit code 1 means the command failed, and 2 means results were written but the vulnerability scan did not run.

Where Safeguard fits

If you connect the GitLab project as an integration, the platform scans it and evaluates policies without any CI job. The job above is for teams that want results inside the pipeline as well.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.