Create a signed container image with Tanzu Build Service

This topic describes how to create a Tanzu Build Service image resource that builds a container image from source code signed with Cosign.

This topic builds upon the steps in the kpack tutorial.


Before you can configure Tanzu Build Service to sign your image builds, you must:

Configure Tanzu Build Service to sign your image builds

To configure Tanzu Build Service to sign your image builds:

  1. Ensure that you are in a Kubernetes context where you are authenticated and authorized to create and edit secret and service account resources.

  2. Generate a Cosign keypair and store it as a Kubernetes secret by running:

    cosign generate-key-pair k8s://NAMESPACE/COSIGN-KEYPAIR-NAME


    • 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
  3. 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

    You will also see a file in your current directory. Keep this file as you will need it to verify the signature of the images that are built.

  4. If you are using Docker Hub or a registry that does not support OCI media types, add the annotation "1" to the Cosign secret as follows:

    apiVersion: v1
    kind: Secret
    type: Opaque
      name: tutorial-cosign-key-pair
      namespace: default
      annotations: "1"
      cosign.key: PRIVATE-KEY-DATA
      cosign.password: COSIGN-PASSWORD PUBLIC-KEY-DATA

    For more information about configuring Cosign key pairs, see the Tanzu Build Service documentation.

  5. 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. The default is the default service account in the workload namespace.

    apiVersion: v1
    kind: ServiceAccount
      namespace: default


    • 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.
  6. Apply the service account resource to the cluster by running:

    kubectl apply -f cosign-service-account.yaml
  7. Create an image resource file named image-cosign.yaml. For example:

    kind: Image
      name: tutorial-cosign-image
      namespace: default
      serviceAccountName: tutorial-cosign-service-account
        name: my-builder
        kind: Builder
          revision: 82cb521d636b282340378d80a6307a08e3d4a4c4


    • 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 ""
      • Docker Hub has the form "my-dockerhub-user/my-repo" or ""
      • Google Cloud Registry has the form ""
  8. 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.


    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.

  9. Apply the image resource to the cluster by running:

    kubectl apply -f image-cosign.yaml
  10. 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   True
  11. Verify image signature by running:

    cosign verify --key LATEST-IMAGE-WITH-DIGEST

    Where LATEST-IMAGE-WITH-DIGEST is the value of LATESTIMAGE you retrieved in the previous step. For example:

    The expected output is similar to the following:

    Verification for --
    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.
  12. 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.

check-circle-line exclamation-circle-line close-line
Scroll to top icon