Container Security: Qualys and GitLab CI/CD Integration

Container Security: Qualys and GitLab CI/CD Integration

In a development logic based on a containerized environment, it is important to check if during the CI/CD pipeline the released container meets the defined security criteria. Qualys already has plugins available to perform the previously mentioned checks; but currently, they are available for Jenkins and Bamboo only. This article addresses the matter of integrating the Container Security module directly into Gitlab’s CI/CD tool, and it also provides some useful inputs to create a direct integration between Qualys and GitLab.


  1. Active Container Security module in your Qualys instance
  2. Active API module in your Qualys instance

Container Security sensor deployment

The first step of the procedure involves the deployment of the CI/DC dedicated Container Security Sensor. It is recommended to install it on the machine that handles the container build during the CI/CD process.

Download deploy Qualys Container Sensor

Download the Build (CI/CD) sensor and follow the steps illustrated by the wizard on the Qualys platform.

Download deploy Qualys Container Sensor

How the CI/CD Sensor works

The sensor automatically scans images that are labeled with the “qualys_scan_target:”. Moreover, it can be removed it if there are multiple tags. The data is then uploaded to the Qualys Platform.

GitLab Integration

1. Modify the Pipeline to tag the container you are building

The example we provide in this article includes three different stages. A first build part, followed by the release, consists of pushing the docker image in the registry. The deployment process comes after and the application is so officially released in Kubernetes environment. When modifying the build phase, the following conditions are to be met:

a) the container has to receive the tag ‘qualys_scan_target:’ to inform the sensor that the image must be analyzed and scanned;

b) contact the Qualys Cloud platform via API to gather the scanned data.

Point a) is easily achieved by modifying the pipeline:

   stage: build
   - IMAGE_ID=$(docker build -q -t qualys_scan_target:test-app-$RELEASE.$CI_PIPELINE_ID -t test-app:$RELEASE.$CI_PIPELINE_ID -f Dockerfile-app . | cut -c8-19)

When the script is performed, it launches docker build in the background that, in order words, doesn’t show any output neither on the GUI nor the terminal. During this process, the image is tagged as follows:

  • qualys_scan_target:test-app-$RELEASE.$CI_PIPELINE_ID

The command returns the Image ID in an untruncated format, such as:


In fact, on Qualys, images are presented/indexed as such. Moreover, they are obtained from their full and complete version, where the “sha256:” part is deleted and the next 12 characters are selected. To accomplish this task of reducing the Image ID, we recommend to apply -cut –which is required to make API calls toward the Qualys Cloud Platform.

2. Identification of vulnerabilities via API

Consequently, to the build procedure, the next step is to perform a script that connects to the Qualys Cloud Platform to get the list of all vulnerabilities once the scan is complete.

To contact the cloud, it is necessary to authenticate on the platform to get an access token, and then query the API to receive all desired metrics. The easiest way to test the process is to create a BASH script that utilizes the Qualys credentials to login, as well as the image ID of the image to analyze. The username and password can be saved as environment variables in the GitLab CI/CD process settings.

Processo CI-CD di GitLab

In this sample case we added the bash script in the directory dedicated to the gitlab-runner user, but it is recommended to integrate the script in a vulnerability analysis dedicated container.

       - IMAGE_ID=$(docker build -q -t qualys_scan_target:socialhive-app-$RELEASE.$CI_PIPELINE_ID -t socialhive-app:$RELEASE.$CI_PIPELINE_ID -f Dockerfile-app . | cut -c8-19)
       - sh /home/gitlab-runner/ -u $qualys_username -p $qualys_password -I $IMAGE_ID

Script sample:

In the example above, the API query outputs the vulnerability number related to the analyzed image. The returned data is checked only for the most critical vulnerabilities – those of 4 and 5 severity level. Based on this information, it is possible to calculate a risk index by assigning a risk value weight to each vulnerability of a specific severity level. In the code example this article provides, a weight of value 3 is assigned to each vulnerability of severity 5, while the value 1 is assigned to vulnerabilities of severity 4. If the risk weight exceeds a defined threshold (in example 10), the script exits outputs error code 1. This process blocks the pipeline preventing the user to proceed to the next steps of release and deployment. Here is an example:

The script has been modified by blocking the pipeline if the $risk variable is greater than 0, hence if there is at least one vulnerability whose critical level if either 4 or 5. By looking at the output of the build-app-backend process, it reveals that the pipeline blocked a vulnerability of severity level 5.

esempio script

On the contrary, the build-app-cdn process passed, as the analysis of the image verified the presence of no vulnerability.

esempio script 2

The script we provided is of a basic level, the aim of the presentation is to inform the audience on how to integrate the Qualys Container Sensor with the GitLab pipeline and access to all the information via API.