Create policy to block vulnerable images from your cluster
This feature is tech preview. Tech preview features may be subject to significant changes before they become GA.
Big picture
Protecting your cluster from vulnerable images can be very difficult. An image that appears to be secure today could contain a newly-discovered vulnerability tomorrow, and acting on this new information in real time can be challenging.
Calico Cloud’s Image Assurance Admission Controller automatically blocks resources that would create containers with vulnerable images from entering your cluster using the latest vulnerability data and scan results.
Concepts
About the Calico Cloud Admission Controller
Calico Cloud uses Kubernetes Validating Webhook Configuration to register the Calico Cloud Admission Controller as a callback to accept or reject resources that create pods (such as deployments and daemonsets).
How the Admission Controller evaluates admission requests
The Calico Cloud Admission Controller blocks the creation or modification of resources that create pods. If a resource that creates pods is admitted by the Admission Controller, the pods it creates are not reevaluated. For example, if you create a deployment, the Admission Controller receives an admission request and either allows or rejects the request. If allowed, the Admission Controller will not evaluate the request for the replica set that Kubernetes creates for the deployment or the pod that is created for the replica set. Why? Because it could destabilize a production cluster if new vulnerabilities are found for deployed images and pods are restarted.
However, if you create a pod directly, the Admission Controller evaluates the admission request for the pod and allows or rejects the request.
About container admission policies
Container admission policies are custom Kubernetes resources that allow you to configure the criteria for the Admission Controller to reject admission requests for resources that create pods.
How to
Install the Admission Controller
-
Create a directory to download the manifests/scripts needed for the installation.
mkdir admission-controller-install && cd admission-controller-install
-
Generate the certificate key pair.
For secure TLS communication between the Kubernetes API server and the Admission controller, you must generate a TLS certificate and key pair.
You can either generate the TLS key and certificate yourself and move them to the current folder under the names
admission_controller_key.pem
andadmission_controller_cert.pem
, or use the following command to generate the pair:export URL="https://installer.calicocloud.io/manifests/v3.20.0-1.0-18/manifests" && curl ${URL}/generate-open-ssl-key-cert-pair.sh | bash
cautionIf you generate the key and certificate pair yourself, you must set the SANS to
tigera-image-assurance-admission-controller-service.tigera-image-assurance.svc
. -
Download and configure the Admission Controller manifests.
As a safety mechanism, we require that you specify the namespaces that the Admission Controller will apply in
the IN_NAMESPACE_SELECTOR_KEY
and the IN_NAMESPACE_SELECTOR_VALUES
. These values configure the Kubernetes API server to send admission requests to our Admission Controller only for resources from relevant namespaces.
For example, to configure the Kubernetes API server to send admission requests for
resources created in any namespace with label key name
, and label values either prod
or staging-test
, set the variables as follows:
export IN_NAMESPACE_SELECTOR_KEY="name" && export IN_NAMESPACE_SELECTOR_VALUES="prod staging-test"
Here is the namespace manifest with the staging-test label and name key.
kind: Namespace
apiVersion: v1
metadata:
name: staging-test
labels:
name: staging-test
Do not add Kubernetes critical namespaces such as the kube-system
namespace. This could create a
deadlock situation where you cannot bring up the Admission Controller because a critical Kubernetes pod is not running, but you also cannot bring up the critical Kubernetes pod because the Admission Controller is not running.
export IN_NAMESPACE_SELECTOR_KEY="name" && \
export IN_NAMESPACE_SELECTOR_VALUES="prod staging-test" && \
curl ${URL}/install-ia-admission-controller.sh | bash
-
Apply the Admission Controller manifests.
kubectl apply -f ./tigera-image-assurance-admission-controller-deploy.yaml
Create container admission policies
Container admission policies are used to define criteria for the Admission Controller to admit or reject admission for resources that create pods. For details, see ContainerAdmissionPolicies.
Sample container admission policies
This ContainerAdmissionPolicy allows admission requests for pod-creating resources whose image is in the registry/repository gcr.io/company/production-repository/*
, with a scan status of either Pass
or Warn
, and rejects all other admission requests.
apiVersion: containersecurity.tigera.io/v1beta1
kind: ContainerAdmissionPolicy
metadata:
name: reject-failed-and-non-gcr
spec:
selector: all()
namespaceSelector: all()
order: 10
rules:
- action: 'Reject'
imagePath:
operator: IsNoneOf
values:
- '^gcr.io/company/production-repository/.*'
- action: Allow
imageScanStatus:
operator: IsOneOf
values:
- Pass
- Warn
- action: Reject
The following ContainerAdmissionPolicy rejects deploying or updating pod-creating resources with the label, reject-policy: reject-outdated-scans
,
from any namespace labeled, apply-container-admission-policies == 'true'
, that would deploy an image that hasn't been scanned in 3 days.
apiVersion: containersecurity.tigera.io/v1beta1
kind: ContainerAdmissionPolicy
metadata:
name: reject-failed-and-non-gcr
spec:
selector: "reject-policy == 'reject-outdated-scans'"
namespaceSelector: "apply-container-policies == 'true'"
order: 1
rules:
- action: Allow
imageLastScan:
operator: 'gt'
duration:
days: 3
- action: Reject
The first rule (Allow), allows images based on the age of the image scan (in days). In this example, we want to allow images that have been scanned within the last three days. So, we use the gt operator (greater than), along with Duration, 3 days, to say the image scan time must be greater than 3 days ago but less than now. "Now" is defined as when the attempt was made to create the Kubernetes resource. If the Allow rule does not match, then the second action rule (Reject) is evaluated, which denies everything.
You can also use modify the Allow rule to match an absolute time. For help, see ContainerAdmissionPolicies.
Troubleshoot
My container admission policy is not blocking resources from a namespace, even though the namespaceSelector matches the namespace
This indicates that the Kubernetes API server is not sending admission requests for the namespace. Verify that the key and value(s) that you specified for IN_NAMESPACE_SELECT_KEY
and IN_NAMESPACE_SELECT_VALUES
in the installation steps, match the policy namespaces.