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:
| Feature | GitHub with GitHub Actions | GitLab with GL CI/CD | GitHub, 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 request 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:
- Create a
semgrep.ymlfile in.github/workflowsin the repository you want to scan. - Copy the relevant code snippet provided in Sample GitHub Actions configuration file.
- Paste the relevant code snippet to
semgrep.ymlfile. This is your Semgrep configuration file for GitHub Actions. - Commit the configuration file under
/REPOSITORY-ROOT-DIRECTORY/.github/workflows/semgrep.yml. - The Semgrep job starts automatically upon detecting the committed
semgrep.ymlfile.
If you are self-hosting your repository, you must use a self-hosted runner.
Sample GitHub Actions configuration file
- Default
- Semgrep CE
The following configuration creates a CI job that runs scans using the products and options 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.
permissions:
contents: read
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.
The following configuration creates a CI job that runs Semgrep Community Edition (CE) scans using rules configured for your programming language.
# Name of this GitHub Actions workflow.
name: Semgrep CE scan
on:
# Scan in PRs:
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.
permissions:
contents: read
jobs:
semgrep:
# User definable name of this GitHub Actions job.
name: semgrep-oss/scan
# 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 scan" command on the command line of the docker image.
- run: semgrep scan --config auto
You can customize the scan by entering custom rules or other rulesets to scan with. See Scan your codebase with a specific ruleset.
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.
permissions:
# This permission is required when uploading sarifs to any repository at GitHub
security-events: write
# These permissions are only required when uploading sarifs to private and internal repositories at GitHub
contents: read
actions: read
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@v3
with:
sarif_file: semgrep.sarif
if: always()
GitLab CI/CD
To add a Semgrep configuration snippet in your GitLab CI/CD pipeline:
- Create or edit your
.gitlab-ci.ymlfile in the repository you want to scan. - Copy the relevant code snippet provided in Sample GitLab CI/CD configuration snippet, and then paste it to your
.gitlab-ci.ymlfile. - Commit the updated
.gitlab-ci.ymlfile. - The Semgrep job starts automatically upon detecting the committed
.gitlab-ci.ymlfile. You can also view the job from your GitLab project's CI/CD > Pipelines page.
Sample GitLab CI/CD configuration snippet
- Default
- Semgrep CE
The following configuration creates a CI job that runs scans using the products and options 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
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.
The following configuration creates a CI job that runs Semgrep CE scans using rules configured for your programming language.
semgrep:
# A Docker image with Semgrep installed.
image: semgrep/semgrep
# Run the "semgrep scan" command on the command line of the docker image.
script: semgrep scan --config auto .
rules:
# Scan in MRs.
- if: $CI_MERGE_REQUEST_IID
# Scan mainline (default) branches and report all findings.
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
You can customize the scan by entering custom rules or other rulesets to scan with. See Scan your codebase with a specific ruleset.
Upload findings to GitLab Security Dashboard
Alternate job that uploads SAST 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"
# Run the "semgrep ci" command on the command line of the docker image and send findings
# to GitLab SAST.
script: semgrep ci --code --gitlab-sast > gl-sast-report.json || true
artifacts:
reports:
sast: gl-sast-report.json
Jenkins
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:
- Create or edit your
Jenkinsfileconfiguration file in the repository you want to scan. You can also edit yourJenkinsfilefrom Jenkins's interface. - Copy the relevant code snippet provided in Sample Jenkins configuration snippet.
- Paste the code to your
Jenkinsfile, and then commit the file. - The Semgrep job starts automatically upon detecting the
Jenkinsfileupdate. - 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_REFdefinition provided within the code snippet.
Sample Jenkins configuration snippet
- Default
- Semgrep CE
- Default (Docker)
- Default (Bitbucket Data Center)
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 using the products and options 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.
The following configuration creates a CI job that runs Semgrep CE scans using rules configured for your programming language.
This code snippet uses Jenkins declarative syntax.
pipeline {
agent any
stages {
stage('Semgrep-Scan') {
steps {
sh 'pip3 install semgrep'
sh 'semgrep scan --config auto'
}
}
}
}
You can customize the scan by entering custom rules or other rulesets to scan with. See Scan your codebase with a specific ruleset.
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 '''docker pull semgrep/semgrep && \
docker run \
-e SEMGREP_APP_TOKEN=$SEMGREP_APP_TOKEN \
-e SEMGREP_REPO_URL=$SEMGREP_REPO_URL \
-e SEMGREP_REPO_NAME=$SEMGREP_REPO_NAME \
-e SEMGREP_BRANCH=$SEMGREP_BRANCH \
-e SEMGREP_COMMIT=$SEMGREP_COMMIT \
-e SEMGREP_PR_ID=$SEMGREP_PR_ID \
-v "$(pwd):$(pwd)" --workdir $(pwd) \
semgrep/semgrep semgrep ci '''
}
}
}
}
The following configuration creates a CI job that runs scans depending on what products you have enabled in Semgrep AppSec Platform. It is for use with code hosted in Bitbucket Data Center.
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')
BITBUCKET_TOKEN = credentials('FS_BITBUCKET_TOKEN')
// Uncomment the following line to scan changed
// files in PRs or MRs (diff-aware scanning):
// SEMGREP_BASELINE_REF = "${env.CHANGE_ID != null ? '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:\/\/YOUR_BITBUCKET_DATA_CENTER_URL\/scm\/(.*).git$/, '$1')
// SEMGREP_REPO_URL = env.GIT_URL.replaceFirst(/^(https:\/\/.*?)\/scm\/(.*)\/(.*)\.git$/, '$1/projects/$2/repos/$3')
// SEMGREP_PR_ID = "${env.CHANGE_ID != null ? env.CHANGE_ID : ''}"
SEMGREP_APP_URL = "https://semgrep.dev"
}
stages {
stage('Semgrep-Scan') {
steps {
sh 'pip3 install semgrep'
sh 'semgrep ci'
}
}
}
}
Bitbucket Pipelines
To add a Semgrep configuration snippet into Bitbucket Pipelines:
- Create or edit your
bitbucket-pipelines.ymlfile in the repository you want to scan. - Copy the relevant code snippet provided in Sample Bitbucket Pipelines configuration snippet, and then paste it to your
bitbucket-pipelines.yml. - Commit the updated
bitbucket-pipelines.ymlconfiguration file. - The Semgrep job starts automatically upon detecting the committed
bitbucket-pipelines.ymlfile. You can view the job through Bitbucket's interface, by clicking REPOSITORY_NAME > Pipelines. - Optional: Create a daily scheduled run for the custom pipeline on the main branch by scheduling a pipeline in Bitbucket.
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
- Default
- Semgrep CE
The following configuration creates a CI job that runs scans using the products and options 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.
The following configuration creates a CI job that runs Semgrep CE scans using rules configured for your programming language.
image: semgrep/semgrep:latest
pipelines:
default:
- parallel:
- step:
name: 'Run Semgrep scan with current branch'
deployment: dev # https://support.atlassian.com/bitbucket-cloud/docs/set-up-and-monitor-deployments/
script:
- semgrep scan --config auto
You can customize the scan by entering custom rules or other rulesets to scan with. See Scan your codebase with a specific ruleset.
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!"