Microsoft Defender for Cloud · Azure Container Registry
Container registries should not allow unrestricted network access
Written and reviewed by Emnode · Last reviewed
What does the recommendation "Container registries should not allow unrestricted network access" check?
Flags any container registry whose data plane is reachable from any network. A registry is non-compliant when 'publicNetworkAccess' is Enabled (or unset) and the firewall is wide open, meaning 'networkRuleSet.defaultAction' is Allow rather than Deny. The control is satisfied once you either turn the public endpoint off entirely or set the default action to Deny and admit only named IP ranges or virtual networks. It checks the registry's network posture only: it does not look at who can authenticate, whether the admin user account is enabled, whether content trust is on, or whether image content has been scanned for vulnerabilities. Those concerns belong to separate recommendations, so a registry can pass this check and still be weak in other respects.
Why does "Container registries should not allow unrestricted network access" matter?
By default a registry accepts pulls and pushes from any host on the internet, so the only thing standing between an attacker and your images is a credential. Registries hold the exact artefacts that run in production, so a stolen token or a leaked service principal becomes a path to pull proprietary code or, worse, push a poisoned image that later runs in your cluster as a trusted workload. Because the endpoint is public, attackers do not need a foothold in your network to begin probing it, and automated scanners catalogue exposed registries continuously. Restricting the network surface means a compromised credential is useless from an unapproved address, which turns a single secret leak from an immediate breach into a contained incident that your monitoring has time to catch.
How do I fix "Container registries should not allow unrestricted network access"?
- Confirm the registry is on the Premium SKU, because firewall rules and private endpoints are not available on Basic or Standard: 'az acr update --name <registry> --sku Premium'.
- Lock the firewall to deny by default, then allow only the addresses you trust: 'az acr update --name <registry> --default-action Deny' followed by 'az acr network-rule add --name <registry> --ip-address <cidr>'. To remove the public endpoint completely in favour of a private endpoint, run 'az acr update --name <registry> --public-network-enabled false'.
- Enforce the posture at scale by assigning the built-in policy. Look up its definition by exact display name rather than hardcoding a GUID: pid=$(az policy definition list --query "[?displayName=='Container registries should not allow unrestricted network access'].name" -o tsv); then 'az policy assignment create --name acr-no-public-net --policy "$pid" --scope <scope>'.
Remediation script · bash
# 1. Lock down an existing Premium registry: add a private endpoint, then close the public door.
RG=platform-rg
ACR=prodimagesacr
VNET=hub-vnet
SUBNET=registry-subnet
# Create the private endpoint into your VNet (registry must be Premium).
ACR_ID=$(az acr show --name "$ACR" --query id -o tsv)
az network private-endpoint create \
--resource-group "$RG" --name "${ACR}-pe" \
--vnet-name "$VNET" --subnet "$SUBNET" \
--private-connection-resource-id "$ACR_ID" \
--group-id registry \
--connection-name "${ACR}-conn"
# Close the public door but keep trusted services (Defender, ACR Tasks, import) reaching it.
az acr update --name "$ACR" \
--default-action Deny \
--public-network-enabled false \
--allow-trusted-services true
# 2. Create a NEW registry encrypted with a customer-managed key (CMK is create-time only).
# Prereqs already in place: user-assigned identity granted 'Key Vault Crypto Service
# Encryption User' on a key vault with soft-delete + purge protection, and an RSA key.
az acr create --resource-group "$RG" --name regulatedacr --sku Premium \
--identity "$identityID" --key-encryption-key "$keyID"
# 3. Ratchet it shut estate-wide: audit any registry that allows unrestricted network access.
pid=$(az policy definition list \
--query "[?displayName=='Container registries should not allow unrestricted network access'].name" -o tsv)
az policy assignment create \
--name audit-acr-network \
--policy "$pid" \
--scope "/subscriptions/00000000-0000-0000-0000-000000000000" Full walkthrough (console steps, edge cases and verification) in the lesson Harden Azure Container Registry.
Is "Container registries should not allow unrestricted network access" a false positive?
A registry that has set 'defaultAction' to Deny but still keeps 'publicNetworkAccess' Enabled so a small list of build-agent IPs can push is a deliberate and valid design, yet some tooling still flags the public endpoint as present. The control is satisfied by the Deny default action, so prioritise reviewing the allowed IP list periodically and keep it minimal rather than reopening the firewall.