Kyverno And Cosign

Kyverno And Cosign

In my previous article, I have written about kyverno. Continuing that, In this short article, I’m going to explore Kyverno and Cosign together. Kyverno is a Kubernetes native policy engine, and cosign is a tool used for signing container images. This article assumes that you know the basics of Kyverno and Cosign.

This article is more hands on oriented, so I will encourage you to try this hands on.

  • What we are going to do in this blog

    1. Creating a container image
    2. Pushing the image to container registry
    3. Signing the Image with Cosign
    4. Creating a ClusterPolicy that will enforce only signed images to be used while creating k8s resources.
    5. Creating a pod with the same image that we had made above.
  • For the example purpose, I will be creating a very simple container image based on nginx:alpine image.

  • Create a new directory and name it anything you want.
  • First, let's create an index.html page that we will be using in the image.
<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Cosign and Kyverno</title>
    <h1> Having fun with Cosign and Kyverno </h1>
  • Now let's create a Dockerfile in the same directory.
    FROM nginx:alpine
    COPY index.html /usr/share/nginx/html
  • Now we need to build the image. To build the image, execute the command
    podman build -t kranurag7/kyverno-cosign .
  • I'm using Podman here. If you use any other tool like docker, then replace podman with docker.

Signing the image

  • Now comes the part of signing the image.
  • To sign the image, we will use cosign.
  • Execute the command cosign sign --key cosign.key kranurag7/kyverno-cosign
  • If everything is correct, you should see this message.

Screenshot from 2022-04-26 14-48-20.png

  • After signing when you go to docker hub or your respective container registry then you will notice a tag pushed to the repo as soon as you sign the image.


  • I'm not going into the details of cosign in this article. I will write another one for that.
  • If verifies that your image is signed now.
  • You can also verify your image from the terminal.
    cosign verify --key kranurag7/kyverno-cosign | jq
  • You should see something like this.

Screenshot from 2022-04-26 14-55-14.png

  • If you don't have jq installed then skip jq

Creating a Pod with the signed Image

  • Now that we have our image ready, let's create a ClusterPolicy that will only allow the pods whose container images are signed with cosign.
  • To do that, we will go to and copy-paste one policy named verify_image. You can find it here
kind: ClusterPolicy
  name: verify-image
  annotations: Verify Image Sample medium Pod 1.4.2 >-
      Using the Cosign project, OCI images may be signed to ensure supply chain
      security is maintained. Those signatures can be verified before pulling into
      a cluster. This policy checks the signature of an image repo called to ensure it has been signed by verifying
      its signature against the provided public key. This policy serves as an illustration for
      how to configure a similar rule and will require replacing with your image(s) and keys.      
  validationFailureAction: enforce
  background: false
    - name: verify-image
        - resources:
              - Pod
        - image: "*"
          key: |-
            -----BEGIN PUBLIC KEY-----
            -----END PUBLIC KEY-----
  • Now we will execute the command kubectl apply -f verify_image.yaml
  • After this, we will try running our signed image and one unsigned image as well.
  • Let's first start with an image which is not signed by cosign.
  • For illustration purpose, we will run the nginx image
    kubectl run my-pod --image=nginx
  • You will notice that the object is not getting created, and it's throwing an error.
  • The error will look something like this.

Screenshot from 2022-04-26 14-27-04.png

  • You can also check this in the policy reports.
    kubectl get polr

Screenshot from 2022-04-26 14-29-56.png

  • It's showing that one policy is failing.
  • For looking at policies, I generally use policy-reporter. In the policy-reporter Dashboard, you will notice that one failing policy is there. For me, this is much simpler to visualize what's happening in the cluster.

Screenshot from 2022-04-26 14-32-04.png

  • You can see in the image above that one policy is failing and something is wrong.
  • Now let's deploy a pod with the image we have signed a few minutes back.
  • kubectl run my-pod --image=kranurag7/kyverno-cosign


  • Now let's try executing the command for the simple web page that we had created.
    kubectl exec -it my-pod -- curl localhost:80
  • You should see some output like this

Screenshot from 2022-04-26 15-21-24.png

  • Now let's see this in browser
    kubectl port-forward my-pod 8081:80
  • Go to your browser and type localhost:8081. You should see this in your browser. Screenshot from 2022-04-26 15-25-12.png

  • That's all I have for this article. I hope you enjoyed reading and practicing it. Stay tuned for more.

Did you find this article valuable?

Support Kubesimplify by becoming a sponsor. Any amount is appreciated!