Contributed by Karan Kumar (@karanibm6) originally published on shipwright.io
![Building Secure Container Images with Shipwright](https://cd.foundation/wp-content/uploads/sites/78/2024/07/Container-Images-Shipwright-1024x536.png)
Introduction
In the modern software development era, containers have become an essential tool for developers. They offer a consistent environment for applications to run, making it easier to develop, test, and deploy software across different platforms. However, like any other technology, containers are not immune to security vulnerabilities. This is where vulnerability scanning for container images becomes crucial. In this blog, we will discuss how to run vulnerability scanning on container images with Shipwright while building those images.
Before jumping into this feature, let’s explain what Shipwright is and why vulnerability scanning is important.
What is Shipwright
Shipwright is an open source framework designed to facilitate the building of container images directly within Kubernetes environments. It aims to streamline the development and deployment process by providing a native Kubernetes solution for creating container images from source code. Shipwright supports multiple build strategies and tools, such as Kaniko, Paketo Buildpacks, Ko, Buildkit, and Buildah, providing flexibility and extensibility to meet various application needs. This Kubernetes-native solution helps ensure that container images are built efficiently and securely, leveraging the strengths of the Kubernetes ecosystem.
Shipwright consists of four core components:
- Build: defines what source code you are trying to build from, and where the resulting container image should be publish (the what and where?)
- BuildRun: defines the when to trigger the building mechanism, telling the Kubernetes cluster when to build your application (the when?)
- BuildStrategy and ClusterBuildStrategy: defines how your application is assembled and which build tool to use (how to build?)
You can learn more by visiting this link.
Why is Vulnerability Scanning Important?
Vulnerability scanning for container images involves examining the image for known security vulnerabilities. This is typically done using automated tools that compare the contents of the image against a database of known vulnerabilities. The key reasons for Vulnerability Scanning are:
- Security: Containers often include third-party libraries and dependencies, which might have known vulnerabilities. If these vulnerabilities are exploited, they can lead to data breaches, unauthorized access, and other security incidents.
- Compliance: Many industries have regulatory requirements that mandate regular security assessments, including vulnerability scanning. Ensuring your container images are free from known vulnerabilities helps meet these compliance standards.
- Stability: Vulnerabilities can also impact the stability and performance of your applications. By identifying and fixing these issues early, you can maintain the reliability of your software.
There are many popular tools available for vulnerability scanning of container images, such as Clair, Trivy, Aqua Security, and Snyk.
In Shipwright, we use Trivy under the covers for vulnerability scanning, our rationale for choosing this tool can be found in our SHIP-0033.
Vulnerability Scanning in Shipwright
Before we dive into how it works, let’s explore the features offered by Shipwright for vulnerability scanning of container builds :
spec:
output:
vulnerabilityScan:
enabled: true
failOnFinding: true #image won't be push to registry if set to true
ignore:
issues:
- CVE-2022-12345 #specify list of cve to be ignored
severity: Low | Medium | High | Critical
unfixed: true #ignores the unfixed vulnerabilities
Configuration Options
- vulnerabilityScan.enabled: Specify whether to run vulnerability scan for image. The supported values are true and false.
- vulnerabilityScan.failOnFinding: Indicates whether to fail the build run if the vulnerability scan results in vulnerabilities. The supported values are true and false. This field is optional and false by default.
- vulnerabilityScan.ignore.issues: References the security issues to be ignored in vulnerability scan
- vulnerabilityScan.ignore.severity: Denotes the severity levels of security issues to be ignored, valid values are:
- low: it will exclude low severity vulnerabilities, displaying only medium, high, and critical vulnerabilities.
- medium: it will exclude low and medium-severity vulnerabilities, displaying only high and critical vulnerabilities.
- high: it will exclude low, medium, and high-severity vulnerabilities, displaying only the critical vulnerabilities.
- vulnerabilityScan.ignore.unfixed: Indicates to ignore vulnerabilities for which no fix exists. The supported types are true and false.
Let’s dive right in
Now, let’s see vulnerability scanning for a container image with Shipwright in action. If you want to try out in kind cluster, follow the steps from this section until you create the push secret. As a next step, create a build object with vulnerability scanning enabled, replacing <REGISTRY_ORG> with the registry username your push-secret have access to:
REGISTRY_ORG=<your_registry_org>
cat <<EOF | kubectl apply -f -
apiVersion: shipwright.io/v1beta1
kind: Build
metadata:
name: buildah-golang-build
spec:
source:
type: Git
git:
url: https://github.com/shipwright-io/sample-go
contextDir: docker-build
strategy:
name: buildah-shipwright-managed-push
kind: ClusterBuildStrategy
paramValues:
- name: dockerfile
value: Dockerfile
output:
image: docker.io/${REGISTRY_ORG}/sample-golang:latest
pushSecret: push-secret
vulnerabilityScan:
enabled: true
failOnFinding: true # if set to true, then the image won't be pushed to the registry
EOF
To view the Build which you just created:
$ kubectl get builds
NAME REGISTERED REASON BUILDSTRATEGYKIND BUILDSTRATEGYNAME CREATIONTIME
buildah-golang-build True Succeeded ClusterBuildStrategy buildah-shipwright-managed-push 72s
Now submit your buildrun
cat <<EOF | kubectl create -f -
apiVersion: shipwright.io/v1beta1
kind: BuildRun
metadata:
generateName: buildah-golang-buildrun-
spec:
build:
name: buildah-golang-build
EOF
Wait until your BuildRun is completed and then you can view it as follows:
$ kubectl get buildruns
NAME SUCCEEDED REASON STARTTIME COMPLETIONTIME
buildah-golang-buildrun-s9gsh False VulnerabilitiesFound 2m54s 98s
Here, you can see that the buildrun failed with reason VulnerabilitiesFound
and it will not push the image to the registry as the failOnFinding option is set to true.
And one can find the list of vulnerabilities in the build run under the .status.output
path:
apiVersion: shipwright.io/v1beta1
kind: BuildRun
metadata:
creationTimestamp: "2024-07-08T08:03:18Z"
generateName: buildah-golang-buildrun-
generation: 1
labels:
build.shipwright.io/generation: "1"
build.shipwright.io/name: buildah-golang-build
name: buildah-golang-buildrun-s9gsh
namespace: default
resourceVersion: "19926"
uid: f3c558e9-e027-4f59-9fdc-438a31c6de11
spec:
build:
name: buildah-golang-build
status:
buildSpec:
output:
image: docker.io/karanjmu92/sample-golang:latest
pushSecret: push-secret
vulnerabilityScan:
enabled: true
failOnFinding: true
paramValues:
- name: dockerfile
value: Dockerfile
source:
contextDir: docker-build
git:
url: https://github.com/shipwright-io/sample-go
type: Git
strategy:
kind: ClusterBuildStrategy
name: buildah-shipwright-managed-push
completionTime: "2024-07-08T08:04:34Z"
conditions:
- lastTransitionTime: "2024-07-08T08:04:34Z"
message: Vulnerabilities have been found in the image which can be seen in the
buildrun status. For detailed information,see kubectl --namespace default logs
buildah-golang-buildrun-s9gsh-w488m-pod --container=step-image-processing
reason: VulnerabilitiesFound
status: "False"
type: Succeeded
failureDetails:
location:
container: step-image-processing
pod: buildah-golang-buildrun-s9gsh-w488m-pod
output:
vulnerabilities:
- id: CVE-2023-24538
severity: critical
- id: CVE-2023-24540
severity: critical
.
.
.
- id: CVE-2024-24791
severity: medium
source:
git:
branchName: main
commitAuthor: OpenShift Merge Robot
commitSha: 96afb4108fba22e91f42168d8babb5562ac8e5bb
timestamp: "2023-08-10T15:24:45Z"
startTime: "2024-07-08T08:03:18Z"
taskRunName: buildah-golang-buildrun-s9gsh-w488m
Conclusion
Shipwright offers a robust and flexible solution for building container images within Kubernetes environments. By integrating vulnerability scanning directly into the build process, Shipwright ensures that container images are secure and compliant with Industry Standards and gets closer to Supply Chain Security Best Practices.