> ## 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.

# Ensure Image Vulnerability Scanning Using Amazon ECR Or Third Party Provider

### More Info:

Enable image vulnerability scanning on Amazon ECR (scan-on-push) or a third-party provider so that container images are checked for known vulnerabilities before deployment.

### Risk Level

Medium

### Address

Security

### Compliance Standards

* CIS EKS

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. **Identify all image sources used by the cluster**
           * On any machine with `kubectl` access, list all images currently referenced in workloads:
             ```bash theme={null}
             kubectl get pods --all-namespaces -o jsonpath='{range .items[*]}{.spec.containers[*].image}{"\n"}{.spec.initContainers[*].image}{"\n"}{end}' \
               | tr ' ' '\n' | sort -u
             ```
           * From this list, determine which images are pulled from Amazon ECR (`*.dkr.ecr.*.amazonaws.com`) and which come from other registries (for potential third‑party scanning).

        2. **Check ECR repositories for scan-on-push configuration (AWS CLI)**
           * On any machine with AWS CLI access and appropriate IAM permissions, for each AWS account/region that hosts ECR images, run:
             ```bash theme={null}
             aws ecr describe-repositories --region us-east-1 --query 'repositories[].repositoryName' --output text
             ```
           * For each repository listed, check its scanning configuration:
             ```bash theme={null}
             aws ecr describe-repositories \
               --repository-names REPLACE_WITH_REPOSITORY_NAME \
               --region us-east-1 \
               --query 'repositories[].imageScanningConfiguration'
             ```
           * Record which repositories have `"scanOnPush": true` and which do not.

        3. **Enable or correct ECR scan-on-push settings where missing**
           * For any ECR repository that does not have scan-on-push enabled, set it:
             ```bash theme={null}
             aws ecr put-image-scanning-configuration \
               --repository-name REPLACE_WITH_REPOSITORY_NAME \
               --image-scanning-configuration scanOnPush=true \
               --region us-east-1
             ```
           * For new repositories you manage via IaC (CloudFormation/Terraform), ensure the repository definition includes the equivalent of `scanOnPush=true` so future repos are compliant by default.

        4. **Run ad‑hoc scans for existing images that may predate scan-on-push**
           * In the AWS console, go to `https://console.aws.amazon.com/ecr/repositories`, select the correct Region, then open each repository that contains images used by your EKS cluster.
           * On the **Images** tab of a repository, select important/tagged images (e.g., `latest`, release tags) and choose **Scan** to perform manual scans, prioritizing images currently deployed in the cluster.

        5. **Evaluate and document third‑party scanning (if using non‑ECR registries)**
           * For any non‑ECR registry discovered in step 1, confirm whether a vulnerability scanning solution is in place (e.g., native registry scanning, CI pipeline scanner, or external scanning service).
           * Collect evidence such as:
             * Registry or scanner configuration showing automatic scans on push or on schedule.
             * Sample scan reports for images actually deployed in the cluster.
           * If no scanning exists for a given registry, plan and implement a scanning solution comparable in coverage to ECR’s image scanning.

        6. **Verify effective coverage for all deployed images**
           * Cross‑check: every image from step 1 should either reside in an ECR repository with `scanOnPush=true` or in a non‑ECR registry with documented, active vulnerability scanning.
           * Optionally, spot‑check a few images by pulling their latest scan results in ECR (via console or CLI) or your third‑party tool, to confirm scans are actually running and producing findings.
      </Accordion>

      <Accordion title="Using kubectl">
        This control is configured in AWS ECR and/or your chosen image scanning provider, not in Kubernetes objects, so it cannot be fixed with `kubectl`. Make the changes in the AWS console, AWS CLI, or your IaC definitions for ECR repositories, and then follow the guidance in the Manual Steps section.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        # Purpose: Report which container images used in the cluster are stored in ECR
        #          and whether their repositories have scan-on-push enabled.

        set -euo pipefail

        # --------- CONFIGURATION ---------
        # AWS CLI profile and region used to query ECR
        AWS_PROFILE="default"
        AWS_REGION="us-east-1"

        # ---------------------------------
        echo "Collecting unique container images from all namespaces..."
        IMAGES=$(
          kubectl get pods --all-namespaces -o jsonpath='{range .items[*]}{range .spec.containers[*]}{.image}{"\n"}{end}{range .spec.initContainers[*]}{.image}{"\n"}{end}{end}' \
          | sort -u
        )

        if [ -z "$IMAGES" ]; then
          echo "No images found in the cluster."
          exit 0
        fi

        echo "Discovered images:"
        printf '  %s\n' $IMAGES
        echo

        # Function: parse ECR registry, repository, and tag from an image string
        parse_ecr_image() {
          local image="$1"

          # Match public or private ECR:
          # private: 123456789012.dkr.ecr.us-east-1.amazonaws.com/repo[:tag]
          # public:  public.ecr.aws/alias/repo[:tag]
          if [[ "$image" =~ ^([0-9]{12}\.dkr\.ecr\.[a-z0-9-]+\.amazonaws\.com)/(.*)$ ]]; then
            local registry="${BASH_REMATCH[1]}"
            local remainder="${BASH_REMATCH[2]}"
          elif [[ "$image" =~ ^(public\.ecr\.aws)/(.*)$ ]]; then
            local registry="${BASH_REMATCH[1]}"
            local remainder="${BASH_REMATCH[2]}"
          else
            # Not an ECR image
            return 1
          fi

          # Split remainder into repo and tag/digest
          # repo:tag or repo@sha256:...
          local repo="${remainder%%[@:]*}"
          local tag_or_digest="${remainder#"$repo"}"
          local tag=""

          if [[ "$tag_or_digest" == ":"* ]]; then
            tag="${tag_or_digest#:}"
          elif [[ "$tag_or_digest" == "@"* ]]; then
            tag="${tag_or_digest#@}"
          else
            tag="latest"
          fi

          echo "$registry" "$repo" "$tag"
          return 0
        }

        echo "Checking ECR scan-on-push configuration for all ECR-backed images..."
        echo

        # Collect unique ECR repositories referenced by the cluster
        declare -A ECR_REPOS=()

        while read -r img; do
          parsed=$(parse_ecr_image "$img" || true)
          if [ -n "$parsed" ]; then
            registry=$(awk '{print $1}' <<< "$parsed")
            repo=$(awk '{print $2}' <<< "$parsed")
            key="$registry/$repo"
            ECR_REPOS["$key"]=1
          fi
        done <<< "$IMAGES"

        if [ "${#ECR_REPOS[@]}" -eq 0 ]; then
          echo "No ECR images are currently used by this cluster."
          echo "Potential issue: Images may be coming from registries where vulnerability scanning is not configured or not centrally visible."
          exit 0
        fi

        echo "ECR repositories referenced by the cluster:"
        for key in "${!ECR_REPOS[@]}"; do
          echo "  $key"
        done
        echo

        # Query scan-on-push for each ECR repo
        echo "Repository scan-on-push status (AWS_PROFILE=$AWS_PROFILE, AWS_REGION=$AWS_REGION):"
        echo

        for key in "${!ECR_REPOS[@]}"; do
          registry="${key%%/*}"
          repo="${key#"$registry/"}"

          # Private ECR repositories live in specific regions and accounts.
          # Skip public ECR (public.ecr.aws) here; scanning configuration is different.
          if [[ "$registry" == "public.ecr.aws" ]]; then
            echo "public.ecr.aws/$repo : SKIPPED (public ECR; verify scanning configuration manually)"
            continue
          fi

          # Extract account ID and region from registry
          # Example registry: 123456789012.dkr.ecr.us-east-1.amazonaws.com
          account_id="${registry%%.*}"
          reg_region="$(cut -d'.' -f4 <<< "$registry")"

          # Only check in the configured AWS_REGION to avoid cross-region confusion
          if [ "$reg_region" != "$AWS_REGION" ]; then
            echo "$registry/$repo : SKIPPED (registry region $reg_region != configured AWS_REGION $AWS_REGION; run script per region)"
            continue
          fi

          # Query ECR for scan-on-push
          set +e
          SCAN_OUTPUT=$(AWS_PROFILE="$AWS_PROFILE" AWS_REGION="$AWS_REGION" aws ecr describe-repositories \
            --repository-names "$repo" \
            --query "repositories[0].imageScanningConfiguration.scanOnPush" \
            --output text 2>&1)
          status=$?
          set -e

          if [ $status -ne 0 ]; then
            echo "$registry/$repo : ERROR querying ECR: $SCAN_OUTPUT"
            continue
          fi

          if [ "$SCAN_OUTPUT" = "True" ]; then
            echo "$registry/$repo : scanOnPush=ENABLED"
          elif [ "$SCAN_OUTPUT" = "False" ]; then
            echo "$registry/$repo : scanOnPush=DISABLED  <-- REVIEW: images from this repo are not auto-scanned on push"
          else
            echo "$registry/$repo : UNKNOWN response: $SCAN_OUTPUT"
          fi
        done

        echo
        echo "INTERPRETATION:"
        echo "- Any line ending with 'scanOnPush=DISABLED' indicates a repository used by the cluster whose images are not automatically scanned on push; this is a gap against the control."
        echo "- 'SKIPPED' lines require manual review to confirm that an equivalent vulnerability scanning mechanism is enabled for those registries."
        ```

        Explanation of problematic output:

        * `scanOnPush=DISABLED` for any `registry/repo` used by running pods indicates that Amazon ECR image scanning on push is not enabled for that repository and should be reviewed and remediated.
        * `SKIPPED` entries (public ECR or different regions) mean the script could not automatically confirm scanning; you must verify that either ECR scanning or a third-party vulnerability scanner is in place for those images.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
