Skip to main content

Sample continuous integration (CI) configurations

This document provides sample configuration snippets to run Semgrep CI on various continuous integration (CI) providers.

Feature support

Support for certain features of Semgrep AppSec Platform depend on your CI provider or source code management tool (SCM). The following table breaks down the features and their availability:

Integrations with source code providers, dependent on CI provider:

FeatureGitHub with GitHub ActionsGitLab with GL CI/CDGitHub, GitLab, or BitBucket with other CI providers
Diff-aware scanning✅ (May need additional set up)
Hyperlinks✅ (May need additional set up)
PR or MR comments✅ (May need additional set up)
SCM security dashboard✅ GitHub Advanced Security Dashboard✅ GitLab Security Dashboard❌ No

For example, if you use CircleCI as your CI provider on a GitHub repository, Semgrep AppSec Platform does not have any support for GitHub Advanced Security Dashboard.

The following list defines the above features.

Diff-aware scanning
Semgrep AppSec Platform can scan only changes in files when running on a pull or merge request (PR or MR). This keeps the scan fast and reduces finding duplication.
Hyperlinks to code
Semgrep AppSec Platform collects findings in a Findings page. In this page, you can click on a finding to return to your SCM (Github, GitLab, or Bitbucket) to view the lines of code in your repository that generated the finding.
Receiving results (findings) as PR or MR comments
This feature enables you to receive PR or MR comments from Semgrep AppSec Platform on the lines of code that generated a finding.
SCM security dashboard
Send Semgrep findings to your SCM's security dashboard.

GitHub Actions

To add a Semgrep configuration file in your GitHub Actions pipeline:

  1. Create a semgrep.yml file in .github/workflows in the repository you want to scan.
  2. Copy the relevant code snippet provided in Sample GitHub Actions configuration file.
  3. Paste the relevant code snippet to semgrep.yml file. This is your Semgrep configuration file for GitHub Actions.
  4. Commit the configuration file under /REPOSITORY-ROOT-DIRECTORY/.github/workflows/semgrep.yml.
  5. The Semgrep job starts automatically upon detecting the committed semgrep.yml file.
note

If you are self-hosting your repository, you must use a self-hosted runner.

Sample GitHub Actions configuration file

The following configuration creates a CI job that runs scans depending on what products you have enabled in Semgrep AppSec Platform.

# Name of this GitHub Actions workflow.
name: Semgrep

on:
# Scan changed files in PRs (diff-aware scanning):
pull_request: {}
# Scan on-demand through GitHub Actions interface:
workflow_dispatch: {}
# Scan mainline branches if there are changes to .github/workflows/semgrep.yml:
push:
branches:
- main
- master
paths:
- .github/workflows/semgrep.yml
# Schedule the CI job (this method uses cron syntax):
schedule:
- cron: '20 17 * * *' # Sets Semgrep to scan every day at 17:20 UTC.
# It is recommended to change the schedule to a random time.

jobs:
semgrep:
# User definable name of this GitHub Actions job.
name: semgrep/ci
# If you are self-hosting, change the following `runs-on` value:
runs-on: ubuntu-latest

container:
# A Docker image with Semgrep installed. Do not change this.
image: semgrep/semgrep

# Skip any PR created by dependabot to avoid permission issues:
if: (github.actor != 'dependabot[bot]')

steps:
# Fetch project source with GitHub Actions Checkout. Use either v3 or v4.
- uses: actions/checkout@v4
# Run the "semgrep ci" command on the command line of the docker image.
- run: semgrep ci
env:
# Connect to Semgrep AppSec Platform through your SEMGREP_APP_TOKEN.
# Generate a token from Semgrep AppSec Platform > Settings
# and add it to your GitHub secrets.
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}

You can run specific product scans by passing an argument, such as --supply-chain. View the list of arguments.

caution

If you define both branches or branches-ignore and paths or paths-ignore, the workflow only runs when both filters are satisfied.

For example, if your configuration file includes the following definition, the workflow runs only if there are changes on the development branch to .github/workflows/semgrep.yml :

push:
branches:
- development
paths:
- .github/workflows/semgrep.yml

Upload findings to GitHub Advanced Security Dashboard

Alternate job that uploads findings to GitHub Advanced Security Dashboard
# Name of this GitHub Actions workflow.
name: Semgrep

on:
# Scan changed files in PRs (diff-aware scanning):
pull_request: {}
# Scan on-demand through GitHub Actions interface:
workflow_dispatch: {}
# Scan mainline branches and report all findings:
push:
branches: ["master", "main"]
# Schedule the CI job (this method uses cron syntax):
schedule:
- cron: '20 17 * * *' # Sets Semgrep to scan every day at 17:20 UTC.
# It is recommended to change the schedule to a random time.

