This topic provides an overview of Out of the Box Supply Chain with Testing and Scanning for Supply Chain Choreographer.
This package contains Cartographer Supply Chains that tie together a series of Kubernetes resources that drive a developer-provided workload from source code to a Kubernetes configuration ready to be deployed to a cluster. It contains supply chains that pass the source code through testing and vulnerability scanning, and also the container image.
This package includes all the capabilities of the Out of the Box Supply Chain With Testing, but adds source and image scanning using Grype.
Workloads that use source code or prebuilt images perform the following:
Building from source code:
Using a prebuilt application image:
To use this supply chain, verify that:
Verify that you have the supply chains with scanning, not with testing, installed by running:
tanzu apps cluster-supply-chain list
NAME LABEL SELECTOR
source-test-scan-to-url apps.tanzu.vmware.com/has-tests=true,apps.tanzu.vmware.com/workload-type=web
source-to-url apps.tanzu.vmware.com/workload-type=web
If you see source-test-to-url
in the list, the setup is wrong. You must not have the source-test-to-url
installed at the same time as source-test-scan-to-url
.
This example builds on the previous Out of the Box Supply Chain examples, so only additions are included here.
To ensure that you configured the namespace correctly, it is important that the namespace has the objects that you configured in the other supply chain setups:
registries secrets: Kubernetes secrets of type kubernetes.io/dockerconfigjson
that contain credentials for pushing and pulling the container images built by the supply chain and the installation of Tanzu Application Platform.
service account: The identity to be used for any interaction with the Kubernetes API made by the supply chain.
rolebinding: Grant to the identity the necessary roles for creating the resources prescribed by the supply chain.
For more information about the preceding objects, see Out of the Box Supply Chain Basic.
Tekton pipeline: A pipeline runs whenever the supply chain hits the stage of testing the source code.
For more information, see Out of the Box Supply Chain Testing.
And the new objects, that you create here:
scan policy: Defines what to do with the results taken from scanning the source code and image produced. For more information, see ScanPolicy section.
source scan template: A template of how TaskRuns are created for scanning the source code. See ScanTemplate section.
image scan template: A template of how TaskRuns are created for scanning the image produced by the supply chain. See ScanTemplate section.
The following section includes details about the new objects, compared to Out of the Box Supply Chain With Testing.
For source and image scans, scan templates and scan policies must exist in the same namespace as the workload. These define:
ScanTemplate
: how to run a scan, allowing one to change details about the execution of the scan (either for images or source code)
ScanPolicy
: how to evaluate whether the artifacts scanned are compliant. For example, allowing one to be either very strict, or restrictive about particular vulnerabilities found.
The names of the objects must match the names in the example with default installation configurations. This is overridden either by using the ootb_supply_chain_testing_scanning
package configuration in the tap-values.yaml
file or by using workload parameters:
To override by using the ootb_supply_chain_testing_scanning
package configuration, make the following modification to your tap-values.yaml
file and perform a Tanzu Application Platform update.
ootb_supply_chain_testing_scanning:
scanning:
source:
policy: SCAN-POLICY
template: SCAN-TEMPLATE
image:
policy: SCAN-POLICY
template: SCAN-TEMPLATE
Where SCAN-POLICY
and SCAN-TEMPLATE
are the names of the ScanPolicy
and ScanTemplate
.
To override through workload parameters, use the these commands.
tanzu apps workload apply WORKLOAD --param "scanning_source_policy=SCAN-POLICY" -n DEV-NAMESPACE
tanzu apps workload apply WORKLOAD --param "scanning_source_template=SCAN-TEMPLATE" -n DEV-NAMESPACE
Where:
WORKLOAD
is the name of the workload.SCAN-POLICY
and SCAN-TEMPLATE
are the names of the ScanPolicy
and ScanTemplate
.DEV-NAMESPACE
is the developer namespace.For more information, see Create or update a workload.
The ScanPolicy defines a set of rules to evaluate for a particular scan to consider the artifacts (image or source code) either compliant or not.
When a ImageScan or SourceScan is created to run a scan, those reference a policy whose name must match the following sample scan-policy
:
---
apiVersion: scanning.apps.tanzu.vmware.com/v1beta1
kind: ScanPolicy
metadata:
name: scan-policy
labels:
'app.kubernetes.io/part-of': 'enable-in-gui'
spec:
regoFile: |
package main
# Accepted Values: "Critical", "High", "Medium", "Low", "Negligible", "UnknownSeverity"
notAllowedSeverities := ["Critical", "High", "UnknownSeverity"]
ignoreCves := []
contains(array, elem) = true {
array[_] = elem
} else = false { true }
isSafe(match) {
severities := { e | e := match.ratings.rating.severity } | { e | e := match.ratings.rating[_].severity }
some i
fails := contains(notAllowedSeverities, severities[i])
not fails
}
isSafe(match) {
ignore := contains(ignoreCves, match.id)
ignore
}
deny[msg] {
comps := { e | e := input.bom.components.component } | { e | e := input.bom.components.component[_] }
some i
comp := comps[i]
vulns := { e | e := comp.vulnerabilities.vulnerability } | { e | e := comp.vulnerabilities.vulnerability[_] }
some j
vuln := vulns[j]
ratings := { e | e := vuln.ratings.rating.severity } | { e | e := vuln.ratings.rating[_].severity }
not isSafe(vuln)
msg = sprintf("CVE %s %s %s", [comp.name, vuln.id, ratings])
}
A ScanTemplate defines the PodTemplateSpec used by a TaskRun to run a particular scan (image or source). When the supply chain initiates an ImageScan or SourceScan, they reference these templates which must live in the same namespace as the workload with the names matching the following:
blob-source-scan-template
)private-image-scan-template
)You can install the Grype ScanTemplates in the namespace that you are writing the workload to with Namespace Provisioner. See Provision developer namespaces in Namespace Provisioner.
Label the namespace that you are writing the workload to, with the default namespace_selector apps.tanzu.vmware.com/tap-ns=""
, by running:
kubectl label namespaces YOUR-DEV-NAMESPACE apps.tanzu.vmware.com/tap-ns=""
NoteAlthough you can customize the templates, if you are following the Getting Started guide, VMware recommends that you follow what is provided in the installation of
grype.scanning.apps.tanzu.vmware.com
. For more information, see About Source and Image Scans.
To enable SCST - Scan to store scan results by using SCST - Store, see Developer namespace setup for exporting the SCST - Store CA certificate and authentication token to the developer namespace.
You can configure your developer namespace to include more than one pipeline using either of the following methods:
Use a single pipeline running on a container image that includes testing tools and runs a common script to execute tests. This allows you to accommodate multiple workloads based in different languages in the same namespace that use a common make test script, as shown in the following example:
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: developer-defined-tekton-pipeline
labels:
apps.tanzu.vmware.com/pipeline: test
spec:
#...
steps:
- name: test
image: <image_that_has_JDK_and_Go>
script: |-
cd `mktemp -d`
wget -qO- $(params.source-url) | tar xvz -m
make test
Update the pipeline resources to include labels that differentiate between the pipelines. For example, differentiate between Java and Go pipelines by adding labels for Java and Go:
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: java-tests
labels:
apps.tanzu.vmware.com/pipeline: test
apps.tanzu.vmware.com/language: java
spec:
#...
steps:
- name: test
image: gradle
script: |-
# ...
./mvnw test
---
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: go-tests
labels:
apps.tanzu.vmware.com/pipeline: test
apps.tanzu.vmware.com/language: go
spec:
#...
steps:
- name: test
image: golang
script: |-
# ...
go test -v ./...
To match the correct pipeline, you add a testing_pipeline_matching_labels
parameter to the workload. For example, if you want to match to the Java pipeline, you have the following workload.yaml
:
apiVersion: carto.run/v1alpha1
kind: Workload
metadata:
name: sample-java-app
labels:
apps.tanzu.vmware.com/has-tests: true
apps.tanzu.vmware.com/workload-type: web
app.kubernetes.io/part-of: sample-java-app
spec:
params:
- name: testing_pipeline_matching_labels
value:
apps.tanzu.vmware.com/pipeline: test
apps.tanzu.vmware.com/language: java
...
This matches the workload to the pipeline with the apps.tanzu.vmware.com/language: java
label.
With the ScanPolicy and ScanTemplate objects, with the required names set, submitted to the same namespace where the workload is submitted, you are ready to submit your workload.
Regardless of the workflow being targeted, such as local development or GitOps, the workload configuration details are the same as in Out of the Box Supply Chain Basic, except that you mark the workload as having tests enabled.
For example:
tanzu apps workload create tanzu-java-web-app \
--git-branch main \
--git-repo https://github.com/vmware-tanzu/application-accelerator-samples \
--sub-path tanzu-java-web-app \
--label apps.tanzu.vmware.com/has-tests=true \
--label app.kubernetes.io/part-of=tanzu-java-web-app \
--type web
Create workload:
1 + |---
2 + |apiVersion: carto.run/v1alpha1
3 + |kind: Workload
4 + |metadata:
5 + | labels:
6 + | apps.tanzu.vmware.com/workload-type: web
7 + | apps.tanzu.vmware.com/has-tests: "true"
8 + | app.kubernetes.io/part-of: tanzu-java-web-app
9 + | name: tanzu-java-web-app
10 + | namespace: default
11 + |spec:
12 + | source:
13 + | git:
14 + | ref:
15 + | branch: main
16 + | url: https://github.com/vmware-tanzu/application-accelerator-samples
17 + | subPath: tanzu-java-web-app
The Supply Chain halts progression if either a SourceScan (sourcescans.scanning.apps.tanzu.vmware.com
) or an ImageScan (imagescans.scanning.apps.tanzu.vmware.com
) fails policy enforcement through the ScanPolicy (scanpolicies.scanning.apps.tanzu.vmware.com
).
This can prevent source code from building or images deploying that contain vulnerabilities that are in violation of the user-defined scan policy. For information about learning how to handle these vulnerabilities and unblock your Supply Chain, see Triaging and Remediating CVEs.
Supply Chain Security Tools - Scan includes additional integrations for running an image scan using Snyk.