This topic describes how you can install SCST - Scan (Trivy) from the VMware package repository.
CautionThis integration is in alpha, which means that it is still in early development by the Tanzu Practice Global Tech Team and might be subject to change at any point. You might encounter unexpected behavior.
List available tags by running:
imgpkg tag list -i projects.registry.vmware.com/tanzu_practice/tap-scanners-package/trivy-repo-scanning-bundle | sort -V
For example:
$ imgpkg tag list -i projects.registry.vmware.com/tanzu_practice/tap-scanners-package/trivy-repo-scanning-bundle | sort -V
0.1.0-alpha.19
0.1.4-alpha.1
0.1.4-alpha.3
0.1.4-alpha.5
0.1.4-alpha.6
0.1.4-alpha.7
0.1.4-alpha.9
0.1.4-alpha.10
0.1.4-alpha.11
0.1.5-alpha.1
0.1.5-alpha.2
0.1.5-alpha.3
0.1.6-alpha.1
0.1.6-alpha.2
0.1.6-alpha.4
0.1.6-alpha.6
0.1.6-alpha.7
0.1.7-alpha.1
Use the latest alpha version available for your version of Tanzu Application Platform.
For example, given the example output if you are using Tanzu Application Platform v1.4, you use 0.1.4-alpha.11
.
You must relocate the images from tanzu.packages.broadcom.com
to your own container image registry before installing.
Trivy is in the alpha development phase, is not packaged as part of the Tanzu Application Platform package, and is hosted on tanzu.packages.broadcom.com
.
For information about supported registries, see the registry’s documentation.
To move images from the VMware project registry to your registry:
Install Docker if it is not already installed.
Set up environment variables for installation by running:
export INSTALL_REGISTRY_USERNAME=MY-REGISTRY-USER
export INSTALL_REGISTRY_PASSWORD=MY-REGISTRY-PASSWORD
export INSTALL_REGISTRY_HOSTNAME=MY-REGISTRY
export VERSION=VERSION-NUMBER
export INSTALL_REPO=TARGET-REPOSITORY
Where:
MY-REGISTRY-USER
is the user with write access to MY-REGISTRY
.MY-REGISTRY-PASSWORD
is the password for MY-REGISTRY-USER
.MY-REGISTRY
is your own registry.VERSION
is your Trivy version. For example, 0.1.4-alpha.6
.TARGET-REPOSITORY
is your target repository, a directory, or a repository on MY-REGISTRY
that serves as the location for the installation files for Trivy.Install the Carvel tool imgpkg CLI. For more information, see Deploying Cluster Essentials v1.4.
Move the images with the imgpkg CLI by running:
imgpkg copy -b projects.registry.vmware.com/tanzu_practice/tap-scanners-package/trivy-repo-scanning-bundle:${VERSION} \
--to-repo ${INSTALL_REGISTRY_HOSTNAME}/${INSTALL_REPO}/trivy-repo-scanning-bundle
NoteThe VMware project repository does not require authentication, so you don’t need to perform a Docker login.
Tanzu CLI packages are available on repositories. Adding the Trivy scanning package repository makes the Trivy scanning bundle and its packages available for installation.
VMware recommends installing Trivy objects in the existing tap-install
namespace to keep Trivy grouped logically with the other Tanzu Application Platform components.
Add the Trivy package repository to the cluster by running:
tanzu package repository add trivy-scanner-repository \
--url ${INSTALL_REGISTRY_HOSTNAME}/${INSTALL_REPO}/trivy-repo-scanning-bundle:$VERSION \
--namespace tap-install
Get the status of the Trivy package repository, and ensure that the status updates to Reconcile succeeded
, by running:
tanzu package repository get trivy-scanner-repository --namespace tap-install
For example:
$ tanzu package repository get trivy-scanner-repository --namespace tap-install
NAME: trivy-scanner-repository
VERSION: 7750726
REPOSITORY: projects.registry.vmware.com/tanzu_practice/tap-scanners-package/trivy-repo-scanning-bundle
TAG: 0.1.4-alpha.6
STATUS: Reconcile succeeded
REASON:
List the available packages by running:
tanzu package available list --namespace tap-install
For example:
$ tanzu package available list --namespace tap-install
/ Retrieving available packages...
NAME DISPLAY-NAME SHORT-DESCRIPTION
trivy.scanning.apps.tanzu.vmware.com trivy Default scan templates using Trivy
Before installing Trivy, you must create the configuration for installing Trivy:
Define the --values-file
flag to customize the default configuration. You must define the following fields in the values.yaml
file for the Trivy Scanner configuration. You can add fields as needed to activate or deactivate behaviors. You can append the values to the values.yaml
file. Create a values.yaml
file by using the following configuration:
---
namespace: DEV-NAMESPACE
targetImagePullSecret: TARGET-REGISTRY-CREDENTIALS-SECRET
targetSourceSshSecret: TARGET-SOURCE-SSH-SECRET
Where:
DEV-NAMESPACE
is your developer namespace. To use a namespace other than the default namespace, ensure that the namespace exists before you install. If the namespace does not exist, the scanner installation fails.TARGET-REGISTRY-CREDENTIALS-SECRET
is the name of the secret that contains the credentials to pull an image from a private registry for scanning.TARGET-SOURCE-SSH-SECRET
is the name of the secret containing SSH credentials for cloning private repositoriesTo see all available values, run the following command with the version that you want:
VERSION="0.1.4-alpha.6"
tanzu package available get trivy.scanning.apps.tanzu.vmware.com/$VERSION --values-schema -n tap-install
Example output:
KEY DEFAULT TYPE DESCRIPTION
environmentVariables <nil> <nil> Environment Variables you want added to the scan container to impact trivy behavior
resources.limits.cpu 1000m string Limits describes the maximum amount of cpu resources allowed.
resources.requests.cpu 250m string Requests describes the minimum amount of cpu resources required.
resources.requests.memory 128Mi string Requests describes the minimum amount of memory resources
scanner.docker.server string <nil>
scanner.docker.username string <nil>
scanner.docker.password string <nil>
scanner.pullSecret string <nil>
scanner.serviceAccount trivy-scanner string Name of scan pod's service ServiceAccount
scanner.serviceAccountAnnotations <nil> <nil> Annotations added to ServiceAccount
trivy.cli.image.additionalArguments string additional arguments to be appended to the image scan command
trivy.cli.plugins.aqua.repositoryUrl string location of the aqua plugin tar in an OCI registry to be used in place of the embedded version
trivy.cli.repositoryUrl string location of the CLI tar in an OCI registry to be used in place of the embedded version
trivy.cli.source.additionalArguments string additional arguments to be appended to the fs scan command
trivy.db.repositoryUrl string location of the vulnerability database in an OCI registry to be used as the download location prior to running a scan
caCertSecret string Reference to the secret containing the registry ca cert set as ca_cert_data
metadataStore.authSecret.importFromNamespace string Namespace from which to import the Insight Metadata Store auth_token
metadataStore.authSecret.name string Name of deployed Secret with key auth_token
metadataStore.caSecret.importFromNamespace metadata-store string Namespace from which to import the Insight Metadata Store CA Cert
metadataStore.caSecret.name app-tls-cert string Name of deployed Secret with key ca.crt holding the CA Cert of the Insight Metadata Store
metadataStore.clusterRole metadata-store-read-write string Name of the deployed ClusterRole for read/write access to the Insight Metadata Store deployed in the same cluster
metadataStore.url https://metadata-store-app.metadata-store.svc.cluster.local:8443 string Url of the Insight Metadata Store
namespace default string Deployment namespace for the Scan Templates
targetImagePullSecret string Reference to the secret used for pulling images from private registry
targetSourceSshSecret string Reference to the secret containing SSH credentials for cloning private repositories
Trivy integration can work with or without the SCST - Store integration. The values.yaml
file is slightly different for each configuration.
To persist the results found by the Trivy, enable the SCST - Store integration by appending the SCST - Scan fields to Trivy in the values.yaml
file.
The Grype, Snyk, Prisma, Carbon Black, and Trivy integrations enable the Metadata Store. To prevent conflicts, the configuration values are slightly different based on whether another scanner integration is installed or not. If Tanzu Application Platform was installed by using the Full Profile, the Grype Scanner integration is installed unless it is explicitly excluded.
values.yaml
by looking at the configuration of an installed scanner in the same namespace as it already exists.
For information about how the scanner was initially created, see Set up multicluster Supply Chain Security Tools (SCST) - Store.
The following example values.yaml
has other scanners already installed in the same dev-namespace
where Trivy is installed:
#! ...
metadataStore:
#! The url where the Store deployment is accessible.
#! Default value is: "https://metadata-store-app.metadata-store.svc.cluster.local:8443"
url: "STORE-URL"
caSecret:
#! The name of the secret that contains the ca.crt to connect to the Store Deployment.
#! Default value is: "app-tls-cert"
name: "CA-SECRET-NAME"
importFromNamespace: "" #! since both Trivy and Grype/Snyk both enable store, one must leave importFromNamespace blank
#! authSecret is for multicluster configurations.
authSecret:
#! The name of the secret that contains the auth token to authenticate to the Store Deployment.
name: "AUTH-SECRET-NAME"
importFromNamespace: "" #! since both Trivy and Grype/Snyk both enable store, one must leave importFromNamespace blank
Where:
STORE-URL
is the URL where the Store deployment is accessible.CA-SECRET-NAME
is the name of the secret that contains the ca.crt
to connect to the Store Deployment. The default is app-tls-cert
.AUTH-SECRET-NAME
is the name of the secret that contains the authentication token to authenticate to the Store Deployment.The following example values.yaml
has no other scanner integrations installed in the same dev-namespace
where Trivy is installed:
#! ...
metadataStore:
#! The url where the Store deployment is accessible.
#! Default value is: "https://metadata-store-app.metadata-store.svc.cluster.local:8443"
url: "STORE-URL"
caSecret:
#! The name of the secret that contains the ca.crt to connect to the Store Deployment.
#! Default value is: "app-tls-cert"
name: "CA-SECRET-NAME"
#! The namespace where the secrets for the Store Deployment live.
#! Default value is: "metadata-store"
importFromNamespace: "STORE-SECRETS-NAMESPACE"
#! authSecret is for multicluster configurations.
authSecret:
#! The name of the secret that contains the auth token to authenticate to the Store Deployment.
name: "AUTH-SECRET-NAME"
#! The namespace where the secrets for the Store Deployment live.
importFromNamespace: "STORE-SECRETS-NAMESPACE"
Where:
STORE-URL
is the URL where the Store deployment is accessible.CA-SECRET-NAME
is the name of the secret that contains the ca.crt
to connect to the Store Deployment. Default is app-tls-cert
.STORE-SECRETS-NAMESPACE
is the namespace where the secrets for the Store Deployment live. Default is metadata-store
.AUTH-SECRET-NAME
is the name of the secret that contains the authentication token to authenticate to the Store Deployment.values.yaml
file that is enabled by default:
# ...
metadataStore:
url: "" # Deactivate Supply Chain Security Tools - Store integration
The following sample ScanPolicy
allows you to control whether SupplyChain
passes or fails based on the CycloneDX vulnerability results returned from the Trivy.
---
apiVersion: scanning.apps.tanzu.vmware.com/v1beta1
kind: ScanPolicy
metadata:
name: trivy-scan-policy
labels:
app.kubernetes.io/part-of: enable-in-gui
spec:
regoFile: |
package main
import future.keywords.in
import future.keywords.every
# Accepted Values: "critical", "high", "medium", "low", unknown"
notAllowedSeverities := ["critical", "high", "unknown"]
notAllowedSet := {x | x := notAllowedSeverities[_]}
ignoreCves := []
isSafe(match) {
severities := { e | e := match.ratings.rating.severity } | { e | e := match.ratings.rating[_].severity }
every severity in severities {
not severity in notAllowedSet
}
}
isIgnored(match) {
match.id in ignoreCves
}
deny[msg] {
notAllowedVulnerabilities := { vulnerability |
vulnerabilities := {e | e := input.bom.vulnerabilities.vulnerability} | {e | e := input.bom.vulnerabilities.vulnerability[_]}
some vulnerability in vulnerabilities
not isIgnored(vulnerability)
not isSafe(vulnerability)
}
formattedVulnerabilityMessages := { message |
some vulnerability in notAllowedVulnerabilities
ratings := {e | e := vulnerability.ratings.rating.severity} | {e | e := vulnerability.ratings.rating[_].severity}
formattedRatings := concat(", ", ratings)
affectedComponents := {e | e := vulnerability.affects.target.ref} | {e | e := vulnerability.affects.target[_].ref}
formattedComponents := concat("\\n", affectedComponents)
message = sprintf("CVE: %s \\nRatings: %s\\nAffected Components: \\n%s", [vulnerability.id, formattedRatings, formattedComponents])
}
some formattedVulnerabilityMessage in formattedVulnerabilityMessages
msg := formattedVulnerabilityMessage
}
To prepare ScanPolicy
, run:
kubectl apply -n $DEV-NAMESPACE -f SCAN-POLICY-YAML-FILE
Where:
DEV-NAMESPACE
is the name of the developer namespace you want to use.SCAN-POLICY-YAML-FILE
is the name of your SCST - Scan YAML file.After the following prerequisites are completed, install the Trivy:
This section explains how to configure Trivy in an air-gapped environment.
For information about additional flags and configuration, see Air-Gapped Environment in the Trivy documentation.
If you have a host with access, you can use the ORAS CLI to perform a copy by running:
oras copy -r ghcr.io/aquasecurity/trivy-db:2 registry.company.com/project_name/trivy-db:2 # the tag of 2 is required
Copying 4a39b38cf2fd db.tar.gz
Copied 4a39b38cf2fd db.tar.gz
Copied ghcr.io/aquasecurity/trivy-db:2 => registry.company.com/project_name/trivy-db:2
Digest: sha256:ed57874a80499e858caac27fc92e4952346eb75a2774809ee989bcd2ce48897a
CautionUsing a relocated database means you are taking responsibility for keeping it up to date to ensure that security scans are relevant. Stale databases weaken your security posture.
If you do not have a host with access, you can use the ORAS CLI to download the database and manifest and then push to your registry:
Download the trivy-db
by running:
oras pull ghcr.io/aquasecurity/trivy-db:2
Example output:
$ oras pull ghcr.io/aquasecurity/trivy-db:2
Downloading 1612cc15d377 db.tar.gz
Downloaded 1612cc15d377 db.tar.gz
Pulled ghcr.io/aquasecurity/trivy-db:2
Digest: sha256:af903c7ddbe7516f18b06254b6297cf53c0ece918def07322925c71d2f694860
Download the manifest for trivy-db
by running:
oras manifest fetch ghcr.io/aquasecurity/trivy-db:2 > trivy-db-manifest.json
Add the media type to the manifest by running:
jq '.mediaType="application/vnd.oci.image.manifest.v1+json"' trivy-db-manifest.json > updated-trivy-db-manifest.json
Push the downloaded trivy-db
to your registry by running:
oras push registry.company.com/project_name/trivy-db:2 ./db.tar.gz
Example output:
oras push registry.company.com/project_name/trivy-db:2 \
./db.tar.gz
Uploading 1612cc15d377 db.tar.gz
Uploaded 1612cc15d377 db.tar.gz
Pushed registry.company.com/project_name/trivy-db:2
Digest: sha256:41a7eeab8837e90d8a5afd56cfce73936e15d3db04c5294f992ecff9492971dc
Push the updated trivy-db
manifest to your registry by running:
oras manifest push registry.company.com/project_name/trivy-db:2 updated-trivy-db-manifest.json
Example output:
oras manifest push registry.company.com/project_name/trivy-db:2 updated-trivy-db-manifest.json
Pushed registry.company.com/project_name/trivy-db:2
Digest: sha256:b51a2fccf38e723aac1a7217ba36ca52398b2b20e3d74c9d5089dfdcd9bb2f11
Clean up files by running:
rm trivy-db-manifest.json updated-trivy-db-manifest.json db.tar.gz
Update data values with the database repository URL by adding this YAML to values.yaml
:
trivy:
db:
repositoryUrl: "registry.company.com/project_name/trivy-db"
The URL omits the tag 2
.
This section describes how to use a different Trivy CLI version than what is bundled with the package. To use another Trivy version:
Install the ORAS CLI by following steps in the ORAS documentation.
Download the CLI version that you want from the GitHub releases page.
For example, by running:
$ wget -c https://github.com/aquasecurity/trivy/releases/download/v0.36.0/trivy_0.36.0_Linux-64bit.tar.gz -O trivy.tar.gz
Length: 48363295 (46M) [application/octet-stream]
Saving to: ‘trivy.tar.gz’
trivy.tar.gz 100%[==>] 46.12M 50.7MB/s in 0.9s
2023-01-25 10:47:55 (50.7 MB/s) - ‘trivy.tar.gz’ saved [48363295/48363295]
Move the CLI to your registry by running:
oras push registry.company.com/project_name/trivy-cli:0.36.0 \
--artifact-type trivy/cli \
./trivy.tar.gz:application/gzip
Uploading 121f4d8282aa trivy.tar.gz
Uploaded 121f4d8282aa trivy.tar.gz
Pushed registry.company.com/project_name/trivy-cli:0.36.0
Digest: sha256:5bdb18378e8f66a72f4bef4964edeccfcc2f21883e7a6caca6dbf7a3d7233696
Edit your values.yaml
to add the location of your CLI:
trivy:
cli:
repositoryUrl: "registry.company.com/project_name/trivy-cli:0.36.0"
Trivy Aqua plug-in enables Aqua SaaS integration with your Trivy scans. To use another Trivy Aqua plug-in version:
Install the ORAS CLI by following steps in the ORAS documentation.
Download the version of Trivy Aqua plug-in you want from the GitHub releases page.
For example, v0.115.14 in GitHub:
TRIVY-AQUA-PLUGIN-VERSION="v0.115.6"
wget -c "https://github.com/aquasecurity/trivy-plugin-aqua/releases/download/${TRIVY-AQUA-PLUGIN-VERSION}/linux_amd64_${TRIVY-AQUA-PLUGIN-VERSION}.tar.gz" -O trivy-aqua-plugin.tar.gz
--2023-01-30 10:44:05-- https://github.com/aquasecurity/trivy-plugin-aqua/releases/download/v0.115.6/linux_amd64_v0.115.6.tar.gz
HTTP request sent, awaiting response... 200 OK
Length: 50915539 (49M) [application/octet-stream]
Saving to: ‘trivy-aqua-plugin.tar.gz’
trivy-aqua-plugin.tar.gz 100%[==>] 48.56M 35.3MB/s in 1.4s
2023-01-30 10:44:07 (35.3 MB/s) - ‘trivy-aqua-plugin.tar.gz’ saved [50915539/50915539]
The YAML file is a necessary component for telling Trivy that it has the plug-in already installed. Download the plugin.yml
file associated with Trivy Aqua plug-in version you downloaded by running:
TRIVY-AQUA-PLUGIN-VERSION="v0.115.6"
wget -c "https://raw.githubusercontent.com/aquasecurity/trivy-plugin-aqua/${TRIVY-AQUA-PLUGIN-VERSION}/plugin.yaml" -O plugin.yaml
--2023-01-30 10:46:32-- https://raw.githubusercontent.com/aquasecurity/trivy-plugin-aqua/v0.115.6/plugin.yaml
HTTP request sent, awaiting response... 200 OK
Length: 909 [text/plain]
Saving to: ‘plugin.yaml’
plugin.yaml 100%[==>] 909 --.-KB/s in 0s
2023-01-30 10:46:32 (54.2 MB/s) - ‘plugin.yaml’ saved [909/909]
Move the plug-in and YAML to your registry by running:
TRIVY-AQUA-PLUGIN-VERSION="v0.115.6"
REPOSITORY-URL="registry.company.com/project_name/trivy-aqua-plugin:$TRIVY-AQUA-PLUGIN-VERSION"
oras push ${REPOSITORY-URL} \
--artifact-type trivy/aqua-plugin \
./trivy-aqua-plugin.tar.gz:application/gzip \
./plugin.yaml:text/yaml
Uploading 6fb65adbfde2 plugin.yaml
Uploading 7340855e31ff trivy-aqua-plugin.tar.gz
Uploaded 6fb65adbfde2 plugin.yaml
Uploaded 7340855e31ff trivy-aqua-plugin.tar.gz
Pushed registry.company.com/project_name/trivy-aqua-plugin:v0.115.6
Digest: sha256:791274e44b97fad98edf570205fddc1b0bc21c56d3d54565ad9475fd4da969ae
Where:
TRIVY-AQUA-PLUGIN-VERSION
is the version of Trivy Aqua plug-in you are using.REPOSITORY-URL
is the repository where you want to relocate the plug-in.Edit your values.yaml
to add the location of your CLI as follows:
trivy:
plugins:
aqua:
repositoryUrl: "registry.company.com/project_name/trivy-aqua-plugin:v0.115.6"
To integrate with the Aqua SaaS platform:
To connect to the SaaS Platform you must have an API key. To create an API key:
To integrate with the Aqua SaaS Platform you must have an API key. You pass this to the scanner through environment variables, referenced in a secret. Create an auth secret similar to this one:
apiVersion: v1
kind: Secret
metadata:
name: aqua-creds
namespace: APP-NAMESPACE
stringData:
aqua-key: API-KEY
aqua-secret: API-KEY-SECRET
Where:
APP-NAMESPACE
is the developer namespace your app uses.API-KEY
is the Aqua Platform API key.API-KEY-SECRET
is the Aqua Platform API key’s Secret.Set environment variables to tell Trivy to connect and report to Aqua SaaS. You can find plug-in options in the README file in GitHub.
Here is an example of referencing your API key and secret from a Kubernetes Secret created earlier:
namespace: dev
targetImagePullSecret: registry-credentials
environmentVariables:
- name: TRIVY-RUN-AS-PLUGIN
value: aqua
- name: AQUA-KEY
valueFrom:
secretKeyRef:
name: aqua-creds
key: aqua-key
- name: AQUA-SECRET
valueFrom:
secretKeyRef:
name: aqua-creds
key: aqua-secret
Where:
TRIVY-RUN-AS-PLUGIN
is the Trivy plug-in you want to enable without using the subcommand.AQUA-KEY
is the Aqua Platform API key.AQUA-SECRET
is the Aqua Platform API key’s Secret.You need additional configuration when attempting to pull an image from a registry with a self-signed certificate during image scans:
If your tap-values.yaml
file used during installation has the following shared section filled in, Trivy uses this section to connect to your registry without additional configuration. Use the following YAML with a Tanzu Application Platform values shared CA:
shared:
ca_cert_data: | # To be passed if using custom certificates.
-----BEGIN CERTIFICATE-----
MIIFXzCCA0egAwIBAgIJAJYm37SFocjlMA0GCSqGSIb3DQEBDQUAMEY...
-----END CERTIFICATE-----
Create a secret that holds the registry’s CA certificate data. For example:
apiVersion: v1
kind: Secret
metadata:
name: trivy-registry-cert
namespace: dev
type: Opaque
data:
ca_cert_data: BASE64_CERT
Add caCertSecret
to the root of trivy-values.yaml
to update your Trivy installation. For example:
namespace: dev
targetImagePullSecret: tap-registry
caCertSecret: trivy-registry-cert