Introduction

In this article, we’ll see how we can block “latest” image tag, that is, denying the use of images with the “latest” tag. Yes! You read it right. But why block the “latest” tag? We’ll see that below.

What’s wrong with the “latest” tag?

We’ll understand this with the help of a scenario. Let us start with a Dockerfile and consider the following actions:

  • First we build the image.

docker build -t demo/test .

  • Now, we tag it with a version number using the tag “v1”

docker tag demo/test demo/test:v1

  • We push the image to the repository.

docker push demo/test

Now our repo will contain two tags: “latest” and “v1”

  • Next, we update the Dockerfile and  build the image with the tag “v2” since it’s the update version.

docker build -t demo/test:2 .

  • We’ll push the image to our repo again.

docker push demo/test

  • Let us run the docker image.

docker run demo/test

Here’s where the confusion happens. We expect the new, updated version of the image to run but instead what we get is the old image running. We may think that this is because we are not pulling the image with the “latest” tag. 

The same problem will happen even if we run the image with the “latest” tag. This is because the “latest” does nothing but imply to use the last build that doesn’t have a version or a tag. It does not ensure that the latest version of the image (in our case the “v2” tagged image) is pulled.

Why do we need this policy?

In many of the production environments, the image with the “latest” tag gets pulled, if present, automatically. As discussed above, this does not allow the updated image to be pulled. So to be on the safer side, we’ll use an OPA policy to prevent any images with the “latest” tag. Another reason to block the “latest” tag is because it makes it difficult to identify which version of the image is running and hence makes it hard to roll back.

Block “Latest” Image Tag

template.yaml

apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
  name: k8sblocklatesttag
  annotations:
    description: Blocks images with the "latest" tag.
spec:
  crd:
    spec:
      names:
        kind: K8sBlockLatestTag
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8sblocklatesttag

        violation[{"msg": msg, "details": {}}]{
        input.review.object.kind == "Pod"
        imagename := input.review.object.spec.containers[_].image
        endswith(imagename,"latest")
        msg := "Images with tag the tag \"latest\" is prohibited"
        }

Rego Policy explained:

  1. Check if the kind is “Pod”.
  2. Store the image’s name in the “imagename” variable.
  3. Check if the image’s name in the variable ends with the string “latest” as we want to block the “latest” image tag. 
  4. The message gets printed if all the above returns true.

constraint.yaml

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sBlockLatestTag
metadata:
  name: block-latest-tag
spec:
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Pod"]

We are not going to provide any parameters.

deployment-non-violation.yaml

apiVersion: v1
kind: Pod
metadata:
  name: private-image-test-1
spec:
  containers:
    - name: uses-private-image
      image: 071460744267.dkr.ecr.us-east-1.amazonaws.com/test/snyk:prod
      imagePullPolicy: IfNotPresent
      command: [ "echo", "SUCCESS" ]

This file will get created without any issues as the tag name is not “latest”.

deployment-violation.yaml

apiVersion: v1
kind: Pod
metadata:
  name: private-image-test-1
spec:
  containers:
    - name: uses-private-image
      image: 071460744267.dkr.ecr.us-east-1.amazonaws.com/test/snyk:latest
      imagePullPolicy: IfNotPresent
      command: [ "echo", "SUCCESS" ]

This will not get created as the image is tagged as “latest”.

Conclusion

The use of the “latest” tag might seem completely normal but as seen above it’s always suggested to block the tag. We should also tag the images with the proper version as it makes tracking images easier.

Other related articles:

Practice here:

https://www.katacoda.com/cloudsecops/courses/opagatekeeper-policy/blocklatest

References:

Thank you for reading! – Vishal Pranav and Setu Parimi

Sign up for the blog directly here.

Check out our professional services here.

Feedback is welcome! For professional services, fan mail, hate mail, or whatever else, contact [email protected]


0 Comments

Leave a Reply

%d bloggers like this: