> ## 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 Using ImagePolicyWebhook Admission Controller

### More Info:

Verifies image provenance is enforced via the ImagePolicyWebhook admission controller so only approved, verified images can be admitted to the cluster.

### Risk Level

High

### Address

Security

### Compliance Standards

* CIS GKE

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. **Review current admission configuration for ImagePolicyWebhook**
           * Machine: any machine with kubectl access
           * Command:
             ```bash theme={null}
             kubectl get validatingwebhookconfigurations,mutatingwebhookconfigurations \
               -o yaml | grep -i -A5 -B5 "imagepolicy"
             ```
           * Interpretation: Check if any webhook configuration refers to an ImagePolicyWebhook implementation (e.g., names/URLs mentioning “image-policy”, “imageprovenance”, or your chosen image policy service). If none exist, image provenance via ImagePolicyWebhook is not configured.

        2. **Identify and inspect any image policy webhook configuration**
           * Machine: any machine with kubectl access
           * Commands:
             ```bash theme={null}
             kubectl get validatingwebhookconfigurations
             kubectl get mutatingwebhookconfigurations
             ```
             For each candidate webhook name (replace with actual name you saw, for example `image-policy-webhook`):
             ```bash theme={null}
             kubectl get validatingwebhookconfiguration image-policy-webhook -o yaml
             ```
           * Interpretation: Confirm that the webhook is configured to intercept `CREATE` and `UPDATE` operations on `pods` and/or higher-level workload types (Deployments, StatefulSets, DaemonSets, Jobs, CronJobs) in relevant API groups.

        3. **Verify the webhook enforces only approved, verified images**
           * Machine: any machine with kubectl access
           * From the webhook config YAML, collect:
             * `clientConfig.url` or `clientConfig.service` target
             * `rules.resources` and `rules.operations`
             * `failurePolicy` and `namespaceSelector`/`objectSelector`
           * Then retrieve the backing Service/Deployment implementing the webhook (example name, adjust as needed):
             ```bash theme={null}
             kubectl get svc,imagepolicy-deployment -n kube-system -o yaml
             kubectl logs deploy/imagepolicy-deployment -n kube-system --tail=100
             ```
           * Interpretation: Using your organization’s image policy design, confirm that the webhook backend validates image provenance (e.g., signature verification, allowed registries, allowed repositories/tags) and **rejects** non‑compliant images.

        4. **Check behavior with a non‑compliant image (safe test)**
           * Machine: any machine with kubectl access
           * Create a pod manifest using an image that should be rejected by policy (e.g., from an unapproved registry or with a disallowed tag):
             ```bash theme={null}
             cat <<'EOF' > /tmp/test-unapproved-image.yaml
             apiVersion: v1
             kind: Pod
             metadata:
               name: test-unapproved-image
               namespace: default
             spec:
               containers:
               - name: c
                 image: gcr.io/library/busybox:latest
                 command: ["sh", "-c", "sleep 3600"]
             EOF

             kubectl apply -f /tmp/test-unapproved-image.yaml
             ```
           * Interpretation: The request should be rejected by the webhook, with an error message indicating image policy violation. If the pod is admitted and runs, provenance is not effectively enforced.

        5. **If image provenance is missing or ineffective, plan and apply an ImagePolicyWebhook configuration**
           * Machine: any machine with kubectl access
           * Using Kubernetes documentation and your image verification solution, prepare:
             1. A Deployment/Service that implements image verification logic.
             2. A `ValidatingWebhookConfiguration` that:
                * Targets `CREATE`/`UPDATE` on workloads using containers.
                * Uses `failurePolicy: Fail` (or your risk‑based choice).
                * Uses appropriate `namespaceSelector` to include production namespaces.
           * Apply once designed:
             ```bash theme={null}
             kubectl apply -f /path/to/your-image-policy-webhook.yaml
             ```

        6. **Re‑verify enforcement and document the decision**
           * Machine: any machine with kubectl access
           * Confirm configuration and behavior after changes:
             ```bash theme={null}
             kubectl get validatingwebhookconfigurations -o yaml | grep -i -A5 -B5 "imagepolicy"
             kubectl delete pod test-unapproved-image --ignore-not-found
             kubectl apply -f /tmp/test-unapproved-image.yaml
             ```
           * Interpretation: Ensure the test pod is rejected; capture the webhook configuration and rejection output as evidence. If you intentionally choose not to enforce image provenance via ImagePolicyWebhook (e.g., using a different trusted mechanism), document that rationale and the alternative controls in your risk register.
      </Accordion>

      <Accordion title="Using kubectl">
        ```bash theme={null}
        # 1) Check if ImagePolicyWebhook admission plugin is enabled (GKE Autopilot/Standard)
        # Run on: any machine with kubectl access

        kubectl get podsecurityadmissionconfigurations --all-namespaces
        ```

        If this returns `No resources found` or there is no admission configuration mentioning `ImagePolicyWebhook`, you likely do not have a cluster-scoped admission configuration resource configured. In GKE, image provenance is typically configured via Binary Authorization rather than raw ImagePolicyWebhook; absence here means you must confirm how provenance is enforced.

        ```bash theme={null}
        # 2) List all Validating and MutatingWebhookConfigurations
        # Run on: any machine with kubectl access

        kubectl get validatingwebhookconfigurations,mutatingwebhookconfigurations -o wide
        ```

        Review the `NAME` and `WEBHOOKS` columns. A problem exists if:

        * There is no webhook related to image policy, image verification, or provenance (names often contain strings like `imagepolicy`, `binauthz`, `image-verify`, `cosign`, `notary`), and
        * You rely on this mechanism to enforce provenance (per your policy).

        ```bash theme={null}
        # 3) Inspect candidate webhook configurations for image provenance logic
        # Replace <webhook-name> with any likely image-related webhook name
        # Run on: any machine with kubectl access

        kubectl get validatingwebhookconfiguration <webhook-name> -o yaml
        kubectl get mutatingwebhookconfiguration <webhook-name> -o yaml
        ```

        In the YAML, focus on:

        * `webhooks.rules` → `apiGroups`, `apiVersions`, `resources`:\
          A problem exists if the webhook does not target pod/image-bearing resources such as:
          * `apiGroups: [""]`, `resources: ["pods", "pods/ephemeralcontainers"]`
          * Or workload types like `deployments`, `daemonsets`, `statefulsets`, `jobs`, `cronjobs`.

        * `webhooks.rules.operations`:\
          A problem exists if `CREATE` (and ideally `UPDATE`) operations are not included for these resources, because images could be introduced/changed without being checked.

        * `webhooks.clientConfig`:\
          A problem exists if the `service` or `url` targets a non-existent/broken backend (service missing, TLS misconfigured, or timeouts), meaning image checks may silently fail-open depending on `failurePolicy`.

        * `webhooks.failurePolicy`:\
          A problem exists if `failurePolicy: Ignore` is set, because if the external verifier is unreachable, images may be admitted without provenance verification. Many orgs require `failurePolicy: Fail`.

        * `webhooks.matchPolicy`, `namespaceSelector`, `objectSelector`:\
          A problem exists if selectors exclude namespaces or pods that should be governed by provenance policy (for example, all application namespaces are excluded).

        ```bash theme={null}
        # 4) Check whether the webhook is actually invoked on pod creation
        # Run on: any machine with kubectl access

        # Try to create a simple pod using an untrusted or obviously test image
        kubectl apply -f - <<'EOF'
        apiVersion: v1
        kind: Pod
        metadata:
          name: image-provenance-test
          namespace: default
        spec:
          containers:
          - name: test
            image: nginx:1.7.9 # adjust to an image that should be blocked by your policy
        EOF
        ```

        Interpretation:

        * If the pod is **created successfully** and your policy says unverified/unapproved images must be blocked, this indicates:
          * No effective image provenance enforcement, or
          * The webhook configuration does not cover this namespace/resource/type.

        * If the pod **fails to create** with an error message from an admission controller (e.g. mentioning image verification, signature, policy, or provenance), that indicates some form of image provenance enforcement is in place. Review the error details and webhook config to confirm it meets your policy and CIS guidance.

        ```bash theme={null}
        # 5) Clean up the test pod
        # Run on: any machine with kubectl access

        kubectl delete pod image-provenance-test -n default --ignore-not-found
        ```

        Use the above evidence to decide whether:

        * Image provenance is enforced (via ImagePolicyWebhook, Binary Authorization, or an equivalent validating webhook), and
        * The scope and failure behavior align with your security requirements and the benchmark recommendation.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        # Purpose: Report ImagePolicyWebhook / image provenance configuration cluster-wide
        # Scope:   Run on any machine with kubectl access and current kube-context set

        set -euo pipefail

        echo "=== 1) API server admission configuration (ImagePolicyWebhook) ==="
        echo
        echo "--- API Server Pod/Deployment manifests using ImagePolicyWebhook (if any) ---"
        kubectl get pods -A \
          -l component=kube-apiserver, tier=control-plane \
          -o wide 2>/dev/null || echo "No kube-apiserver pods with standard labels found"

        echo
        echo "--- API Server container args containing 'admission-control' or 'enable-admission-plugins' ---"
        kubectl get pods -A \
          -l component=kube-apiserver,tier=control-plane \
          -o jsonpath='{range .items[*]}Namespace: {.metadata.namespace} | Pod: {.metadata.name}{"\n"}  Args: {.spec.containers[*].command} {.spec.containers[*].args}{"\n\n"}{end}' \
          2>/dev/null || echo "Unable to fetch kube-apiserver pod args via standard labels."

        echo
        echo "--- API Server ConfigMap / flags (kube-apiserver) via kube-system namespace (best-effort) ---"
        kubectl get cm -n kube-system 2>/dev/null | grep -Ei 'apiserver|kube-apiserver' || \
          echo "No obvious kube-apiserver ConfigMaps found in kube-system."

        echo
        echo "NOTE: You must verify that the kube-apiserver process is started with:"
        echo "  - admission-control=...,ImagePolicyWebhook,...  (legacy)"
        echo "     OR"
        echo "  - enable-admission-plugins=...,ImagePolicyWebhook,...  (current)"
        echo "If ImagePolicyWebhook is missing from both, image provenance is NOT enforced by this mechanism."
        echo

        echo "=== 2) Validating/MutatingAdmissionConfiguration that references ImagePolicyWebhook ==="
        echo
        echo "--- AdmissionConfiguration resources (if API is enabled) ---"
        # This may fail if the AdmissionConfiguration API is not served
        kubectl get ValidatingAdmissionPolicyConfiguration 2>/dev/null || \
          echo "No ValidatingAdmissionPolicyConfiguration resources or API not available."
        kubectl get MutatingAdmissionPolicyConfiguration 2>/dev/null || \
          echo "No MutatingAdmissionPolicyConfiguration resources or API not available."

        echo
        echo "NOTE: Classic ImagePolicyWebhook configuration usually comes from an"
        echo "AdmissionConfiguration file/flag on the API server, not a Kubernetes object."
        echo "You must inspect the kube-apiserver startup flags or managed control-plane"
        echo "configuration to confirm whether an AdmissionConfiguration file is used and"
        echo "that it defines 'imagePolicy' with 'kubeConfigFile' and 'allowTTLSeconds', etc."
        echo

        echo "=== 3) Image policy / provenance enforcement using other admission mechanisms ==="
        echo
        echo "--- ValidatingWebhookConfiguration objects (may implement image provenance) ---"
        kubectl get validatingwebhookconfigurations.admissionregistration.k8s.io -o wide 2>/dev/null || \
          echo "No ValidatingWebhookConfiguration resources found."

        echo
        echo "--- MutatingWebhookConfiguration objects (may implement image mutation/signature checks) ---"
        kubectl get mutatingwebhookconfigurations.admissionregistration.k8s.io -o wide 2>/dev/null || \
          echo "No MutatingWebhookConfiguration resources found."

        echo
        echo "--- Details of webhooks that reference images or provenance keywords ---"
        webhook_keywords='image|cosign|notary|provenance|signature|sigstore|policy-controller'
        kubectl get validatingwebhookconfigurations.admissionregistration.k8s.io -o yaml 2>/dev/null | \
          egrep -i "$webhook_keywords" || \
          echo "No obvious image/provenance-related patterns found in ValidatingWebhookConfigurations."

        echo
        kubectl get mutatingwebhookconfigurations.admissionregistration.k8s.io -o yaml 2>/dev/null | \
          egrep -i "$webhook_keywords" || \
          echo "No obvious image/provenance-related patterns found in MutatingWebhookConfigurations."
        echo

        echo "=== 4) Namespaces or workloads explicitly bypassing admission webhooks ==="
        echo
        echo "--- Namespaces labeled to disable admission webhooks (common patterns) ---"
        kubectl get ns --show-labels 2>/dev/null | \
          egrep 'no\-webhook|skip\-webhook|admission\-skip|webhook=disabled' || \
          echo "No namespaces with obvious 'skip webhook' labels using common patterns."
        echo

        echo "--- Pods using hostNetwork or privileged (high risk if image provenance is weak) ---"
        kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{" "}{.metadata.name}{" hostNet="}{.spec.hostNetwork}{" privileged="}{range .spec.containers[*]}{.securityContext.privileged}{" "}{end}{"\n"}{end}' 2>/dev/null || \
          echo "Unable to list pod security context details."
        echo

        echo "=== 5) Summary: what indicates a problem ==="
        cat <<'EOF'
        Review guidance:

        1) API server flags:
           - PROBLEM if:
             * kube-apiserver is NOT configured with ImagePolicyWebhook via either:
               - --admission-control including ImagePolicyWebhook
               - --enable-admission-plugins including ImagePolicyWebhook
             AND you have no alternative enforced image provenance mechanism (e.g. cosign-based webhook).

        2) AdmissionConfiguration:
           - PROBLEM if:
             * API server references an AdmissionConfiguration file, but it does NOT define
               an 'imagePolicy' section pointing to a kubeConfigFile for the webhook and
               appropriate allow/deny behavior; or the referenced webhook service does not exist.

        3) Webhooks:
           - POTENTIAL PROBLEM if:
             * There are no ValidatingWebhookConfiguration or MutatingWebhookConfiguration
               objects that implement image signature/provenance checks (by design or by name),
               and ImagePolicyWebhook is also not configured.

        4) Bypasses:
           - PROBLEM / RISK if:
             * Critical namespaces or workloads are labeled/annotated to skip admission webhooks,
               effectively bypassing image provenance checks.

        This script does NOT automatically determine compliance.
        You must:
          - Confirm the kube-apiserver startup configuration (flags / managed control-plane settings).
          - Confirm whether an ImagePolicyWebhook or equivalent webhook is deployed and reachable.
          - Decide whether the observed configuration satisfies your image provenance policy.
        EOF
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
