Why Inline Scanning?
There are many steps involved in building and deploying a containerized application, a complete container image lifecycle approach is key to managing software supply chain risks. The Lacework inline scanner allows you to integrate Lacework security capabilities deeply into your software supply chain workflows by allowing you to scan and assess Docker container images for vulnerabilities without checking them into a container registry.
When implementing the Lacework inline scanner into your Jenkins pipeline, you can scan an image built before it is ever pushed to a registry and reduce the risk of vulnerable containers being deployed.
How do I integrate inline scanning into my Jenkins pipeline?
The Lacework inline scanner releases are provided in binary form for various different architectures and OS choices, along with its source code. You can review the releases here.
There are several options available for building the scanner into your pipeline. If you use static build servers for your pipeline, it would make sense to have the scanner installed on the build machines and executing a scan on any newly built image in your pipelines. This saves time in your build process by not having to download the scanner with each build.
If you provision temporary build servers or do not want to keep the scanner installed on your build machines for another reason, you can deploy the scanner either by pulling the scanner into your build directory, by executing it from a docker container or via the Lacework Security Scanner plugin. While this option slightly increases your build times, it has the benefit of ensuring that you are always using the latest scanner version without having to update it on your build servers. In the next section, you can find example pipeline configurations for each scenario. Please review the inline scanner documentation for a more complete description of the features and options provided by the Lacework inline scanner.
Scenario 1 - Installing the Inline Scanner on my build machine(s)
1. For Linux or MacOS, log into your build machine and execute the commands below. Find the binary that corresponds to the OS and architecture of your build machine on the release page for the correct download link. For Windows, the corresponding .exe file should be used instead.
It is strongly recommended to move the lw-scanner binary to a location included in the jenkins user's $PATH such as /usr/bin/ as in the example below.
$ curl -L https://github.com/lacework/lacework-vulnerability-scanner/releases/latest/download/lw-scanner-linux-amd64 -o lw-scanner
$ chmod +x lw-scanner
$ mv /usr/bin/lw-scanner
2. Configure the scanner for authorization with your Lacework access token, provided when adding a new "Inline Scanner" integration from your container registry settings in the Lacework console:
$ lw-scanner configure auth
Account Name ():<account_name>
Access Token ():<access_token>
3. In your Jenkins pipeline configuration, you can now incorporate the inline scanner in a build stage:
stage('LW InlineScan') {
steps{
sh "lw-scanner image evaluate ${IMAGE_NAME} ${IMAGE_TAG} --build-id ${BUILD_ID} --save"
}
}
The above "sh" command has a multitude of available flags that you may wish to use. Please review the inline scanner documentation for examples and explanations for additional options.
Scenario 2a - leverage the inline scanner on build machines that do not have the scanner installed
1. When executing your build pipeline on a machine that does not have the scanner already installed, please be sure to set the following environment variables in your build plan, as secret text (configured in Jenkins with their respective credential IDs: lw_access_token & lw_account_name):
environment {
LW_ACCESS_TOKEN = credentials('lw_access_token')
LW_ACCOUNT_NAME = credentials('lw_account_name')
}
2. In your scanning stage, you can now include the `curl` and `chmod` commands from scenario 1 and execute the lw-scanner from the build directory.
stage('LW InlineScan') {
steps {
sh "curl -L https://github.com/lacework/lacework-vulnerability-scanner/releases/latest/download/lw-scanner-linux-amd64 -o lw-scanner"
sh "chmod +x lw-scanner"
sh "./lw-scanner image evaluate ${IMAGE_NAME} ${IMAGE_TAG} --build-id ${BUILD_ID} --save"
}
}
Scenario 2b - Executing the inline scanner from a docker container
Instead of executing the inline scanner from the build directory the build machine directly, you can alternatively use the "lacework/lacework-inline-scanner" docker image to execute the scan.
1. Please be sure to set the following environment variables in your build plan, as secret text (configured in Jenkins with their respective credential IDs: lw_access_token & lw_account_name):
environment {
LW_ACCESS_TOKEN = credentials('lw_access_token')
LW_ACCOUNT_NAME = credentials('lw_account_name')
}
2. Configure your scan stage to deploy the scanner image.
stage('LW InlineScan') {
steps{
sh "docker run \
-e LW_ACCOUNT_NAME=${LW_ACCOUNT_NAME} \
-e LW_ACCESS_TOKEN=${LW_ACCESS_TOKEN} \
-v /var/run/docker.sock:/var/run/docker.sock \
lacework/lacework-inline-scanner:latest \
image evaluate ${IMAGE_NAME} ${IMAGE_TAG} --build-id ${BUILD_ID} --save"
}
}
Scenario 2c - Using the Lacework Security Scanner Jenkins plugin
Lacework offers a Jenkins plugin that can be installed on your Jenkins server directly and provides functionality for pipelines. The plugin can manage your integration token and account name variables and allows scanner behavior to easily be managed in your pipelines. The plugin can be installed via the "Manage Plugins" setting menu. The official plugin documentation can be reviewed here.
1. Once the plugin has been installed, navigate to the "Configure System" menu in Jenkins and add your "Account Name" and "Access Token":
2. After the plugin has been configured with your access token and account name, it can be used either in a freestyle project or added as a stage in your pipeline script, using the following example syntax:
stage('LW InlineScan') {
steps{
lacework(imageName: "${IMAGE_NAME}",
imageTag: "${IMAGE_TAG}",
customFlags: "",
fixableOnly: true,
noPull: true,
evaluatePolicies: true,
saveToLacework: true,
disableLibraryPackageScanning: false,
showEvaluationExceptions: true,
tags: "")
}
}
Example Pipeline
The following example Jenkins pipeline, pulls a Dockerfile from a GitHub repository, executes a 'docker build' and scans the image before pushing it to an ECR repository. This pipeline requires 'curl', 'docker cli' as well as the 'aws cli' to be installed on the build machine.
pipeline {
environment {
registry = "123456789.dkr.ecr.us-east-1.amazonaws.com/myimage"
region = "us-east-1"
tag = "latest"
dockerImage = ''
LW_ACCESS_TOKEN = credentials('lw_access_token')
LW_ACCOUNT_NAME = credentials('lw_account_name')
}
agent any
stages {
stage('Cloning Git') {
steps {
git branch: 'main', url: 'https://github.com/user/repo.git'
}
}
stage('Building image') {
steps{
script {
dockerImage = docker.build registry +":$tag"
}
}
}
stage('Docker login') {
steps{
sh "docker login -u AWS -p \$(aws ecr get-login-password --region ${region}) 123456789.dkr.ecr.us-east-1.amazonaws.com"
}
}
stage('LW InlineScan') {
steps{
sh "docker run \
-e LW_ACCOUNT_NAME=${LW_ACCOUNT_NAME} \
-e LW_ACCESS_TOKEN=${LW_ACCESS_TOKEN} \
-v /var/run/docker.sock:/var/run/docker.sock \
lacework/lacework-inline-scanner:latest \
image evaluate ${registry} ${tag} --build-id ${BUILD_ID} --save"
}
}
stage('Push Image') {
steps{
script {
docker.withRegistry("https://" + registry) {
dockerImage.push()
}
}
}
}
}
}
Reviewing Results
Unless output of the build stage is suppressed on purpose (eg. &>/dev/null), you can review the scanner findings directly from the console output of the build:
In addition to the console output, if the '--save' flag is used, the results will also be populated in your Lacework dashboard for review. Other flags such as in the example from the image above (--html-file) allow the scan output to be saved in a file and specific formatting, in the build directory and archived as artifact if so desired. For a complete list of available flags, please review the documentation.