jobs:
semgrep:
# User definable name of this GitHub Actions job.
name: semgrep/ci
# If you are self-hosting, change the following `runs-on` value:
runs-on: ubuntu-latest

container:
# A Docker image with Semgrep installed. Do not change this.
image: semgrep/semgrep

# Skip any PR created by dependabot to avoid permission issues:
if: (github.actor != 'dependabot[bot]')

steps:
# Fetch project source with GitHub Actions Checkout. Use either v3 or v4.
- uses: actions/checkout@v4
# Run the "semgrep ci" command on the command line of the docker image.
- run: semgrep ci --sarif > semgrep.sarif
env:
# Connect to Semgrep AppSec Platform through your SEMGREP_APP_TOKEN.
# Generate a token from Semgrep AppSec Platform > Settings
# and add it to your GitHub secrets.
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}

- name: Upload SARIF file for GitHub Advanced Security Dashboard
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: semgrep.sarif
if: always()

GitLab CI/CD

To add a Semgrep configuration snippet in your GitLab CI/CD pipeline:

  1. Create or edit your .gitlab-ci.yml file in the repository you want to scan.
  2. Copy the relevant code snippet provided in Sample GitLab CI/CD configuration snippet, and then paste it to your .gitlab-ci.yml file.
  3. Commit the updated .gitlab-ci.yml file.
  4. The Semgrep job starts automatically upon detecting the committed .gitlab-ci.yml file. You can also view the job from your GitLab project's CI/CD > Pipelines page.

Sample GitLab CI/CD configuration snippet

The following configuration creates a CI job that runs scans depending on what products you have enabled in Semgrep AppSec Platform.

semgrep:
# A Docker image with Semgrep installed.
image: semgrep/semgrep
# Run the "semgrep ci" command on the command line of the docker image.
script: semgrep ci

rules:
# Allow triggering a scan manually from the GitLab UI
- if: $CI_PIPELINE_SOURCE == "web"
# Scan changed files in MRs, (diff-aware scanning):
- if: $CI_MERGE_REQUEST_IID
# Scan mainline (default) branches and report all findings.
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

variables:
# Connect to Semgrep AppSec Platform through your SEMGREP_APP_TOKEN.
# Generate a token from Semgrep AppSec Platform > Settings
# and add it as a variable in your GitLab CI/CD project settings.
SEMGREP_APP_TOKEN: $SEMGREP_APP_TOKEN

# Optional variable to receive MR comments. Setup instructions:
# https://semgrep.dev/docs/semgrep-appsec-platform/gitlab-mr-comments
# GITLAB_TOKEN: $PAT

You can run specific product scans by passing an argument, such as --supply-chain. View the list of arguments.

Prefer to use GitLab group variables? See this guide for an appropriate configuration.

Upload findings to GitLab Security Dashboard

Alternate job that uploads findings to GitLab Security Dashboard
semgrep:
# A Docker image with Semgrep installed.
image: semgrep/semgrep

rules:
# Scan changed files in MRs, (diff-aware scanning):
- if: $CI_MERGE_REQUEST_IID

# Scan mainline (default) branches and report all findings.
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

variables:
# Connect to Semgrep AppSec Platform through your SEMGREP_APP_TOKEN.
# Generate a token from Semgrep AppSec Platform > Settings
# and add it as a variable in your GitLab CI/CD project settings.
SEMGREP_APP_TOKEN: $SEMGREP_APP_TOKEN

# Upload findings to GitLab SAST Dashboard:
SEMGREP_GITLAB_JSON: "1"

# Other optional settings in the `variables` block:

# Receive inline MR comments (requires Semgrep AppSec Platform account)
# Setup instructions:
# https://semgrep.dev/docs/semgrep-appsec-platform/gitlab-mr-comments
# GITLAB_TOKEN: $PAT

# Run the "semgrep ci" command on the command line of the docker image and send findings
# to GitLab SAST.
script: semgrep ci --gitlab-sast > gl-sast-report.json || true
artifacts:
reports:
sast: gl-sast-report.json

Jenkins

note

Your UI (user interface) may vary depending on your Jenkins installation. These steps use a Classic UI Jenkins interface.

