Minimize Container Registries To Only Those Approved
More Info:
Scan images being deployed to Amazon EKS for vulnerabilities.
Risk Level
Low
Address
Security
Compliance Standards
- APRA CPS 234 (Australia)
- BSI C5 (Germany)
- Brazil LGPD
- CCPA / CPRA (California)
- CIS Critical Security Controls v8
- CIS GKE
- CMMC 2.0
- CSA Cloud Controls Matrix v4
- DPDPA
- Digital Operational Resilience Act (EU)
- Essential 8
- ISO/IEC 27017
- ISO/IEC 27018
- ISO/IEC 27701
- KSA PDPL
- MAS Technology Risk Management (Singapore)
- MITRE ATT&CK (Cloud)
- NIS2 Directive
- NIST SP 800-171
- NYDFS 23 NYCRR 500
- SWIFT Customer Security Controls Framework
- Sarbanes-Oxley IT General Controls
- UK NCSC Cyber Assessment Framework
Triage and Remediation
- Remediation
Remediation
Manual Steps
-
Identify all container registries currently in use
- On any machine with access to the project:
# List all images currently deployed to the cluster and extract registriesgcloud container clusters get-credentials CLUSTER_NAME --region REGION --project PROJECT_IDkubectl get pods --all-namespaces -o jsonpath='{range .items[*]}{.spec.containers[*].image}{"\n"}{.spec.initContainers[*].image}{"\n"}{end}' \| tr ' ' '\n' | sed '/^$/d' | sort -u \| sed 's#^\([^/]*\)/.*#\1#' | sort -u
- Compare the resulting list of registries (e.g.,
gcr.io,us-docker.pkg.dev,docker.io, others) to your organization’s approved registry list.
- On any machine with access to the project:
-
Determine clusters and projects where Binary Authorization should be enforced
- On any machine with
gcloudconfigured:gcloud projects listgcloud container clusters list --project PROJECT_ID --region REGION - For each cluster in scope, decide whether all workloads must be restricted to approved registries or whether exceptions are required (e.g., third‑party images that cannot be mirrored).
- On any machine with
-
Review current Binary Authorization configuration and policy (if any)
- On any machine with
gcloudconfigured:# Check if Binary Authorization is enabled on the clustergcloud container clusters describe CLUSTER_NAME \--region REGION --project PROJECT_ID \--format="value(binaryAuthorization.enabled)"# View the current project-level Binary Authorization policygcloud container binauthz policy export \--project PROJECT_ID > current-binauthz-policy.yaml - Inspect
current-binauthz-policy.yamlto see whether it exists and whether anyadmissionRuleordefaultAdmissionRulereferences constraints on image registries (e.g., via attestor requirements or image pattern constraints).
- On any machine with
-
Design or update the approved-registry policy
- Using the exported
current-binauthz-policy.yamlas a base (or the reference YAML in the Binary Authorization Policy Reference), decide:- Which registries (e.g.,
gcr.io/ORG/*,us-docker.pkg.dev/PROJECT/*) are allowed. - Whether images from unapproved registries should be blocked or only warned (for initial rollout).
- Which registries (e.g.,
- Edit a local policy file, for example:
nano updated-binauthz-policy.yaml
- In that file, define or adjust admission rules to require that images match only the allowed registry patterns, and decide what to do with non-matching images (e.g.,
alwaysDenyfor strict enforcement, or attestation-based exceptions).
- Using the exported
-
Enable Binary Authorization on the cluster and apply the policy
- On any machine with
gcloudconfigured:# Enable Binary Authorization on the cluster (if not already enabled)gcloud container clusters update CLUSTER_NAME \--region REGION --project PROJECT_ID \--enable-binauthz# Import the updated policygcloud container binauthz policy import updated-binauthz-policy.yaml \--project PROJECT_ID - Be aware that tightening the policy can cause new pod creations or updates using disallowed registries to be rejected; plan for staged rollout and testing.
- On any machine with
-
Verify that only approved registries are allowed going forward
- On any machine with
gcloudandkubectlconfigured:# Confirm cluster shows Binary Authorization as enabledgcloud container clusters describe CLUSTER_NAME \--region REGION --project PROJECT_ID \--format="value(binaryAuthorization.enabled)"# Attempt to deploy a test workload from an unapproved registry (should be denied)kubectl run test-unapproved \--image=UNAPPROVED_REGISTRY/namespace/image:tag \--restart=Never# Attempt to deploy a test workload from an approved registry (should be allowed)kubectl run test-approved \--image=APPROVED_REGISTRY/namespace/image:tag \--restart=Never - Confirm that the unapproved image is rejected by admission control and that the approved image runs successfully, then remove the test pods.
- On any machine with
Using kubectl
kubectl cannot configure which container registries are allowed for image pulls or enable Binary Authorization; this control is managed at the GKE control‑plane / project level via gcloud, the GCP console, or IaC. Refer to the Manual Steps section for the exact gcloud commands and policy configuration needed to restrict registries.
Automation
#!/usr/bin/env bash
#
# Report all unique image registries used by workloads in a GKE cluster.
# Run on: any machine with kubectl access and context set to the target cluster.
#
# This does NOT change anything; it only reports for review.
set -euo pipefail
echo "Collecting images from all namespaces and workload types..." >&2
# Collect images from common workload types
images=$(
{
kubectl get pods --all-namespaces -o json;
kubectl get deployments.apps --all-namespaces -o json;
kubectl get daemonsets.apps --all-namespaces -o json;
kubectl get statefulsets.apps --all-namespaces -o json;
kubectl get jobs.batch --all-namespaces -o json;
kubectl get cronjobs.batch --all-namespaces -o json 2>/dev/null || true;
} \
| jq -r '
.. | .image? // empty
' \
| sort -u
)
if [[ -z "${images}" ]]; then
echo "No images found in the cluster (no running or configured workloads?)" >&2
exit 0
fi
echo
echo "=== Unique images found in the cluster ================================="
printf '%s\n' "${images}"
echo "========================================================================"
echo
# Derive registries from images
# Rules:
# - If image contains '/', take the first path segment as 'registry_or_namespace'
# - If that segment contains a '.', ':' or is 'localhost', treat it as a registry
# - Otherwise, treat image as using the default Docker Hub registry
registries=$(
printf '%s\n' "${images}" \
| awk -F/ '
{
if (NF == 1) {
# No "/" → implicit default registry (Docker Hub)
print "<default-docker-registry>"
} else {
first = $1
if (first ~ /\./ || first ~ /:/ || first == "localhost") {
print first
} else {
# Looks like a namespace on Docker Hub (e.g. library/nginx)
print "<default-docker-registry>"
}
}
}
' \
| sort -u
)
echo "=== Derived image registries in use ====================================="
printf '%s\n' "${registries}"
echo "======================================================================="
echo
echo "Review guidance:"
echo "1) Define your APPROVED registries list (for example):"
echo " - gcr.io"
echo " - us.gcr.io"
echo " - eu.gcr.io"
echo " - asia.gcr.io"
echo " - <your-project>.gcr.io"
echo " - <default-docker-registry> (ONLY if Docker Hub is explicitly approved)"
echo
echo "2) Any registry shown above that is NOT on your approved list is a potential problem."
echo " Examples of suspicious output:"
echo " - docker.io or <default-docker-registry> if public Docker Hub is not approved"
echo " - quay.io, ghcr.io, registry.hub.docker.com, or arbitrary hostnames"
echo " - localhost:5000 or other ad-hoc registries not in policy"
echo
echo "3) For each unapproved registry:"
echo " - Identify which workloads use it:"
echo " kubectl get pods --all-namespaces -o wide | grep '<registry-fragment>'"
echo " kubectl get deploy,sts,ds,job,cronjob --all-namespaces -o yaml | grep '<registry-fragment>' -n"
echo " - Decide whether to:"
echo " * Migrate images to an approved registry, and/or"
echo " * Block them via a Binary Authorization policy as per CISGKE 5.1.4."
echo
echo "This script only surfaces current usage; enforcement must be configured via"
echo "GKE/Binary Authorization policy (cloud provider control plane), not kubectl."