Image Policy Admission Controller & Admission Controllers


Image Policy Admission Controller

* ImagePolicyWebhook admission controller

* adds new field to Pod, e.g. pod.spec.container[i].imageID (or an annotation). and kubelet will enforce that both the imageID and image match the image pulled.


* It does not cover Post Pod creation audit (out of scope)

** images allowed due to backend not reachable

** images that kept running after policy change (e.g. CVE discovered)

** images started via local files or http option of kubelet

** checking SHA of images allowed by a tag which was remapped


* Alternatives

1 Admission Control on Controller Objects

2 Enforcement at Docker level:  twistlock/authz Docker plugin

3 Policy Stored in API (PSP) depends on

*** Dockerfile, 

*** the source code, 

*** the source repo, 

*** the source review tools, 

*** vulnerability databases

4 Registry whitelist/blacklist by prefix match on image strings

5 Send every Request to a Generic Admission Control Backend

How to implement?

Three relevant files

1 . Configuration of admission control. Let's say it A.yaml. It is specified using --admission-control-config-file flag at API-server pod's YAML

--admission-control-config-file=/etc/kubernetes/A.yaml

Content of /etc/kubernetes/A.yaml

kind: AdmissionConfiguration
plugins:
- name: ImagePolicyWebhook
  path: /etc/kuberenets/B.yaml

2. Configuration of Image Policy. Let's say it is B.yaml OR B.json. It is specified in A.yaml as above

Here is content of /etc/kuberenets/B.yaml

      imagePolicy:
        kubeConfigFile: /etc/kubernetes/admission/C
        allowTTL: 50
        denyTTL: 50
        retryBackoff: 500
        defaultAllow: false # DENY ALL PODS IF SERVICE NOT AVAILABLE

3. kubeconfig file. Ler's tell it as file C. It is specified in file B, as above

Here is partial C file

# clusters refers to the remote service.
clusters:
- name: name-of-remote-imagepolicy-service
  cluster:
    certificate-authority: /path/to/ca.pem    # CA for verifying the remote service.
    server: https://images.example.com/policy # URL of remote service to query. Must use 'https'.
# users refers to the API server's webhook configuration.
users:
- name: name-of-api-server
  user:
    client-certificate: /path/to/cert.pem # cert for the webhook admission controller to use
    client-key: /path/to/key.pem          # key matching the cert

Note: We can remove B.yaml 2 and put its content to A.yaml. Now A.yaml will point to kubeConfigFile C, as below

apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: ImagePolicyWebhook
  configuration:
    imagePolicy:
      kubeConfigFile: /etc/kubernetes/admission/C
      allowTTL: 50
      denyTTL: 50
      retryBackoff: 500
      defaultAllow: true

Admission Controllers

List of admission controllers are enabled by default

  • NamespaceLifecycle
  • LimitRanger, 
  • ServiceAccount
  • TaintNodesByCondition, 
  • Priority, 
  • DefaultTolerationSeconds, 
  • DefaultStorageClass, 
  • StorageObjectInUseProtection, 
  • PersistentVolumeClaimResize, 
  • RuntimeClass, 
  • CertificateApproval, 
  • CertificateSigning, 
  • CertificateSubjectRestriction, 
  • DefaultIngressClass, 
  • MutatingAdmissionWebhook, 
  • ValidatingAdmissionWebhook, 
  • ResourceQuota

As per CSI following plugins shall be enabled

  • EventRateLimit,
  • AlwaysPullImages,
  • PodSecurityPolicy OR SecurityContextDeny
  • NodeRestriction

As per CSI following plugins shall be disabled

  • ServiceAccount
  • NamespaceLifecycle
  • AlwaysAdmit