Skip to main content

Sonatype for GitLab CI

CI/CD pipeline jobs in GitLab leverage custom docker images to perform desired actions in the context of the GitLab project's build workspace. As such, the GitLab Sonatype IQ docker Image provides the ability to run policy evaluation against build artifacts in GitLab and produces an evaluation report with policy violation counts and a link to a detailed report on the IQ server.

The IQ policy evaluation will pass/fail a GitLab pipeline based on the policy action defined in IQ for the given application and stage.

In addition, Sonatype for GitLab can assist with the remediation of identified vulnerabilities.

Download

Download the Docker Image here: GitLab Sonatype IQ Docker Image

Project Configuration

Any project that wants to leverage GitLab's CI/CD pipeline must include a .gitlab-ci.yml pipeline definition file in the root of the project. Documentation on the various options for pipeline and job definitions is available here. A GitLab pipeline job that performs policy evaluation consists of the following elements and would look something like this:

iq_policy_eval:
  stage: test
  image: sonatype/gitlab-nexus-iq-pipeline:latest
  script:
    - /sonatype/evaluate -i WebAppX target/web-app-x.war
  artifacts:
    name: "policy-eval-$CI_JOB_NAME-$CI_COMMIT_REF_NAME"
    paths:
      - WebAppX-policy-eval-report.html

Let's explore some of these elements in more detail:

  • iq_policy_eval - the name of the job and can be anything you like

  • stage: test - the pipeline stage in which to run the policy evaluation; can be any one of the built-in stages or any custom stage defined earlier in the pipeline definition file

  • image: sonatype/gitlab-nexus-iq-pipeline:latest - the docker image that will be used during the execution of this pipeline job. Available versions can be found in the GitLab Sonatype IQ docker image repository.

  • script - the script statements that will be run in the context of the given docker image; in this case, the following minimal elements are required:

    • /sonatype/evaluate is the shell script inside the docker container that executes the policy evaluation

    • -i WebAppX is the unique ID of the application being evaluated, as defined in the IQ server

    • target/web-app-x.war is a list of one or more artifacts from the build environment to perform the evaluation against

    • See the documentation provided with the image on Docker Hub for details about other options available during policy evaluation

  • artifacts - list of directories or files that will be zipped and archived with the executed pipeline; see the GitLab documentation for more information on how long these artifacts live and how to access them

    • name - the name to give the artifact zip file (note: pipeline variables can be used to create the name, as shown in the above example)

    • paths - references to one or more files or directories in the build environment to include in the archive

      • WebAppX-policy-eval-report.html - this is the name of the report generated by the policy evaluation and is comprised of '<app id>-policy-eval-report.html'

In order to make GitLab CI/CD pipeline job artifacts available across jobs you should add them to the pipeline cache, which could be defined a little further up in the file, as so:

cache:
  paths:
    - target/
    - <submodule1>/target/
    - <submodule2>/target/

Here is a typical output for a policy evaluation job configured as above (some lines were omitted for brevity):

Commencing IQ policy evaluation...
 [INFO] Validating IQ Server version http://192.168.1.201:8070...
 [INFO] Validating application ID repo-a with the IQ Server http://192.168.1.201:8070...
 [INFO] Discovered commit hash 'c857286a3c4bc332e9b4c279fa7fab8dcb9377e3' via environment variable CI_COMMIT_SHA
 [INFO] Starting scan...
 [INFO] Scan target: /builds/root/repo-a/target/dependency/commons-fileupload-1.4.jar
...
 [INFO] 2021-04-09T15:34:33.869Z Finished scanning target: /builds/root/repo-a/target/sonatype-clm/module.xml
 [INFO] 2021-04-09T15:34:33.869Z Scanned 1455 total files
 [INFO] Fingerprinting completed in 1 seconds for 8 archives, 1296 total files
 [INFO] Discovered repository url 'http://172.100.0.2/root/repo-a' via environment variable CI_PROJECT_URL
 [INFO] Waiting for policy evaluation to complete...
 [INFO] Assigned scan ID 361b686717f94080a73ccb9c0a2d99cb
 [INFO] Policy evaluation completed in 10 seconds.
 [INFO] 
 [ERROR] The IQ Server reports policy failing due to 
 Policy(Sev-Critical) [
  Component(displayName=org.apache.logging.log4j : log4j-core : 2.3, hash=58a3e964db5307e30650) [
   Constraint(Severity) [Security Vulnerability Severity >= 8 because: Found security vulnerability CVE-2017-5645 with severity >= 8 (severity = 9.8), on condition 0] ]]
 [ERROR] The IQ Server reports policy failing due to 
 Policy(Sev-High) [
  Component(displayName=Junit : junit : 4.12, hash=2973d150c0dc1fefe998) [
   Constraint(Severity) [Security Vulnerability Severity >= 4 because: Found security vulnerability CVE-2020-15250 with severity >= 4 (severity = 5.5), on condition 0] ]]
