Skip to main content

Semgrep in CI vs CLI: align your SAST scan results and understand differences

When configuring Semgrep, it can be helpful to run it both using the command-line interface (CLI) and in continuous integration (CI) to review findings behavior.

However, the two methods of running Semgrep have somewhat different behavior by default, so the findings may not be directly comparable. If you're seeing different findings with a CLI scan as compared to a scan in CI, here are some possible reasons.

Installation methods and versioning

When comparing Semgrep scans in CI and CLI, ensure that you are running the same version of Semgrep on the CLI as in CI, and that it is installed in the same way as it is in CI.

If you use Semgrep's Docker image in CI and are running the CLI scan locally, the best options are:

  • Use the Docker container locally.
  • Install Semgrep using brew (Mac only).

Branches and diff-aware scans

When comparing findings, ensure that the scans were run on the same code. To compare results for an entire repository, the best option is to scan the latest commit to the default branch.

When running Semgrep in CI, if the triggering event is a pull request or merge request, the recommended configuration runs a diff-aware scan, so only findings identified in the changed code are reported. Therefore, not all findings are reported in these scans.

Rule configuration

If you use Semgrep with Semgrep AppSec Platform, semgrep ci with no additional arguments executes a scan using your organization's policies configuration. Findings are determined by the rules present in different policies. If you have any organization-specific rules in your policies, those are included as well.

Findings on rules in the Blocking policy cause the scan to finish with exit code 1. See also Blocking findings and errors.

On the other hand, semgrep --config auto executes a scan using relevant rules from the Semgrep Registry, without using a particular configuration. It does not include organization-specific rules from Semgrep AppSec Platform.

To address this difference, run semgrep scan with specific rules or rulesets that closely match your policies. For example, if your policies include only the "default" ruleset in the Monitor column, running:

semgrep --config "p/default"

would give similar results to semgrep ci.

Pro analysis

When using semgrep ci with Semgrep AppSec Platform, the Semgrep scan reflects the Pro Engine options configured in Semgrep AppSec Platform at If Pro Engine is enabled, and the scanned code includes supported Pro languages, then interfile and interprocedural analysis is performed.

If Pro Engine is not enabled in Semgrep AppSec Platform, Pro rules are used, but they are run as OSS rules, using only intrafile and intraprocedural analysis.

To perform a CLI scan using Pro Engine, ensure you've installed Pro Engine, and include --pro in your command:

semgrep --config auto --pro

To scan without Pro Engine in CI, even if it is enabled in Semgrep AppSec Platform, use:

semgrep ci --oss-only

Blocking findings and errors

If you use Semgrep in CI without Semgrep AppSec Platform, semgrep ci finishes with exit code 1 if there are any findings, since there is no way to distinguish blocking from non-blocking findings. Review Configuring blocking findings and errors in continuous integration (CI) to change this behavior.

The CLI command semgrep scan finishes with exit code 0 by default as long as the scan is able to complete, even if there are findings. To finish with exit code 1 on any findings, use the --error flag.

Not finding what you need in this doc? Ask questions in our Community Slack group, or see Support for other ways to get help.