To add a Semgrep configuration snippet in your Jenkins pipeline:

  1. Create or edit your Jenkinsfile configuration file in the repository you want to scan. You can also edit your Jenkinsfile from Jenkins's interface.
  2. Copy the relevant code snippet provided in Sample Jenkins configuration snippet.
  3. Paste the code to your Jenkinsfile, and then commit the file.
  4. The Semgrep job starts automatically upon detecting the Jenkinsfile update.
  5. Optional: Create a separate CI job for diff-aware scanning, which scans only changed files in PRs or MRs, by repeating steps 1-3 and uncommenting the SEMGREP_BASELINE_REF definition provided within the code snippet.

Sample Jenkins configuration snippet

info

For SCA scans (Semgrep Supply Chain): users of Jenkins UI with the Git plugin must also set up their branch information. See Setting up Semgrep Supply Chain with Jenkins UI for more information.

The following configuration creates a CI job that runs scans depending on what products you have enabled in Semgrep AppSec Platform.

This code snippet uses Jenkins declarative syntax.

pipeline {
agent any
environment {
// The following variable is required for a Semgrep AppSec Platform-connected scan:
SEMGREP_APP_TOKEN = credentials('SEMGREP_APP_TOKEN')

// Uncomment the following line to scan changed
// files in PRs or MRs (diff-aware scanning):
// SEMGREP_BASELINE_REF = "main"

// Troubleshooting:

// Uncomment the following lines if Semgrep AppSec Platform > Findings Page does not create links
// to the code that generated a finding or if you are not receiving PR or MR comments.
// SEMGREP_JOB_URL = "${BUILD_URL}"
// SEMGREP_COMMIT = "${GIT_COMMIT}"
// SEMGREP_BRANCH = "${GIT_BRANCH}"
// SEMGREP_REPO_NAME = env.GIT_URL.replaceFirst(/^https:\/\/github.com\/(.*).git$/, '$1')
// SEMGREP_REPO_URL = env.GIT_URL.replaceFirst(/^(.*).git$/,'$1')
// SEMGREP_PR_ID = "${env.CHANGE_ID}"
}
stages {
stage('Semgrep-Scan') {
steps {
sh 'pip3 install semgrep'
sh 'semgrep ci'
}
}
}
}

You can run specific product scans by passing an argument, such as --supply-chain. View the list of arguments.

Bitbucket Pipelines

To add a Semgrep configuration snippet into Bitbucket Pipelines:

  1. Create or edit your bitbucket-pipelines.yml file in the repository you want to scan.
  2. Copy the relevant code snippet provided in Sample Bitbucket Pipelines configuration snippet, and then paste it to your bitbucket-pipelines.yml.
  3. Commit the updated bitbucket-pipelines.yml configuration file.
  4. The Semgrep job starts automatically upon detecting the committed bitbucket-pipelines.yml file. You can view the job through Bitbucket's interface, by clicking REPOSITORY_NAME > Pipelines.
  5. Optional: Create a daily scheduled run for the custom pipeline on the main branch by scheduling a pipeline in Bitbucket.
note

These steps can also be performed through Bitbucket's UI wizard. This UI wizard can be accessed through Bitbucket > REPOSITORY_NAME > Pipelines > Create your first pipeline.

Sample Bitbucket Pipelines configuration snippet

The following configuration creates a CI job that runs scans depending on what products you have enabled in Semgrep AppSec Platform.

image: semgrep/semgrep:latest

pipelines:
branches:
# Change to your default branch if different from main
main:
- step:
name: Semgrep scan on push
script:
- export SEMGREP_APP_TOKEN=$SEMGREP_APP_TOKEN
- semgrep ci

pull-requests:
'**': # This applies to pull requests for all branches
- step:
name: Semgrep scan on PR
script:
- export SEMGREP_APP_TOKEN=$SEMGREP_APP_TOKEN
- export BITBUCKET_TOKEN=$PAT # Necessary for PR comments
# Change to your default branch if different from main
- export SEMGREP_BASELINE_REF="origin/main"
- git fetch origin "+refs/heads/*:refs/remotes/origin/*"
- semgrep ci

custom:
# Trigger job manually. For cron in Bitbucket, see: https://support.atlassian.com/bitbucket-cloud/docs/pipeline-triggers/#On-schedule
semgrep-manual:
- step:
name: Semgrep manual scan
script:
- export SEMGREP_APP_TOKEN=$SEMGREP_APP_TOKEN
- semgrep ci

You can run specific product scans by passing an argument, such as --supply-chain. View the list of arguments.

tip

If the pipeline's default runner runs out of memory, you can limit the number of subprocesses Semgrep uses with the -j flag, or add the size directive to the Semgrep step to increase the memory available:

