> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Configure Image Provenance ImagePolicyWebhook Admission Controller

### More Info:

Configure Image Provenance for your deployment.

### Risk Level

Low

### Address

Security

### Compliance Standards

* CIS Kubernetes

### Triage and Remediation

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. **Review current admission controller configuration** (managed control plane: use cloud console/CLI; self-managed: control plane node)
           * Self-managed:
             ```bash theme={null}
             # On each control plane node
             grep -E -- '--admission-control|--enable-admission-plugins' /etc/kubernetes/manifests/kube-apiserver.yaml
             ```
           * Managed (EKS/AKS/GKE/OKE):
             * Open the cluster configuration in the provider console or CLI and locate the API server admission plugins section.
           * Decision: If `ImagePolicyWebhook` (or an equivalent image provenance admission plugin for your platform) is not enabled, image provenance via ImagePolicyWebhook is not configured.

        2. **Identify any existing image policy webhook configuration** (any machine with kubectl access)
           ```bash theme={null}
           kubectl get validatingwebhookconfigurations,mutatingwebhookconfigurations -A \
             -o wide | grep -i image || true
           kubectl get clusterrole,clusterrolebinding -A | grep -i image || true
           ```
           * Decision: If you see webhook configurations, ClusterRoles, or bindings clearly tied to image policy/provenance, note their names for detailed inspection.

        3. **Inspect image policy webhook behavior** (any machine with kubectl access)
           ```bash theme={null}
           # Replace with actual names found in step 2, if any
           kubectl get validatingwebhookconfigurations <name> -o yaml
           kubectl get mutatingwebhookconfigurations <name> -o yaml
           ```
           * Verify:
             * Scope: rules include `pods` (and optionally `deployments`, `replicasets`, etc.).
             * Failure policy: typically `Fail` to enforce provenance (not just audit).
             * Service/URL: points to a reachable webhook that validates image signatures/provenance.
           * Decision: If these conditions are not met, image provenance is not effectively enforced.

        4. **Assess current workload image provenance** (any machine with kubectl access)
           ```bash theme={null}
           kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{" "}{.metadata.name}{" "}{range .spec.containers[*]}{.image}{" "}{end}{"\n"}{end}' \
             | sort | uniq
           ```
           * Manually review a sample of images:
             * Determine whether they come from a trusted registry that supports signing/attestation.
             * Confirm that your intended image-signing or attestation tools (e.g., cosign, Notary, in-toto) are actually being used for these images.
           * Decision: If unsigned/unanalyzed images are allowed without webhook enforcement, provenance is not assured.

        5. **Design or refine the image policy and webhook** (any machine with kubectl access)
           * Based on your chosen provenance mechanism (e.g., cosign + policy engine):
             * Draft or update the webhook’s policy to:
               * Require images from specific registries or repositories.
               * Require valid signatures/attestations for allowed images.
               * Optionally block `:latest` or untagged images.
           * Implement by applying or updating manifests:
             ```bash theme={null}
             # Example placeholder; replace with your actual manifests
             kubectl apply -f image-policy-webhook-deployment.yaml
             kubectl apply -f image-policy-webhook-service.yaml
             kubectl apply -f image-policy-validatingwebhookconfiguration.yaml
             ```
           * Note: You must obtain or write these manifests according to the image provenance solution you adopt and the Kubernetes documentation; they are not auto-generated.

        6. **Verify enforcement of image provenance** (any machine with kubectl access)
           * Test pod creation with:
             ```bash theme={null}
             # Known non-compliant image (e.g., unsigned or from disallowed registry)
             kubectl run test-bad-image --image=registry.example.com/unsigned:test || true

             # Known compliant image (properly signed/attested)
             kubectl run test-good-image --image=registry.example.com/signed:test
             ```
           * Confirm results:
             * Non-compliant pod is rejected with an error message from the image policy webhook.
             * Compliant pod is admitted and runs.
           * If both are admitted or both are denied without reference to image policy, revisit steps 2–5 and adjust configuration and policy until the observed behavior matches your intended image provenance requirements.
      </Accordion>

      <Accordion title="Using kubectl">
        ```bash theme={null}
        # 1) Check if any ImagePolicyWebhook configuration exists in the cluster
        # Run on: any machine with kubectl access
        kubectl get validatingwebhookconfigurations,mutatingwebhookconfigurations \
          -o wide
        ```

        * **Potential problem indication:**
          * No webhook configuration objects related to image policy or provenance (names typically contain `imagepolicy`, `image-provenance`, `image-signature`, etc.).
          * Or only generic webhooks that clearly do not enforce image provenance.

        ***

        ```bash theme={null}
        # 2) Inspect details of any candidate webhook that might enforce image provenance
        # Replace the name with any likely candidate from the previous output
        kubectl get validatingwebhookconfigurations <WEBHOOK_NAME> -o yaml
        kubectl get mutatingwebhookconfigurations   <WEBHOOK_NAME> -o yaml
        ```

        Review in the YAML:

        * **`rules:`**
          * **Problem indication:** rules do **not** target `apiGroups: [""]`, `apiVersions: ["v1"]`, `resources: ["pods"]` (or other workload types where images are used), or only apply to irrelevant resources.
        * **`clientConfig:` (URL/service):**
          * **Problem indication:** points to a non-existent service, an HTTP (not HTTPS) endpoint, or uses invalid CA bundle, causing the webhook to be effectively bypassed.
        * **`failurePolicy:`**
          * **Problem indication:** set to `Ignore` so that if the image policy service fails, pod creation continues without image provenance checks.
        * **`namespaceSelector` / `objectSelector`:**
          * **Problem indication:** selectors exclude all or most namespaces/workloads where image provenance should be enforced (e.g., only selected namespaces, leaving production unprotected).
        * **`matchPolicy` / `sideEffects` / `admissionReviewVersions`:**
          * **Problem indication:** misconfiguration that would prevent the webhook from reliably receiving pod admission requests.

        ***

        ```bash theme={null}
        # 3) See what images are currently in use across the cluster
        # Run on: any machine with kubectl access
        kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{range .spec.containers[*]}{.image}{" "}{end}{"\n"}{end}' | sort
        ```

        * **Problem indication:**
          * Widespread use of untrusted or unverifiable image registries (e.g., random public registries) without any corresponding image policy webhook that validates signatures or provenance.
          * Inconsistent image sources that suggest lack of a controlled provenance strategy (e.g., mix of arbitrary Docker Hub images with no signed/private alternatives).

        ***

        ```bash theme={null}
        # 4) Check if any admission configuration references an ImagePolicyWebhook configuration (self-managed clusters)
        # NOTE: This only works if the apiserver manifest is accessible via a DaemonSet or hostPath pod.
        # Run on: a pod/container that can read /etc/kubernetes/manifests on control-plane nodes
        kubectl -n kube-system get pods -o wide
        # (Identify any pod that mounts /etc/kubernetes/manifests and exec into it, then:)
        kubectl -n kube-system exec -it <POD_NAME> -- \
          grep -R "admission-control-config-file" -n /etc/kubernetes/manifests
        ```

        * **Problem indication:**
          * No `--admission-control-config-file` (or equivalent) flag present pointing to a configuration that includes `imagePolicy` / `imagePolicyWebhook` settings.
          * Or a referenced admission config file exists but does not define any `imagePolicy` stanza.

        *(If you cannot access the API server manifest or flags from within the cluster, this part of the review must be done on the control-plane nodes directly and is outside the scope of kubectl.)*

        ***

        ```bash theme={null}
        # 5) For managed Kubernetes (EKS/AKS/GKE/OKE), inspect for known image or admission integrations
        # Run on: any machine with kubectl access
        kubectl get ns
        kubectl get pods -A
        kubectl get crd
        ```

        * **Problem indication:**
          * No vendor- or add-on–specific components that typically implement image provenance or admission enforcement (e.g., no image policy controllers, no Sigstore/Notary/Gatekeeper-style integrations), combined with the lack of webhooks found earlier.

        ***

        Use the results above to decide:

        * Whether an ImagePolicyWebhook (or equivalent admission mechanism) exists and is correctly wired to enforce image provenance on pod creation.
        * Whether the scope (namespaces/resources), failure behavior, and connectivity would realistically prevent unsigned/untrusted images from being admitted.

        Any absence or ineffective configuration indicates the cluster is **not** enforcing image provenance and requires a design and implementation decision rather than an automatic fix.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Audit script for CIS Kubernetes 5.5.1:
        # "Configure Image Provenance using ImagePolicyWebhook admission controller"
        #
        # Run on: any machine with kubectl access and cluster-admin privileges.

        set -euo pipefail

        echo "==[ 1. Check for ImagePolicyWebhook admission plugin on API servers ]=="

        # Try common API server discovery methods
        echo "[*] Discovering kube-apiserver endpoints..."

        APISERVER_ENDPOINTS=$(kubectl get pods -A -l component=kube-apiserver -o jsonpath='{range .items[*]}{.metadata.namespace}/{.metadata.name}{"\n"}{end}' 2>/dev/null || true)

        if [[ -n "${APISERVER_ENDPOINTS}" ]]; then
          echo "[*] Found kube-apiserver pods:"
          echo "${APISERVER_ENDPOINTS}"
          echo

          # Inspect pod specs for admission plugins / ImagePolicyWebhook mentions
          echo "[*] Searching kube-apiserver pod specs for ImagePolicyWebhook configuration..."
          kubectl get pods -A -l component=kube-apiserver -o yaml | \
            awk '
              BEGIN{found=0}
              /kube-apiserver/ {pod=$0}
              /--enable-admission-plugins/ || /--admission-control=/ || /ImagePolicyWebhook/ {
                print "----"; print "POD CONTEXT: " pod; print $0; found=1
              }
              END{ if(found==0) print "NO ImagePolicyWebhook references found in kube-apiserver pod specs." }
            '
        else
          echo "[!] No kube-apiserver pods discovered via label component=kube-apiserver."
          echo "    If this is a managed control plane (EKS/AKS/GKE/OKE), ImagePolicyWebhook"
          echo "    enablement must be checked in the provider's control-plane configuration."
        fi

        echo
        echo "==[ 2. Check for Mutating/ValidatingWebhookConfiguration objects ]=="

        echo "[*] Listing admission webhooks that might enforce image provenance..."
        kubectl get mutatingwebhookconfigurations,validatingwebhookconfigurations -o name || true
        echo

        echo "[*] Detailed search for webhooks referencing images, signatures, or policy engines..."
        kubectl get mutatingwebhookconfigurations,validatingwebhookconfigurations -o yaml 2>/dev/null | \
          awk '
            /kind: (MutatingWebhookConfiguration|ValidatingWebhookConfiguration)/{cfg=$0}
            /name: /{name=$0}
            /image/ || /provenance/ || /cosign/ || /notary/ || /connaisseur/ || /kyverno/ || /gatekeeper/ {
              print "----"; print cfg; print name; print $0;
            }
          ' || true

        echo
        echo "==[ 3. Check for ImagePolicyWebhook Configuration objects ]=="

        echo "[*] Searching for ImagePolicyWebhook configuration resources (if any CRD is in use)..."
        kubectl get crds 2>/dev/null | grep -i imagepolicy || echo "[*] No obvious image policy CRD names found."
        echo

        echo "==[ 4. Summary interpretation guidance ]=="
        cat <<'EOF'

        What output indicates a potential problem (non-compliance with CIS 5.5.1):

        1. API server flags:
           - If no kube-apiserver pod specs show:
               --enable-admission-plugins=...ImagePolicyWebhook...
             or equivalent admission configuration referencing ImagePolicyWebhook,
             then ImagePolicyWebhook is likely NOT enabled on this cluster.

        2. Webhook configurations:
           - If 'kubectl get mutatingwebhookconfigurations,validatingwebhookconfigurations'
             returns either nothing, or only webhooks unrelated to image verification
             (e.g., no refs to image provenance, signatures, cosign, notary, etc.),
             then there may be NO admission webhook enforcing image provenance.

        3. CRDs / Policy engines:
           - Absence of any CRD or webhook associated with image-policy / image-signature
             solutions (e.g., Cosign, Notary, Connaisseur, Kyverno policies about images)
             suggests that image provenance is not being validated.

        This script only reports state; configuring ImagePolicyWebhook and the backing
        policy/verification service must be done manually following Kubernetes and
        your tooling's documentation.
        EOF
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>

### Additional Reading:

* [https://github.com/kubernetes/community/blob/master/contributors/design-proposals/image-provenance.md](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/image-provenance.md)
