Skip to content
This repository was archived by the owner on Sep 10, 2025. It is now read-only.

Commit aa6d5a0

Browse files
committed
🏷️ Prohibit the use of the "latest" tag across component Docker images
1 parent fffd832 commit aa6d5a0

File tree

3 files changed

+57
-1
lines changed

3 files changed

+57
-1
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
apiVersion: constraints.gatekeeper.sh/v1beta1
2+
kind: DisallowedTags
3+
metadata:
4+
name: container-image-must-not-have-latest-tag
5+
spec:
6+
match:
7+
kinds:
8+
- apiGroups: [""]
9+
kinds: ["Pod"]
10+
namespaces:
11+
- "cloud-native-workstation"
12+
parameters:
13+
tags: ["latest"]

kubernetes/constraint-templates.yaml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,44 @@ spec:
9393
container := input.review.object.spec[field][_]
9494
missing(container.resources.limits, "memory")
9595
msg := sprintf("container <%v> has no memory limit", [container.name])
96+
}
97+
---
98+
apiVersion: templates.gatekeeper.sh/v1beta1
99+
kind: ConstraintTemplate
100+
metadata:
101+
name: disallowedtags
102+
spec:
103+
crd:
104+
spec:
105+
names:
106+
kind: DisallowedTags
107+
validation:
108+
openAPIV3Schema:
109+
type: object
110+
properties:
111+
tags:
112+
type: array
113+
items:
114+
type: string
115+
targets:
116+
- target: admission.k8s.gatekeeper.sh
117+
rego: |
118+
package disallowedtags
119+
violation[{"msg": msg}] {
120+
container := input_containers[_]
121+
tags := [forbid | tag = input.parameters.tags[_] ; forbid = endswith(container.image, concat(":", ["", tag]))]
122+
any(tags)
123+
msg := sprintf("container <%v> uses a disallowed tag <%v>; disallowed tags are %v", [container.name, container.image, input.parameters.tags])
124+
}
125+
violation[{"msg": msg}] {
126+
container := input_containers[_]
127+
tag := [contains(container.image, ":")]
128+
not all(tag)
129+
msg := sprintf("container <%v> didn't specify an image tag <%v>", [container.name, container.image])
130+
}
131+
input_containers[c] {
132+
c := input.review.object.spec.containers[_]
133+
}
134+
input_containers[c] {
135+
c := input.review.object.spec.initContainers[_]
96136
}

opa/gatekeeper.sh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ do
1414
deploymentselector=$?
1515
kubectl get resourcelimit 2> /dev/null
1616
resourcelimit=$?
17+
kubectl get disallowedtags 2> /dev/null
18+
disallowedtags=$?
1719
# Exit code 0 means there were no resources found (desired behavior)
1820
# Before CRD registration, the exit code for the get commands is 1
19-
if [ $requiredlabels -ne 0 ] || [ $deploymentselector -ne 0 ] || [ $resourcelimit -ne 0 ]
21+
if [ $requiredlabels -ne 0 ] || [ $deploymentselector -ne 0 ] || [ $resourcelimit -ne 0 ] || [ $disallowedtags -ne 0 ]
2022
then
2123
echo "Constraint Template CRDs: Still creating..."
2224
sleep 5
@@ -32,4 +34,5 @@ set -x
3234
kubectl get requiredlabels
3335
kubectl get deploymentselector
3436
kubectl get resourcelimit
37+
kubectl get disallowedtags
3538
exit 3

0 commit comments

Comments
 (0)