The scenario is:
- Vulnerability scanning with NeuVector as part of a AWS CodeBuild phase
- Sending the scan result report back to a NeuVector controller
- Pushing the image to a registry if no high severity vulnerabilities were found
The two key elements are, scanning local before pushing to a registry, sending the scan report to NeuVector for further processing and reporting.
This repository contains example code which was covered in a Blog and demonstrated in the talks:
- SUSECON 24: [TUTORIAL-1156] NeuVector Integration into AWS CodePipeline CI/CD Workflow
- openSUSE Conference 24: NeuVector Integration into AWS CodePipeline CI/CD workflow
The repository contains a sample buildspec.yaml
to configure AWS CodeBuild and a scan.sh
script to perform the NeuVector scan operation.
Actions performed inside AWS CodeBuild phases.
install
- Generate 8 digit git commit hash
- Retrieve ECR credentials and login to registry
- Make
scan.sh
executable
pre-build
- Start local docker registry (see Digest/RepoDigest value Workaround)
build
- local docker image build and tagging
- push to local registry
- perform NeuVector scan
post-build
- If
build
phase was successful, push image to ECR withlatest
and<commit_hash>
as label.
To apply the shared information, an understanding of AWS CodeBuild and it's terminology is expected.
We make assumptions that the surrounding infrastructure is already created and in a working state.
This includes:
- A CI/CD pipeline setup, for example AWS CodePipeline.
- A running NeuVector installation with an exposed controller API that is reachable inside your VPC.
- CodeBuild configured to connect for VPC connectivity.
- A user in NeuVector with the necessary permissions to upload a scan report
- The user password is saved in AWS Secrets Manager. If this is not the case, then the example
buildspec.yaml
has to be adjusted accordingly. - A second input source called
buildscripts
that contains thescan.sh
script. You can of course refactor this part in thebuildspec.yaml
and adjust it based on your needs. - Setting the AWS CodeBuild Environment to Privileged, this is required by the NeuVector standalone scanner to run.
If you are not interested in puhsing the scan results to NeuVector, then you don't need a NeuVector installation.
The buildspec.yaml
file requires that multiple environment variables are set based on your individual setup.
NV_USERNAME
= User that uploads the scan results to NeuVectorNV_CONTROLLER
= NeuVector Controller API IP or URL that is used to upload the scan resultsOCIREPO
= Name of the image repositoryOCIREPOURI
= URL of the image repositoryOCINAME
= Name of the application / image. Mainly used for the local scan and as name when uploading to NeuVectorNV_PASSWORD
= Password to authenticate against the NeuVector API. Recommend to create it in AWS Secrets Manager. If you decide to add the password in cleartext to yourbuildspec.yaml
(not recommended), then please remove the linesecrets-manager:
and addNV_PASSWORD
including it's value to the regular environment variables.
Please see Build specification reference for CodeBuild for general questions about the syntax and functionality of the buildspec.yaml
file.
A standalone scan will create a scan_results.json
file. This file is parsed in scan.sh
by using jq
to get the count of found high, medium and low severity vulnerabilities. Also to decide if a scan has failed, defined by high severity vulnerability count greater than 0.
To submit the report to a NeuVector Controller, three environment variables need to be passed to the neuvector/scanner
container:
-e SCANNER_CTRL_API_USERNAME=<value> \
-e SCANNER_CTRL_API_PASSWORD=<value> \
-e CLUSTER_JOIN_ADDR=<value> \
SCANNER_CTRL_API_USERNAME
and SCANNER_CTRL_API_PASSWORD
are mentioned in the NeuVector release notes. CLUSTER_JOIN_ADDR
is explained in NeuVector Documentation - Standalone scanner for local scanning.
Those variables are set via NV_USERNAME
, NV_PASSWORD
and NV_CONTROLLER
in the example buildspec.yaml
file and passed to neuvector/scanner
in scan.sh
.
If you are only interested in a standalone scan with fail
or pass
as outcome, don't pass the variables to the scanner.
When they are not set, then the results will not uploaded and the scanning works without a connection to a NeuVector installation.
NeuVector controller expects that a scan result that is submitted contains a value for Digest
or RepoDigest
.
Otherwise the upload fails with error ERRO|SCN|main.main: Failed to sumit scan result - error=Submit scan result failed with status code 400
.
When an image is build locally inside AWS CodeBuild via docker, then this value is missing.
This is per design and how docker
works in general. The value is generated and set as soon an image is pushed to a registry.
Build phase scanning of local images is considered a valid use-case of NeuVector.
Digest
or RepoDigest
should therefore not mandatory to submit scan results.
The issue is reported in the NeuVector upstream project: neuvector/neuvector#1423
In the pre_build
phase of this example, a local registry is started by running the command docker run -d -p 5000:5000 --name registry registry:2
.
docker build
adds an additional tag for this local registry. After a successful build, the image is pushed.
This generates the required value, but the image doesn't leave the CodeBuild environment at this point.
It satisfies the requirement from NeuVector to receive a Digest
value when submitting scan_results.json
.
See CONTRIBUTING for more information.
This library is licensed under the MIT-0 License. See the LICENSE file.