Reading Time: 3 mins
Overview
Supply Chain Security Tools – Store saves software bills of materials (SBoMs) to a database and allows you to query for image, source, package, and vulnerability relationships. It integrates with Supply Chain Security Tools – Scan to automatically store the resulting source and image vulnerability reports. It accepts any CycloneDX input and outputs in both human-readable and machine-readable formats, including JSON, text, and CycloneDX.
Prerequisites
Ensure to complete the TAP install with OOTB test and scan, refer to steps here
postgres database (optional) – By default, Postgres database and an API backend is created during the installation of tanzu packages. If you are planning to use an external postgres DB refer to doc
insight CLI, Grype
Service accounts and access token
insight CLI and Grype
Install insight CLI
Login to Tanzu network and download the tarball based on your operating system, for this demo I choose insight-1.0.1_darwin_amd64 for mac
# On the command line, make the download "insight-1.0.1_darwin_amd64" binary file executable: chmod ugo+x insight-1.0.1_darwin_amd64 # Move the binary file into a directory that is on your PATH: mv insight-1.0.1_darwin_amd64 /usr/local/bin/insight # verify the version insight version
Grype
Service accounts and access token
You can create two types of service accounts, In this demo, I have used Read-write service account.
Read-only service account – only able to use GET
API requests
kubectl apply -f - -o yaml << EOF apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: metadata-store-ro namespace: metadata-store rules: - resources: ["all"] verbs: ["get"] apiGroups: [ "metadata-store/v1" ] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: metadata-store-ro namespace: metadata-store roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: metadata-store-ro subjects: - kind: ServiceAccount name: metadata-store-read-client namespace: metadata-store --- apiVersion: v1 kind: ServiceAccount metadata: name: metadata-store-read-client namespace: metadata-store automountServiceAccountToken: false EOF
(OR)
2. Read-write service account – full access to the API requests
kubectl apply -f - -o yaml << EOF apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: metadata-store-read-write namespace: metadata-store rules: - resources: ["all"] verbs: ["get", "create", "update"] apiGroups: [ "metadata-store/v1" ] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: metadata-store-read-write namespace: metadata-store roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: metadata-store-read-write subjects: - kind: ServiceAccount name: metadata-store-read-write-client namespace: metadata-store --- apiVersion: v1 kind: ServiceAccount metadata: name: metadata-store-read-write-client namespace: metadata-store automountServiceAccountToken: false EOF
Access Token:
To retrieve the read-write access token run the following command:
kubectl get secret $(kubectl get sa -n metadata-store metadata-store-read-write-client -o json | jq -r '.secrets[0].name') -n metadata-store -o json | jq -r '.data.token' | base64 -d
Setting the access token:
When using the CLI, you’ll need to set the METADATA_STORE_ACCESS_TOKEN
environment variable, or use the --access-token
flag.
$ export METADATA_STORE_ACCESS_TOKEN=$(kubectl get secrets -n metadata-store -o jsonpath="{.items[?(@.metadata.annotations['kubernetes\.io/service-account\.name']=='metadata-store-read-write-client')].data.token}" | base64 -d)
Connection to database:
The connection to the Store requires TLS encryption. Follow the instructions below to set up the TLS connection depending on which type of service is being used: For this demo, I have used LoadBalancer.
Using LoadBalancer
Using NodePort
— commonly used with local clusters such as kind, or minikube
LoadBalancer
If you are using a LoadBalancer
configuration, you need to find the external IP of the metadata-store-app
service using below command:
kubectl get service/metadata-store-app --namespace metadata-store -o=jsonpath='{.status.loadBalancer.ingress[0].ip}'
Add the IP entry mapping to metadata-store-app.metadata-store.svc.cluster.local
in /etc/hosts like shown below:
The CA certificate is generated by cert manager. Run the following command to get the CA certificate:
kubectl get secret app-tls-cert -n metadata-store -o json | jq -r '.data."ca.crt"' | base64 -d > /tmp/ca.crt
insight CLI configuration
# Set the target endpoint and CA certificate by running: insight config set-target https://metadata-store-app.metadata-store.svc.cluster.local:8443 --ca-cert /tmp/ca.crt # insight health {"message":"Successfully Reached Metadata Store!"}
Though the data can be added by posting CycloneDX files using many methods, In this demo I will be adding it through Insight CLI:
Generate a CycloneDX File
To use Grype to scan an image and generate an image report in CycloneDX format.
# For this demo, I would be using acr repo which I have used while creating workload in TAP. # Authenticate to acr using docker login , syntax: docker login -u <username> -p <password> docker login tapdemoacr.azurecr.io -u tapdemoacr -p hGQ9wrongonefd3o
# To use Grype to scan an image and generate an image report in CycloneDX format. syntax: grype REPO:TAG -o cyclonedx > NAME # Where: REPO is the name of your repository, TAG is the name of a tag, IMAGE-CVE-REPORT is the resulting file name of the Grype image scan report grype tapdemoacr.azurecr.io/build-service:latest -o cyclonedx > image-cve-report ✔ Vulnerability DB [no update available] ✔ Loaded image ✔ Parsed image ✔ Cataloged packages [96 packages] ✔ Scanned image [82 vulnerabilities]
# To use a CycloneDX-formatted image report: $ insight image create --cyclonedxtype xml --path image-cve-report # For this demo I picked a random cve id from the report to see the vulnerability packages: $ insight vuln get --cveid CVE-2020-16156 1. CVE-2020-16156 (Medium) Packages: 1. perl-base@5.26.1-6ubuntu0.5 # To see the list of the images tagged with the vulnerability: $ insight vuln images --cveid CVE-2020-16156 1. ID: 1 Registry: tapdemoacr.azurecr.io Image Name: supply-chain/tanzu-java-web-app-tap-install Digest: sha256:2ea135cbc1058af2662bf08a5e6ebf3041b64f6aebfe13b5ebfe618b1648d190 Packages: 1. perl-base@5.26.1-6ubuntu0.5 CVEs: 1. CVE-2020-16156 (Medium) 2. ID: 3 Registry: tapdemoacr.azurecr.io Image Name: build-service Digest: sha256:bceaec7f98f3ba34025d71322ca606db7c650a3748617848e4f52a643c541859 Packages: 1. perl-base@5.26.1-6ubuntu0.5 CVEs: 1. CVE-2020-16156 (Medium)
# To see the affected images of specific package insight package images --name perl-base 1. ID: 1 Registry: tapdemoacr.azurecr.io Image Name: supply-chain/tanzu-java-web-app-tap-install Digest: sha256:2ea135cbc1058af2662bf08a5e6ebf3041b64f6aebfe13b5ebfe618b1648d190 Packages: 1. perl-base@5.26.1-6ubuntu0.5 CVEs: 1. CVE-2020-16156 (Medium) 2. ID: 3 Registry: tapdemoacr.azurecr.io Image Name: build-service Digest: sha256:bceaec7f98f3ba34025d71322ca606db7c650a3748617848e4f52a643c541859 Packages: 1. perl-base@5.26.1-6ubuntu0.5 CVEs: 1. CVE-2020-16156 (Medium)
# To list the packages and corresponding CVE's of a specific digest: insight image get --digest sha256:2ea135cbc1058af2662bf08a5e6ebf3041b64f6aebfe13b5ebfe618b1648d190 ID: 1 Registry: tapdemoacr.azurecr.io Image Name: supply-chain/tanzu-java-web-app-tap-install Digest: sha256:2ea135cbc1058af2662bf08a5e6ebf3041b64f6aebfe13b5ebfe618b1648d190 Packages: 1. helper@9.0.3 2. BellSoft Liberica JRE@11.0.14 3. helper@3.0.2 4. HdrHistogram@2.1.12 5. LatencyUtils@2.0.3 6. jackson-annotations@2.12.6 7. jackson-core@2.12.6 8. jackson-databind@2.12.6 9. jackson-datatype-jdk8@2.12.6 10. jackson-datatype-jsr310@2.12.6 11. jackson-module-parameter-names@2.12.6 12. jakarta.annotation-api@1.3.5 13. jul-to-slf4j@1.7.32 14. log4j-api@2.17.0 CVEs: 1. GHSA-8489-44mv-ggj8 (Medium) 2. CVE-2021-44832 (Medium) 2. CVE-2021-44832 (Unknown) 2. CVE-2021-44832 (Unknown) 15. log4j-to-slf4j@2.17.0 CVEs: 1. CVE-2021-44832 (Medium) 1. CVE-2021-44832 (Unknown) 1. CVE-2021-44832 (Unknown)
Demo Video:
VIDEO