All Policies

Check Image Base

Container images can be built from a variety of sources, including other preexisting images. Ensuring images that are allowed to run are built from known, trusted images where their provenance is guaranteed can be an important step in ensuring overall cluster security. This policy ensures that any container image specifies some base image in its metadata from four possible sources: Docker BuildKit, OCI annotations (in manifest or config), or Buildpacks. Note that the ability to detect the presence of a base image is not implicit and requires the author to specify it using metadata or build directives of some sort (ex., Dockerfile FROM statements do not automatically expose this information).

Policy Definition

/other/require-base-image/require-base-image.yaml

 1apiVersion: kyverno.io/v1
 2kind: ClusterPolicy
 3metadata:
 4  name: require-base-image
 5  annotations:
 6    policies.kyverno.io/title: Check Image Base
 7    policies.kyverno.io/category: Other
 8    policies.kyverno.io/severity: medium
 9    kyverno.io/kyverno-version: 1.7.0
10    policies.kyverno.io/minversion: 1.7.0
11    kyverno.io/kubernetes-version: "1.23"
12    policies.kyverno.io/subject: Pod
13    policies.kyverno.io/description: >-
14      Container images can be built from a variety of sources, including other preexisting
15      images. Ensuring images that are allowed to run are built from known, trusted
16      images where their provenance is guaranteed can be an important step in ensuring
17      overall cluster security. This policy ensures that any
18      container image specifies some base image in its metadata from four possible sources:
19      Docker BuildKit, OCI annotations (in manifest or config), or Buildpacks. Note that the
20      ability to detect the presence of a base image is not implicit and requires the author
21      to specify it using metadata or build directives of some sort (ex., Dockerfile FROM
22      statements do not automatically expose this information).      
23spec:
24  validationFailureAction: audit
25  rules:
26  - name: check-base-image
27    match:
28      any:
29      - resources:
30          kinds:
31          - Pod
32    preconditions:
33      all:
34      - key: "{{request.operation}}"
35        operator: NotEquals
36        value: DELETE
37    validate:
38      message: "Images must specify a source/base image from which they are built."
39      foreach:
40      - list: "request.object.spec.containers"
41        context: 
42        - name: imageData
43          imageRegistry: 
44            reference: "{{ element.image }}"
45        - name: mobysource
46          variable:
47            jmesPath: imageData.configData."moby.buildkit.buildinfo.v1" | base64_decode(@).parse_json(@) | sources[?type == 'docker-image'].ref | length(@)
48            default: 0
49        - name: ocisourcelabels
50          variable:
51            jmesPath: imageData.configData.config.Labels | keys(@)
52            default: []
53        - name: ocisourceannotations
54          variable:
55            jmesPath: imageData.manifest.annotations."org.opencontainers.image.base.name"
56            default: ''
57        - name: buildpacks
58          variable:
59            jmesPath: parse_json(imageData.configData.config.Labels."io.buildpacks.lifecycle.metadata").runImage.reference || parse_json(imageData.configData.config.Labels."io.buildpacks.lifecycle.metadata").stack.runImage.image
60            default: ''
61        deny:
62          conditions:
63            all:
64              - key: "org.opencontainers.image.base.name"
65                operator: AnyNotIn
66                value: "{{ ocisourcelabels}}"
67              - key: "{{ ocisourceannotations}}"
68                operator: Equals
69                value: ''
70              - key: "{{ mobysource }}"
71                operator: Equals
72                value: 0
73              - key: "{{ buildpacks }}"
74                operator: Equals
75                value: ''
76