...
 [ERROR] The IQ Server reports policy failing due to 
 Policy(Sev-High) [
  Component(displayName=commons-io : commons-io : 2.2, hash=83b5b8a7ba1c08f9e8c8) [
   Constraint(Severity) [Security Vulnerability Severity < 8 because: Found security vulnerability sonatype-2018-0705 with severity < 8 (severity = 7.8), on condition 0] ]]
 [INFO] 
 [INFO] 
 [INFO] *********************************************************************************************
 [INFO] Policy Action: Failure
 [INFO] Stage: build
 [INFO] Number of components affected: 1 critical, 3 severe, 0 moderate
 [INFO] Number of open policy violations: 1 critical, 12 severe, 0 moderate
 [INFO] Number of grandfathered policy violations: 0
 [INFO] Number of components: 8
 [INFO] The detailed report can be viewed online at http://192.168.1.201:8070/ui/links/application/repo-a/report/361b686717f94080a73ccb9c0a2d99cb
 [INFO] *********************************************************************************************
 [INFO] Processing policy evaluation results...
 ...IQ policy evaluation complete

The policy evaluation job's output lists all the files that are considered for evaluation. If there are policy violations, they are listed as errors. Each policy violation states its severity, the component that triggered the violation, and the failed policy details.

The policy evaluation summary can be found at the end of the job's output. It also contains a link to a detailed report in Lifecycle.

IQ Server Connection Information

The required connection information for the IQ server can be specified at either the group or project level using the CI/CD settings, as so:

126655832.png

The following three environment variables must be defined if not set explicitly in the job definition via script parameters:

126655831.png

An optional environment variable, namedNEXUS_IQ_REPORT_FORMAT, can be set to control the content of the generated evaluation report. If the variable is set to 'summary', the evaluation report will contain brief summary information and a link to the detailed report on the IQ server. Otherwise, the evaluation report will contain a summary header, which includes a link to the detailed report on the IQ server, and details about the components that trigger policy actions, accompanied by policy violation details.

Problems with the IQ server connection will show up in, and can be diagnosed from, the pipeline job output, as so:

126655830.png

Self-signed Certificates

If the IQ Server uses a self-signed certificate, additional configuration is needed to make Sonatype for GitLab CI work.

There are two approaches that could be taken to make that happen:

  • Add the self-signed certificate to the Docker container created from the GitLab Sonatype IQ Docker image on the fly, or

  • Create a custom Docker image from the GitLab Sonatype IQ Docker image, add the self-signed certificate to the new image, and use this newly created image to run policy evaluations against IQ Server.

Add the self-signed certificate on the fly

In order to achieve that the self-signed certificate must be available during the pipeline execution. It could be checked into the repository or pulled at runtime from a common location (e.g. using wget or similar tools).

Below you can see an example of a stripped-down pipeline that adds the self-signed certificate to the Docker container on the fly, assuming the certificate (i.e. iq-server.cert) is checked into the root folder of the repository. If you're implementing this in your environment, make sure the paths are updated accordingly:

iq_policy_eval:
  stage: test
  image: sonatype/gitlab-nexus-iq-pipeline:latest
  before_script:
    - keytool -keystore /opt/java/openjdk/lib/security/cacerts -storepass changeit -noprompt -trustcacerts -importcert -alias iq-server -file iq-server.cert
  script:
    - /sonatype/evaluate -i WebAppX target/web-app-x.war
  artifacts:
    name: "policy-eval-$CI_JOB_NAME-$CI_COMMIT_REF_NAME"
    paths:
      - WebAppX-policy-eval-report.html

Create a custom Docker image

Here's a working Dockerfile that can be used to build a custom image, which contains the self-signed certificate:

FROM sonatype/gitlab-nexus-iq-pipeline
COPY iq-server.cert /certs/
RUN keytool -keystore /opt/java/openjdk/lib/security/cacerts -storepass changeit -noprompt -trustcacerts -importcert -alias iq-server -file /certs/iq-server.cert

The image can be built (replace your-org and the image version with meaningful values) e.g.

docker build -t your-org/gitlab-nexus-iq-pipeline:1.0.0 .

Then it can be published and used for policy evaluations e.g.

iq_policy_eval:
  stage: test
  image: your-org/gitlab-nexus-iq-pipeline:1.0.0
  script:
    - /sonatype/evaluate -i WebAppX target/web-app-x.war
  artifacts:
    name: "policy-eval-$CI_JOB_NAME-$CI_COMMIT_REF_NAME"
    paths:
      - WebAppX-policy-eval-report.html