Certified Kubernetes Security Specialist (CKS)
Supply Chain Security
Whitelist Allowed Registries Image Policy Webhook
In this lesson, learn how to whitelist allowed registries in a Kubernetes cluster to prevent unauthorized container images from being deployed. By default, any user with cluster access can deploy pods with images from any registry—even untrusted sources. This can compromise your cluster's security. The following sections explain how to enforce governance rules to restrict container images to approved registries only.
Understanding the Risk
Consider the following pod definition file. In the image field, a user can reference an image from any registry:
apiVersion: v1
kind: Pod
metadata:
name: sample-pod
spec:
containers:
- name: sample-app
image: some-registry.io/a-very-vulnerable-image
Deploying an image with known vulnerabilities may expose other applications on the cluster to risk. An attacker could leverage these vulnerabilities to gain access to the underlying operating system. For enhanced security, it is vital to restrict container images to trusted registries.
Using Admission Controllers to Restrict Registries
One effective method is to use Kubernetes admission controllers. When a pod creation request is made, it is processed through several stages: authentication, authorization, and admission control. By deploying a validating admission webhook server, you can inspect each incoming request and verify that the container image originates from an approved registry. If not, the webhook will reject the request with a clear error message.
For example, consider the following Python code snippet that demonstrates an admission webhook allowing only images from "internal-registry.io":
@app.route("/validate", methods=["POST"])
def validate():
image_name = request.json["request"]["object"]["spec"]["containers"][0]["image"]
status = True
message = ""
if "internal-registry.io" not in image_name:
message = "You can only use images from the internal-registry.io"
status = False
return jsonify(
{
"response": {
"allowed": status,
"uid": request.json["request"]["uid"],
"status": {"message": message},
}
}
)
Tip
Ensure that your validating webhook server is highly available. This prevents disruptions in pod creation if the webhook becomes unreachable.
Implementing Policies with OPA and Rego
An alternative approach is to deploy Open Policy Agent (OPA) with a validating webhook. By leveraging OPA's Rego language, you can write custom policies that allow container images only from trusted registries. The example below denies any image that does not begin with "internal-registry.io/":
package kubernetes.admission
deny[msg] {
input.request.kind.kind == "Pod"
image := input.request.object.spec.containers[_].image
not startswith(image, "internal-registry.io/")
msg := sprintf("Image '%s' is not from a trusted registry", [image])
}
Using the Built-In ImagePolicyWebhook Admission Controller
The Kubernetes API server includes a built-in admission controller called ImagePolicyWebhook. This controller works with an external webhook server to enforce image policy rules using an admission configuration file.
The diagram below illustrates the Kubernetes admission control process. It covers the steps from executing kubectl
commands through authentication, authorization, and admission controller validations, culminating in pod creation:
Admission Configuration File
An admission configuration file provides the necessary details for connecting to the webhook server. It includes a reference to a KubeConfig file for authentication credentials along with parameters such as TTLs, retry backoff intervals, and default behaviors. For example:
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: ImagePolicyWebhook
configuration:
imagePolicy:
kubeConfigFile: <path-to-kubeconfig-file>
allowTTL: 50
denyTTL: 50
retryBackoff: 500
defaultAllow: true
Default Behavior
If the admission webhook server is unreachable, setting defaultAllow: true
permits pod creation unless the webhook explicitly denies it. Adjust this setting based on your security requirements.
A typical KubeConfig file referenced above might look like this:
<path-to-kubeconfig-file>
clusters:
- name: name-of-remote-imagepolicy-service
cluster:
certificate-authority: /path/to/ca.pem
server: https://images.example.com/policy
users:
- name: name-of-api-server
user:
client-certificate: /path/to/cert.pem
client-key: /path/to/key.pem
Enabling the ImagePolicyWebhook in the kube-apiserver
After preparing the admission configuration file, you need to enable the ImagePolicyWebhook admission controller in the kube-apiserver. This is achieved by adding it to the enabled admission plugins flag and specifying the path to the configuration file through the admission control config file flag.
For example, if the kube-apiserver runs as a service, you can configure it with the following flags:
ExecStart=/usr/local/bin/kube-apiserver \
--advertise-address=${INTERNAL_IP} \
--allow-privileged=true \
--apiserver-count=3 \
--authorization-mode=Node,RBAC \
--bind-address=0.0.0.0 \
--enable-swagger-ui=true \
--etcd-servers=https://127.0.0.1:2379 \
--event-ttl=1h \
--runtime-config=api/all \
--service-cluster-ip-range=10.32.0.0/24 \
--service-node-port-range=30000-32767 \
--v=2 \
--enable-admission-plugins=ImagePolicyWebhook \
--admission-control-config-file=/etc/kubernetes/admission-config.yaml
If the kube-apiserver is deployed as a static pod (for example, in a kubeadm-based setup), include similar flags in the pod manifest:
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
name: kube-apiserver
namespace: kube-system
spec:
containers:
- command:
- kube-apiserver
- --authorization-mode=Node,RBAC
- --advertise-address=172.17.0.107
- --allow-privileged=true
- --enable-bootstrap-token-auth=true
- --enable-admission-plugins=ImagePolicyWebhook
image: k8s.gcr.io/kube-apiserver-amd64:v1.13.3
name: kube-apiserver
With these configurations, the ImagePolicyWebhook admission controller ensures that only container images from approved registries are used when creating pods. This significantly strengthens the overall security posture of your Kubernetes cluster.
Related Resources
For more detailed information on Kubernetes security practices, refer to the following resources:
That concludes this lesson. Proceed to the hands-on labs to practice these configurations and further solidify your understanding of securing Kubernetes clusters.
Watch Video
Watch video content
Practice Lab
Practice lab