pipelines:
default:
- step:
size: 2x
script:
- echo "This step gets double the memory!"

Buildkite

To add Semgrep into your Buildkite pipeline:

  1. Prepare a configuration file to add a Semgrep scan as part of your pipeline. This configuration file can be stored within Buildkite or as a pipeline.yml file in the target repository.
  2. Copy the code snippet provided in Sample Buildkite configuration snippet, making alterations if necessary for your environment.
  3. If you are using Buildkite to store the configuration, save the updated file. Otherwise, commit the updated pipeline.yml file into the /.buildkite folder within the target repository.
  4. The Semgrep job starts automatically upon detecting the committed pipeline.yml file. Alternatively, if you are using the Buildkite UI, you can select New build. You can view the job through Buildkite's interface by clicking Pipelines > pipeline name.
note

These steps can be performed within Buildkite's UI. To do so, navigate to Buildkite's main page, and click Pipelines > New Pipeline.

Sample Buildkite configuration snippet

The following configuration creates a CI job that runs scans according to the products you have enabled in Semgrep AppSec Platform. The provided environment variables are commonly needed to correctly configure scans from Buildkite.

This file configures two mutually exclusive command steps, one for full scans, and one for diff-aware scans. The latter is used for pull or merge requests.

In order for this configuration to run the correct type of scan for each condition, it requires both branch filtering and configuration to build on pull requests.

Branch filtering

  1. In the Buildkite UI, go to the pipeline Settings and select the connected source code manager in the left sidebar. Pipeline settings with example GitHub SCM Figure. Buildkite pipeline settings with using GitHub as the SCM.
  2. Under Branch Limiting, enter your default branch name in the Branch Filter Pattern box. You can include any other branch names that require full scans as well, such as release-*. Branch limiting settings with example main branch Figure. Branch limiting settings with main as the example branch.
  3. Click Save Branch Limiting.

Build on pull requests

To run diff-aware scans, your pipeline must run builds on pull or merge requests. Buildkite integrates with several source code managers and each one has different options to handle pull or merge requests. The most common options are a checkbox within the pipeline settings, or webhooks within the source control manager. Review the documentation for your source control system to ensure your Semgrep pipeline builds on pull or merge requests.

- label: ":semgrep: Semgrep Full Scan"
commands:
- if [[ $BUILDKITE_COMMIT =~ ^[a-fA-F0-9]{40}$ ]]; then export SEMGREP_COMMIT=${BUILDKITE_COMMIT}; fi
- export SEMGREP_BRANCH=${BUILDKITE_BRANCH}
- export SEMGREP_REPO_URL=${BUILDKITE_REPO}
- export SEMGREP_REPO_NAME="$(echo "$BUILDKITE_REPO" | sed -e 's#git@github.com:##' | sed -e 's#.git##')"
- semgrep ci
if: |
build.pull_request.id == null

- label: ":semgrep: Semgrep Diff Scan"
commands:
- if [[ $BUILDKITE_COMMIT =~ ^[a-fA-F0-9]{40}$ ]]; then export SEMGREP_COMMIT=${BUILDKITE_COMMIT}; fi
- export SEMGREP_PR_ID=${BUILDKITE_PULL_REQUEST}
- export SEMGREP_BRANCH=${BUILDKITE_BRANCH}
- export SEMGREP_REPO_URL=${BUILDKITE_REPO}
- export SEMGREP_REPO_NAME="$(echo "$BUILDKITE_REPO" | sed -e 's#git@github.com:##' | sed -e 's#.git##')"
- SEMGREP_BASELINE_REF=${BUILDKITE_PULL_REQUEST_BASE_BRANCH} semgrep ci
if: |
build.pull_request.id != null

plugins:
- docker#v5.11.0:
image: semgrep/semgrep:latest
environment:
# The following variable is required to set up a scan connected to Semgrep AppSec Platform:
- "SEMGREP_APP_TOKEN"

You can run specific product scans by passing the appropriate argument, such as --supply-chain.

CircleCI

To add Semgrep into your CircleCI pipeline:

  1. Create a context:
    1. In CircleCI web app, click Organization Settings > Contexts.
    2. Click Create Context.
    3. Enter semgrep as the name for the context.
    4. Click Add Environment Variable and enter your SEMGREP_APP_TOKEN.
  2. Create or edit your config.yml configuration file in the repository you want to scan.
  3. Copy the relevant code snippet provided in Sample CircleCI configuration snippet.
  4. If your default branch is not main, change the occurrences of main to the name of your default branch.
  5. Commit the updated config.yml configuration file into the /.circleci folder in the target repository.
  6. The Semgrep job starts automatically upon detecting the config.yml update.

