Safeguard
Developer Tools•

The Safeguard CLI never fails a build: how to gate on findings

The Safeguard CLI exits zero when a scan runs, whatever it finds. Two documented ways to block a merge: a platform policy gate, or a check you write.

Safeguard Security Team
3 min read

The Safeguard CLI does not fail a build on findings. A scan that ran exits zero whether it found nothing or fifty critical issues. To block a merge you have two documented options: let a platform policy gate decide, or add your own check on the result file in the next pipeline step.

Why it works this way

The CI/CD documentation is direct about it. The CLI has no severity threshold flag, and enforcement happens through platform policy gates. The CLI documentation repeats that policies and gates are evaluated in the platform, not in the CLI.

That separates two jobs. The CLI produces evidence. The policy decides what the evidence means for your organisation. One set of rules then applies the same way in the IDE, the web app and the pipeline, instead of living in a flag in each YAML file.

Option 1: a platform policy gate

Connect the repository as an integration. The platform scans it and evaluates your policies and gates, and nothing has to run in the pipeline. This is the route the documentation recommends first. The gate result is what you require on the pull request in your source host's branch protection settings.

Option 2: your own check

If you scan in the pipeline and want the job itself to go red, read the output. The CLI site shows a GitHub Actions step that does exactly this, using jq on the vulnerability file:

- name: Scan the working tree
  run: safeguard scan --dir . --output out/

- name: Gate the build
  run: |
    jq -e '[.data.matches[].vulnerability.severity | ascii_downcase] | index("critical") | not' out/*/vuln.json

The jq expression exits non-zero when a critical severity appears. The page says the vulnerability file is grype compatible under the data matches path. Test the expression against your own output before trusting it, because a typo can turn a gate into a no-op.

Decide the rule first

A gate on every critical finding will block on things nobody can fix this week. Decide the rule before you wire it. Common choices are block on critical only, block on findings with a fix available, or block only on new findings relative to the main branch. The jq line above does the first of these. The others need more logic, which is a reason to prefer a platform policy.

What about the planned dependency gate

The documentation mentions a dependency gate that checks manifests against the free Gold Open Source data and can fail on known exploited dependencies. It says the gate is built but not yet published as a GitHub Action or npm package. Do not plan around it until it ships.

A note on false confidence

A green check with a scanner's name on it reads as safe to most reviewers. If the job cannot fail on findings, name it accordingly, for example report rather than gate, so nobody mistakes evidence collection for enforcement. Then make the real gate visible as its own required check.

Quick check

Does exit code 2 mean critical findings?

No. For scan, 2 means results were written but the vulnerability scan did not run. Findings do not change the exit code.

Can I make the pipeline fail without writing jq?

Yes, by connecting the repository and using a platform policy gate as a required check.

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.