top of page
Writer's pictureELDIN PAUL

Optimizing Container Security: Image Scanning and Signing with Cosign, Kyverno and Trivy

Updated: Jul 16, 2024


Container Scanning and Signing using Trivy and Kyverno

Image Scanning, Signing and Security

In the world of cloud-native applications, container security is paramount. Ensuring that your container images are free of vulnerabilities before deployment is a critical step in maintaining a secure environment. In this post, we'll walk through the process of scanning container images using Trivy, signing them with Cosign upon successful scans, and enforcing these policies during deployment in Amazon EKS using Kyverno.


Prerequisites:


Before we start, ensure you have the following tools and services configured:


  • Docker: For building and managing container images.

  • Trivy: A vulnerability scanner for containers.

  • Cosign: A tool for signing and verifying container images.

  • Kyverno: A Kubernetes policy engine.

  • Amazon EKS: An Amazon Elastic Kubernetes Service cluster.


Step 1: Build Your Container Image


First, let's build a simple container image. Create a Dockerfile:

# Dockerfile
FROM alpine:latest
RUN apk --no-cache add curl
CMD ["curl", "--version"]

Build the image:

docker build -t registry-name/alpine-curl:latest .

Step 2: Scan the Image with Trivy


Next, we need to scan the image for vulnerabilities using Trivy.

trivy image registry-name/alpine-curl:latest

Step 3: Sign the Image with Cosign


Once the image is free of vulnerabilities (or has accepted exceptions), you can sign it using Cosign.


Generate a key pair if you don't have one:

cosign generate-key-pair

Get the SHA of the image:

docker inspect --format='{{.RepoDigests}}' registry-name/alpine-curl:latest

Sign the image:

cosign sign --key cosign.key registry-name/alpine-curl@sha256:<unique finger print here>

Verify the signature:

cosign verify --key cosign.pub registry-name/alpine-curl:latest

In the above example, the public Rekor server at https://rekor.sigstore.dev/ will be utilized for storing the transparency log (metadata).


In a scenario that includes a private container registry, there is no requirement to push the metadata to a public Rekor server during setup. Therefore, in such cases, this flag can be used to disable the feature during the signing process.

--tlog-upload=false

Sign the image:

cosign sign --key cosign.key --tlog-upload=false registry-name/alpine-curl@sha256:<unique finger print here>

Verify the signature:

cosign verify --key cosign.pub --insecure-ignore-tlog=true regsirt-name/alpine-curl:latest

Please be aware that enabling the above flags will fully deactivate transparency log and its validation. In case of a private and air-gapped deployment, utilizing these flags can simplify the setup. Yet, if transparency logs are also required, it is recommended to establish a private instance of the Rekor server. The following Github issues can assist you in making an informed decision on this matter.



Step 4: Create a Kyverno Policy


To enforce that only signed images are deployed in your EKS cluster, create a Kyverno policy. This policy will validate the presence of Cosign signatures on container images using the public key.


Create a policy file verify-image-signature.yaml:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: verify-image-signature
spec:
  validationFailureAction: Enforce
  background: false
  rules:
  - name: check-image-signature
    match:
	any:
    	- resources:
        kinds:
        	- Pod
    verifyImages:
    - imageReferences: 
	  	- "registry-name/alpine-curl:*"
	mutateDigest: true
	attestors:
	- count: 1
	  entries:
	  - keys:
		publicKeys: |-
		 -----BEGIN PUBLIC KEY-----
       	 MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8nXRh950IZbRj8Ra/N9sbqOPZrfM
          5/KAQN0/KjHcorm/J5yctVd7iEcnessRQjU917hmKO6JWVGHpDguIyakZA==
          -----END PUBLIC KEY-----                
         rekor:
           ignoreTlog: true

  • IgnoreTlog flag is used to ignore transperancy log validation from rekor server

  • MutateDigest option needs to be set for kyverno to fetch the sha for the corresponding image tag to validate.


More information on Kyverno policies can be found here https://kyverno.io/docs/writing-policies/verify-images/sigstore/


Step 5: Deploy the Kyverno Policy


Apply the Kyverno policy to your EKS cluster:

kubectl apply -f verify-image-signature.yaml

Step 6: Deploy the Application to EKS


Create a deployment file deployment.yaml for your application:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: alpine-curl-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: alpine-curl
  template:
    metadata:
      labels:
        app: alpine-curl
    spec:
      containers:
      - name: alpine-curl
        image: registry-name/alpine-curl:latest

Apply the deployment:

kubectl apply -f deployment.yaml

Sample notification for validation errors:

Error from server (Forbidden): error when creating "deployment.yaml": admission webhook "mutate.kyverno.svc" denied the request:

resource Deployment/default/alpine-curl-deployment was blocked due to the following policies

verify-image-signature:
  check-image-signature: 'image verification failed for "your-username/alpine-curl:latest": 
  failed to verify signature, cosign verification failed for image "your-username/alpine-curl:latest":
  no matching signatures:
  spec:
    containers:
    - image: registry-name/alpine-curl:latest'

Conclusion


By integrating Trivy for vulnerability scanning, Cosign for signing images, and Kyverno for enforcing image policies, you create a robust security pipeline for your containerized applications. This workflow ensures that only secure and verified images are deployed in your EKS cluster, significantly enhancing your container security posture.


Next Steps


  • Automate the Workflow: Integrate this process into your CI/CD pipeline for automated signing based on vulnerability feedback from Trivy or the scanning tool of your preference like Prisma Cloud, Snyk, Wiz, AquaSec etc.

  • Continuous Monitoring: Keep a constant watch on your Kyverno policies and deployed containers to ensure that the validation is occurring correctly.


By following these practices, you'll be well on your way to maintaining a secure and compliant container environment.

184 views0 comments

Recent Posts

See All

Kommentare


bottom of page