Microsoft Defender for Cloud · Azure Kubernetes Service
Container images should be deployed from trusted registries only
Written and reviewed by Emnode · Last reviewed
What does the recommendation "Container images should be deployed from trusted registries only" check?
Flags AKS clusters that allow pods to run images pulled from registries outside an approved list. The check is enforced by the Azure Policy add-on (Gatekeeper) as an admission control: every image reference on a new or updated pod is matched against an 'allowed registries regex' parameter, and anything that does not match is reported as non-compliant. It governs the registry an image comes from, not the contents of the image. It does not scan images for vulnerabilities, verify image signatures, or check digests, and a cluster with no allowed-registries regex configured shows as unhealthy because the policy has nothing to enforce against.
Why does "Container images should be deployed from trusted registries only" matter?
If any registry is permitted, one compromised CI pipeline, a mistyped public image, or a developer pulling 'latest' from Docker Hub can put unreviewed code straight into your cluster, where it inherits the namespace's service-account tokens and network reach. Public registries also rotate and delete tags outside your control, so a deployment that worked yesterday can silently pull a different, poisoned image today. Constraining pods to your own trusted registries means images pass through your build, scanning and approval path before they can run, which is the difference between a contained incident and an attacker executing arbitrary workloads inside your trust boundary.
How do I fix "Container images should be deployed from trusted registries only"?
- Decide the trusted set and write the regex, for example '^.+azurecr.io/.+$' to allow only Azure Container Registry, or '^(myteam\.azurecr\.io|mcr\.microsoft\.com)/.+$' to allow your registry plus Microsoft Container Registry.
- Enable the Azure Policy add-on on the cluster with 'az aks enable-addons --addons azure-policy --name <cluster> --resource-group <rg>', then look up the built-in policy by its exact display name and assign it scoped to the cluster: pid=$(az policy definition list --query "[?displayName=='Container images should only be deployed from trusted registries (Preview)' || displayName=='Kubernetes cluster containers should only use allowed images'].name" -o tsv); az policy assignment create --name aks-trusted-registries --policy "$pid" --scope <cluster-resource-id> --params '{"allowedContainerImagesRegex":{"value":"^.+azurecr.io/.+$"}}'.
- Bake the assignment into your landing-zone Bicep or Terraform so new clusters inherit it, and run the policy in audit ('Audit') effect first to surface existing non-compliant images before switching the effect to 'Deny', which blocks non-matching pods at admission.
Remediation script · bash
# 1. Turn on the Azure Policy add-on so Gatekeeper starts auditing the cluster.
az provider register --namespace Microsoft.PolicyInsights
az aks enable-addons --addons azure-policy \
--resource-group rg-prod --name aks-prod
# Confirm the policy and gatekeeper pods are running.
kubectl get pods -n kube-system -l app=azure-policy
kubectl get pods -n gatekeeper-system
# 2. Assign the built-in pod security baseline initiative in AUDIT first.
# Look the initiative up by its exact display name, never paste a GUID.
SCOPE=$(az aks show -g rg-prod -n aks-prod --query id -o tsv)
SETID=$(az policy set-definition list \
--query "[?displayName=='Kubernetes cluster pod security baseline standards for Linux-based workloads'].name" -o tsv)
az policy assignment create \
--name aks-pod-baseline \
--policy-set-definition "$SETID" \
--scope "$SCOPE" \
--params '{"effect":{"value":"audit"},"excludedNamespaces":{"value":["kube-system","gatekeeper-system","azure-arc"]}}'
# 3. Fix the workloads (in each pod spec, securityContext):
# privileged: false | runAsNonRoot: true | runAsUser: 1000
# allowPrivilegeEscalation: false | readOnlyRootFilesystem: true
# capabilities: { drop: ["ALL"] } and add back only what is needed.
# 4. Once audit is clean except for named exceptions, ENFORCE.
az policy assignment update --name aks-pod-baseline \
--set parameters.effect.value=deny Full walkthrough (console steps, edge cases and verification) in the lesson Enforce AKS pod security.
Is "Container images should be deployed from trusted registries only" a false positive?
A cluster that deliberately runs 'mcr.microsoft.com' system images, such as the AKS-managed kube-system components, will appear to violate a regex that only allows your private ACR. This is a legitimate exception: widen the allowed-registries regex to include 'mcr.microsoft.com' rather than disabling the policy, or scope the assignment to exclude the kube-system namespace so platform images are not forced through your private registry.
More Azure Kubernetes Service controls
- Azure Kubernetes Service clusters should have Defender profile enabled
- Azure Kubernetes Service clusters should have the Azure Policy add-on for Kubernetes installed
- Azure running container images should have vulnerabilities resolved (powered by Microsoft Defender Vulnerability Management)
- Container CPU and memory limits should be enforced
- Container with privilege escalation should be avoided
- Containers sharing sensitive host namespaces should be avoided
- Diagnostic logs in Kubernetes services should be enabled
- Immutable (read-only) root filesystem should be enforced for containers
- Kubernetes API server should be configured with restricted access
- Kubernetes clusters should be accessible only over HTTPS
- Kubernetes clusters should disable automounting API credentials
- Kubernetes clusters should not use the default namespace