Configuration of the CI/CD environment.
Safe runs on different CI/CD providers (Github actions, CircleCI, SemaphoreCI and Jenkins). It uses a docker image which makes it easier to integrate with other providers.
Define the CI/CD Job
Make sure to place the configuration config.json file (which was created during the setup of the project with the cli ) in the root of the repository under the .safe folder. For more information about the config.json file please visit this page.
In your CI/CD pipeline, define a job specifically for SAFE (e.g: security-check). This job will manage the analysis process by referencing the configuration created in the CLI setup
Make sure to run a compilation job before defining the security-check CI job.
SAFE needs to have the BEAM files to be able to run the analysis.
The environment you compile your project on should be the same as the one during the
setup of the project i.e: prod, test, dev.. etc
You should compile the codebase with the debug_info flag.
In case of a Rebar3 or Mix project (Elixir), this option is enabled by default.
To be able to persist the results, you need to add a new entry in your .safe/config.json under the output section with a file
entry.
Here is an example definition for github actions, CircleCI, SemaphoreCI and Jenkins.
Github actions
name: Erlang CI
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1
with:
otp-version: '26'
rebar3-version: '3.24.0'
- name: Compile
run: rebar3 compile
- name: Upload _build directory
uses: actions/upload-artifact@v4
with:
name: build-artifact
path: _build
security-check:
runs-on: ubuntu-latest
needs: build
container:
image: erlangsolutions/safe:1.1.0-otp-26
steps:
- uses: actions/checkout@v4
- name: Download _build directory
uses: actions/download-artifact@v4
with:
name: build-artifact
path: _build
- run: safe start
env:
SAFE_LICENSE: ${{ secrets.SAFE_LICENSE }}
- name: Persist results
if: always()
uses: actions/upload-artifact@v4
with:
name: project-safe-results
path: _results/<<Project_Name>>.safe
CircleCI
security-check:
resource_class: medium
docker:
- image: erlangsolutions/safe:1.1.0-otp-26
working_directory: /repo
steps:
- checkout
- attach_workspace:
at: /repo
- run:
command: safe start
no_output_timeout: 1h
- store_artifacts:
path: /repo/_results/<<Project_Name>>.safe
SemaphoreCI
version: v1.0
name: Erlang
agent:
machine:
type: e2-standard-2
os_image: ubuntu2004
blocks:
- name: build
task:
jobs:
- name: compile
commands:
- rebar3 compile
env_vars:
- name: MIX_ENV
value: test
dependencies: []
- name: Security Check
dependencies: []
task:
jobs:
- name: 'Job #1'
commands:
- checkout
- 'docker run -v $(pwd)/_results:/safe/_results -v /home/semaphore/<<Repository>>:/<<Repository>> --env SAFE_LICENSE="$SAFE_LICENSE" --env SAFE_CI_CONFIG_PATH="/<<Repository>>/.safe/config.json" erlangsolutions/safe:1.1.0-otp-26'
- artifact push job _results/<<Project_Name>>.safe
secrets:
- name: SAFE_LICENSE
To create and use secrets in SemaphoreCI please visit the documentation.
Jenkins

pipeline {
agent none
options {
ansiColor('xterm')
}
parameters {
string(name: 'DOCKER_NAME', defaultValue: 'safe', description: 'Docker image to use for compile stage')
}
stages {
stage('Compile') {
agent {
docker {
image 'erlang:26.2.1'
args '-u root'
}
}
steps {
sh 'rebar3 compile'
}
}
stage('Archive Build') {
agent any
steps {
stash includes: '_build/**', name: 'build-artifact'
}
}
stage('SAFE Security Check') {
agent {
docker {
image "${params.DOCKER_NAME}"
args '-e SAFE_LICENSE'
}
}
steps {
sh 'echo "SAFE_LICENSE=$SAFE_LICENSE"' // for debug (optional)
sh 'safe analyse'
}
}
}
post {
always {
echo 'Pipeline finished.'
}
success {
echo 'Build and tests succeeded!'
}
failure {
echo 'Something went wrong...'
}
}
}
Gitlab CI
The following example shows how to use SAFE in Gitlab CI/CD.
stages:
- build
- test
build-job:
stage: build
image: erlang:24
script:
- rebar3 compile
artifacts:
paths:
- _build/
expire_in: 1h
esl-safe-check:
stage: test
image: erlangsolutions/safe:1.1.0-otp-26
script:
- safe start
dependencies:
- build-job
The minimum system requirements for the CI machine are 2 CPUs and 4GB of RAM.
Example result in the CI/CD output:
The CI job will terminate with exit code 1 in case SAFE finds vulnerabilities.