Integrating NG SAST into the GitLab Merge Request Workflow

This article shows you how to integrate ShiftLeft CORE's NG SAST into your GitLab Merge Request Workflow for automated code analysis whenever you create a new PR.

Background

Integrating NG SAST into your GitLab Merge Request workflow is done using the pipelines for merge requests that GitLab includes in its premium version.

We assume that you're working with a GitLab repo that utilizes GitLab's built-in CI pipelines and Linux-based runners, though you could use GitLab's [runners] as an alternative.

Prerequisites

To facilitate communication between ShiftLeft and GitLab, please create the required environment variables and API access token as described in the following two sections.

Set Environment Variables

Create the following custom environment variables so that GitLab can communicate and use ShiftLeft:

Environment VariableValue
SHIFTLEFT_ACCESS_TOKENYour Access Token
SHIFTLEFT_API_TOKENYour ShiftLeft Public API Token

You can find your public API token by going to Dashboard > Account Settings.

When running in a production environment, we recommend that you use a CI token as the access token. You can create your CI token in the ShiftLeft Dashboard.

Please note that the presence of any set environment variables will override those in a configuration file.

GitLab API Access

Configure a personal access token so that ShiftLeft can authenticate with the GitLab API. Name it MR_TOKEN for use in the Bash script used to run NG SAST, and make sure to assign it the api and read_api scopes.

Step 1: Mandate Successful Merge Checks

As a GitLab administrator, you can edit your project properties to enforce branch protection rules. Go to Settings > General and expand the Merge Requests section. Scroll down to Merge checks and make sure that both are checked:

  • Pipelines must succeed
  • All discussions must be resolved

GitLab merge check settings

Step 2: Configure the GitLab Pipelines Configuration File and Include Code Analysis

The .gitlab-ci.yml file controls the jobs executed in GitLab pipelines, and this is where you can insert instructions to run the NG SAST code review process.

If you don't already have a .gitlab-ci.yml file in your project repository, you will need to create one.

Once you've created the configuration file, you can add the following snippet to the rest of your YAML file to invoke code analysis for merge_request events:

Analyze code with NG SAST:
stage: test
dependencies:
- build
image:
name: ubuntu:latest
script:
# Ensure curl and jq are installed
- apt update && apt install -y curl jq
# Install sl
- curl https://cdn.shiftleft.io/download/sl >/usr/local/bin/sl && chmod a+rx /usr/local/bin/sl
# Run NG SAST script
- sh sl-analysis.sh
rules:
- when: always

Here is what a complete .gitlab-ci.yml file could look like for a Maven project:

image: maven:latest
variables:
SHIFTLEFT_ACCESS_TOKEN: $SHIFTLEFT_ACCESS_TOKEN
MR_TOKEN: $MR_TOKEN
Build code:
stage: build
artifacts:
paths:
- target/
script:
- mvn package
rules:
- when: always
Analyze code with NG SAST:
stage: test
dependencies:
- Build code
image:
name: ubuntu:latest
script:
# Ensure curl and jq are installed
- apt update && apt install -y curl jq
# Install sl
- curl https://cdn.shiftleft.io/download/sl >/usr/local/bin/sl && chmod a+rx /usr/local/bin/sl
# Run NG SAST script
- sh sl-analysis.sh
rules:
- when: always

Note that the configuration file calls a script called sl-analysis.sh. You will need to add the file, which includes the code shown below, to the root of your repository (be sure to modify the placeholder variables as indicated in the file's comments):

#!/bin/sh
#### Analyze code
sl analyze \
--app "$CI_PROJECT_NAME" \
--version-id "$CI_COMMIT_SHA" \
--tag branch="$CI_COMMIT_REF_NAME" \
--cpg \
--wait \
target/war-or-jar-file-name # Change this
#### Run build rules
# Check if this is running in a merge request
if [ -n "$CI_MERGE_REQUEST_IID" ]; then
echo "Got merge request $CI_MERGE_REQUEST_IID for branch $CI_COMMIT_REF_NAME"
# Run check-analysis and save report to /tmp/check-analysis.md
sl check-analysis \
--app "$CI_PROJECT_NAME" \
--report \
--report-file /tmp/check-analysis.md \
--source "tag.branch=master" \
--target "tag.branch=$CI_COMMIT_REF_NAME"
CHECK_ANALYSIS_OUTPUT=$(cat /tmp/check-analysis.md)
COMMENT_BODY=$(jq -n --arg body "$CHECK_ANALYSIS_OUTPUT" '{body: $body}')
# Post report as merge request comment
curl -i -XPOST "https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/merge_requests/$CI_MERGE_REQUEST_IID/notes" \
-H "PRIVATE-TOKEN: $MR_TOKEN" \
-H "Content-Type: application/json" \
-d "$COMMENT_BODY"
fi

Please note that the script above includes a section that runs build rules; we will cover build rules in the following sections.

Step 3: Configure Your Build Rules

NG SAST allows you to create build rules, which define the security approval conditions that must be met before you can merge a merge request.

You can define build rules in a configuration file. By default, the name and location of your configuration file in your repository should be shiftleft.yml. The file should be formatted as follows:

build_rules:
- id: Any critical findings
severity:
- critical

Step 4: Push Your Files to GitLab

Once you've created the following files, commit them to your project and push them to GitLab:

  • .gitlab-ci.yml
  • shiftleft.yml
  • sl-analysis.sh

Please note that GitLab will automatically create a pipeline for you once you push .gitlab-ci.yml.

Step 5: Testing the Workflow

At this point, you can test your workflow. When you begin merging your changes into your master branch, ShiftLeft will run, analyze your code, and indicate whether the merger should fail or not based on the build rules you define.

For example, if one of your build rules is violated, you will see the following result in your build logs:

GitLab build logs

GitLab will also report that a build rule failed:

GitLab Conversation