This topic tells you how to create a Tanzu Build Service image resource that builds a container image from source code signed with Cosign.
Before you can configure Tanzu Build Service to sign your image builds, you must:
-
Install Tanzu Build Service. The Full, Iterate, and Build profiles include Tanzu Build Service by default. If you have not installed Tanzu Application Platform with one of these profiles, see Installing Tanzu Build Service.
-
Install Cosign. For instructions, see the Cosign documentation.
-
Have a Builder or ClusterBuilder resource configured.
-
Have an image resource configured.
-
Review the kpack tutorial. This topic builds upon the steps in this tutorial.
To configure Tanzu Build Service to sign your image builds:
-
Ensure that you are in a Kubernetes context where you are authenticated and authorized to create and edit secret and service account resources.
-
Generate a Cosign keypair and store it as a Kubernetes secret by running:
cosign generate-key-pair k8s://NAMESPACE/COSIGN-KEYPAIR-NAME
Where:
NAMESPACE
is the namespace to store the Kubernetes secret in.COSIGN-KEYPAIR-NAME
is the name of the Kubernetes secret.
For example:
cosign generate-key-pair k8s://default/tutorial-cosign-key-pair
-
Enter a password for the private key. Enter any password you want. After the command has completed, you will see the following output:
Successfully created secret tutorial-cosign-key-pair in namespace default Public key written to cosign.pub
You will also see a
cosign.pub
file in your current directory. Keep this file as you will need it to verify the signature of the images that are built. -
If you are using Docker Hub or a registry that does not support OCI media types, add the annotation
kpack.io/cosign.docker-media-types: "1"
to the Cosign secret as follows:apiVersion: v1 kind: Secret type: Opaque metadata: name: tutorial-cosign-key-pair namespace: default annotations: kpack.io/cosign.docker-media-types: "1" data: cosign.key: PRIVATE-KEY-DATA cosign.password: COSIGN-PASSWORD cosign.pub: PUBLIC-KEY-DATA
For more information about configuring Cosign key pairs, see the Tanzu Build Service documentation.
-
To enable Cosign signing, create or edit the service account resource that is referenced in the image resource so that it includes the Cosign keypair secret created earlier. The service account is in the same namespace as the image resource and is directly referenced by the image or default if there isn't one.
apiVersion: v1 kind: ServiceAccount metadata: name: SERVICE-ACCOUNT-NAME namespace: default secrets: - name: REGISTRY-CREDENTIALS - name: COSIGN-KEYPAIR-NAME imagePullSecrets: - name: REGISTRY-CREDENTIALS
Where:
SERVICE-ACCOUNT-NAME
is the name of your service account resource. For example,tutorial-cosign-service-account
.COSIGN-KEYPAIR-NAME
is the name of the Cosign keypair secret generated earlier. For example,tutorial-cosign-key-pair
.REGISTRY-CREDENTIALS
is the secret that provides credentials for the container registry where application container images are pushed to.
-
Apply the service account resource to the cluster by running:
kubectl apply -f cosign-service-account.yaml
-
Create an image resource file named
image-cosign.yaml
. For example:apiVersion: kpack.io/v1alpha2 kind: Image metadata: name: tutorial-cosign-image namespace: default spec: tag: IMAGE-REGISTRY serviceAccountName: tutorial-cosign-service-account builder: name: my-builder kind: Builder source: git: url: https://github.com/spring-projects/spring-petclinic revision: 82cb521d636b282340378d80a6307a08e3d4a4c4
Where:
IMAGE-REGISTRY
with a writable repository in your registry. The secret referenced in the service account is a secret providing credentials for the registry where application container images are pushed to. For example:- Harbor has the form
"my-harbor.io/my-project/my-repo"
- Docker Hub has the form
"my-dockerhub-user/my-repo"
or"index.docker.io/my-user/my-repo"
- Google Cloud Registry has the form
"gcr.io/my-project/my-repo"
- Harbor has the form
-
If you are using Out of the Box Supply Chains, edit the respective
ClusterImageTemplate
to enable signing in your supply chain. For more information, see Authoring supply chains.Important VMware discourages referencing the service account using the
service_account
value when installing the Out of the Box Supply Chain. This is because it gives your run cluster access to the private signing key. -
Apply the image resource to the cluster by running:
kubectl apply -f image-cosign.yaml
-
After the image resource finishes building, you can get the fully resolved and built OCI image by running:
kubectl -n default get image tutorial-cosign-image
Example output:
NAME LATESTIMAGE READY tutorial-cosign-image index.docker.io/your-project/app@sha256:6744b... True
-
Verify image signature by running:
cosign verify --key cosign.pub LATEST-IMAGE-WITH-DIGEST
Where
LATEST-IMAGE-WITH-DIGEST
is the value ofLATESTIMAGE
you retrieved in the previous step. For example:index.docker.io/your-project/app@sha256:6744b...
The expected output is similar to the following:
Verification for index.docker.io/your-project/app@sha256:6744b... -- The following checks were performed on each of these signatures: - The cosign claims were validated - The signatures were verified against the specified public key - Any certificates were verified against the Fulcio roots.
-
Configure Supply Chain Security Tools for VMware Tanzu - Policy Controller to ensure that only signed images are allowed in your cluster. For more information, see the Supply Chain Security Tools for VMware Tanzu - Policy Controller documentation.