A ConstraintTemplate library is a reusable collection of Gatekeeper policy definitions. Each ConstraintTemplate supplies evaluation logic; a separate constraint selects a template and provides the scope and parameters that make its policy effective. In Policy Controller, templates are available when Gatekeeper is enabled, but a template alone does not enforce a rule. section 11.2.3 section 13.4.1
The default Policy Controller library included 32 templates at the time described, covering cases such as allowed container registries, resource constraints, and privileged containers. Inspect the templates installed on a cluster with `kubectl get constrainttemplates`. Custom templates can extend the library when the supplied definitions do not fit a requirement. section 13.4.1 section 11.2.3
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8simagedigests
annotations:
metadata.gatekeeper.sh/title: "Image Digests"
description: >-
Requires container images to contain a digest.
https://kubernetes.io/docs/concepts/containers/images/
spec:
crd:
spec:
names:
kind: K8sImageDigests
validation:
openAPIV3Schema:
type: object
description: >-
Requires container images to contain a digest.
https://kubernetes.io/docs/concepts/containers/images/
properties:
exemptImages:
description: >-
Any container that uses an image that matches an entry in this list will be excluded
from enforcement. Prefix-matching can be signified with '*'. For example: 'my-image-*'.
It is recommended that users use the fully-qualified Docker image name (e.g. start with a domain name)
in order to avoid unexpectedly exempting images from an untrusted repository.
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8simagedigests
import data.lib.exempt_container.is_exempt
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
not is_exempt(container)
satisfied := [re_match("@[a-z0-9]+([+._-][a-z0-9]+)*:[a-zA-Z0-9=_-]+", container.image)]
not all(satisfied)
msg := sprintf("container <%v> uses an image without a digest <%v>", [container.name, container.image])
}
violation[{"msg": msg}] {
container := input.review.object.spec.initContainers[_]
not is_exempt(container)
satisfied := [re_match("@[a-z0-9]+([+._-][a-z0-9]+)*:[a-zA-Z0-9=_-]+", container.image)]
not all(satisfied)
msg := sprintf("initContainer <%v> uses an image without a digest <%v>", [container.name, container.image])
}
violation[{"msg": msg}] {
container := input.review.object.spec.ephemeralContainers[_]
not is_exempt(container)
satisfied := [re_match("@[a-z0-9]+([+._-][a-z0-9]+)*:[a-zA-Z0-9=_-]+", container.image)]
not all(satisfied)
msg := sprintf("ephemeralContainer <%v> uses an image without a digest <%v>", [container.name, container.image])
}
libs:
- |
package lib.exempt_container
is_exempt(container) {
exempt_images := object.get(object.get(input, "parameters", {}), "exemptImages", [])
img := container.image
exemption := exempt_images[_]
_matches_exemption(img, exemption)
}
_matches_exemption(img, exemption) {
not endswith(exemption, "*")
exemption == img
}
_matches_exemption(img, exemption) {
endswith(exemption, "*")
prefix := trim_suffix(exemption, "*")
startswith(img, prefix)
}
This `ConstraintTemplate` manifest illustrates the reusable-definition side: it names a `K8sImageDigests` constraint kind and declares a validation schema for parameters such as exempt images. A separate constraint is needed to apply it. section 13.4.1
Allow only trusted image registries
Create a `K8sAllowedRepos` constraint named `allowed-registries`, match Pods, and set `parameters.repos` to `gcr.io` and `hub.evermore.local`. A Pod using `bitnami/nginx` is then denied by the admission webhook as an invalid image repository. The reusable template defines the check; the constraint supplies this cluster’s allowed registries. section 13.9.1 section 11.2.3
Test disruptive constraints before enforcing them. A privileged-container constraint can use `enforcementAction: dryrun` to report violations, while `excludedNamespaces` keeps specified system namespaces outside its scope. Review the reported Pods before switching to enforcement; otherwise, a security policy may block workloads the cluster needs. section 13.4.1 section 13.9.1