The sample configuration provides jobs for both full scanning and diff-aware scanning, which scans only changed files in PRs or MRs. You do not need to create any other jobs.

CircleCI runs the Semgrep job on all the commits for the project by default. If you want the job to scan only branches that have an associated a pull request open, you can enable the option "Only build pull requests" in Project Settings > Advanced.

note

For the default branch and tags, CircleCI always runs the Semgrep CI job on all commits.

Sample CircleCI configuration snippet

The following configuration creates a CI job that runs scans depending on what products you have enabled in Semgrep AppSec Platform.

version: 2.1
workflows:
semgrep:
jobs:
- semgrep-full-scan:
filters:
branches:
only: main
context:
- semgrep
- semgrep-diff-scan:
filters:
branches:
ignore: main
context:
- semgrep
jobs:
semgrep-full-scan:
docker:
- image: semgrep/semgrep
steps:
- checkout
- run:
name: "Semgrep full scan"
command: semgrep ci
semgrep-diff-scan:
parameters:
default_branch:
type: string
default: main
docker:
- image: semgrep/semgrep
steps:
- checkout
- run:
name: Semgrep diff scan
environment:
SEMGREP_BASELINE_REF: << parameters.default_branch >>
command: semgrep ci

You can run specific product scans by passing an argument, such as --supply-chain. View the list of arguments.

Azure Pipelines

info

Scanning a project with the semgrep ci command requires the project to be version-controlled by Git. If you have Azure Repos that are version-controlled with Team Foundations Version Control, they must be migrated to Git to be scanned with semgrep ci and have results reported to the Semgrep AppSec Platform.

To add Semgrep into Azure Pipelines:

  1. Access the YAML pipeline editor within Azure Pipelines by following the YAML pipeline editor guide.
  2. Copy the relevant code snippet provided in Sample Azure Pipelines configuration snippet into the Azure Pipelines YAML editor.
  3. Save the code snippet.
  4. Set environment variables.
  5. Group the environment variables as a variable group.
  6. Optional: Create a separate CI job for diff-aware scanning, which scans only changed files in PRs or MRs, by repeating steps 1-4 and adding SEMGREP_BASELINE_REF as an environment variable.

Sample Azure Pipelines configuration snippet

This configuration snippet is tested with hosted Azure runners. If you are using self-hosted runners, you may need to make adjustments to ensure that the necessary software is available.

The following configuration creates a CI job that runs scans depending on what products you have enabled in Semgrep AppSec Platform.

variables:
- group: Semgrep_Variables

steps:
- checkout: self
clean: true
fetchDepth: 20
persistCredentials: true
- script: |
python -m pip install --upgrade pip
pip install semgrep
if [ $(Build.SourceBranchName) = "master" ]; then
echo "Semgrep full scan"
semgrep ci
elif [ $(System.PullRequest.PullRequestId) -ge 0 ]; then
echo "Semgrep diff scan"
export SEMGREP_PR_ID=$(System.PullRequest.PullRequestId)
export SEMGREP_BASELINE_REF='origin/master'
git fetch origin master:origin/master
semgrep ci
fi

Setting environment variables in Azure Pipelines

Set these variables within Azure Pipelines UI following the steps in Environment variables:

  • SEMGREP_APP_TOKEN

Set these environment variables to troubleshoot the links to the code that generated a finding or if you are not receiving PR or MR comments:

  • SEMGREP_JOB_URL
  • SEMGREP_COMMIT
  • SEMGREP_BRANCH
  • SEMGREP_REPO_URL
  • SEMGREP_REPO_NAME

Set this environment variable for diff-aware scanning:

  • SEMGREP_BASELINE_REF. Its value is typically your trunkline branch, such as main or master.

You can run specific product scans by passing an argument, such as --supply-chain. View the list of arguments.

Other providers

To run Semgrep CI on any other provider, use the semgrep/semgrep image, and run the semgrep ci command with SEMGREP_BASELINE_REF set for diff-aware scanning.

Note: If you need to use a different image than docker, install Semgrep CI by pip install semgrep.

By setting various CI environment variables, you can run Semgrep in the following CI providers:

  • AppVeyor
  • Bamboo
  • Bitrise
  • Buildbot
  • Codeship
  • Codefresh
  • Drone CI
  • TeamCity CI
  • Travis CI

Is your CI provider missing? Let us know by filing an issue.


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