Skip to main content
emnode
Compliance

Harden Azure Container Registry

One capability across the registries that hold your images: make sure no registry is reachable from the public internet by default, that the images it stores are pulled over a private path, and that regulated workloads can prove their layers are encrypted under a key you control.

14 min·10 sections·AZURE

Last reviewed

Hardening container registries: the basics

What does an exposed Azure Container Registry actually look like?

An Azure Container Registry is the supply-chain root of everything you run: every image your AKS clusters, Container Apps and Container Instances pull starts life here. Exposure shows up in a few distinct shapes rather than one setting. The registry can accept connections over its public endpoint from any network on the internet, so anyone with a credential, or a leaked one, can reach it from anywhere. It can lack a private endpoint, so even your own workloads pull images across the public internet rather than over the Azure backbone. And its image layers can rest under the platform-managed key when a regulated workload needs a customer-managed key it can rotate and revoke. Each is its own Defender for Cloud recommendation, but the underlying risk is the same: the place your trusted images live is reachable, or pullable, more widely than you meant.

Microsoft Defender for Cloud turns each of these into its own recommendation, which is why one registry can fail several container checks at once. 'Container registries should not allow unrestricted network access' and 'Container registries should use private link' close the network doors, and 'Container registries should be encrypted with a customer-managed key' covers encryption at rest for the regulated case. They read as separate problems on the report, but they are one job: make the registry reachable only from your network, pull over a private path, and, where the data class demands it, hold the keys yourself.

Most of this exposure is the default rather than a decision. A new registry accepts public network traffic out of the box, a Basic or Standard SKU was chosen so private link and firewall rules were never an option, a Premium registry was created without a private endpoint because the quickstart did not mention one. The work is to find every registry that is reachable from the public internet, move it to Premium where network controls live, route pulls through a private endpoint, and reserve customer-managed keys for the workloads whose compliance class genuinely requires them.

In this lesson you will learn how Azure Container Registry expresses public reachability, private connectivity and encryption at rest, how to find every over-exposed registry in a subscription, and how to lock them down without breaking the pulls your clusters and pipelines depend on. The Controls this lesson covers section lists every Defender for Cloud recommendation in this capability, each linking to a deep page with the exact check and a copy-and-paste fix.

Fun fact

The registry is the keys to the kingdom

Researchers have repeatedly shown that a single over-permissioned or internet-reachable container registry is one of the highest-value targets in a cloud estate: push access to it means push access to what every downstream cluster runs. Public scans regularly turn up registries reachable over their public endpoint, and a leaked pull or push credential against an open registry is far more dangerous than the same credential against one that only answers inside a virtual network. Azure leaves the public endpoint enabled on a new registry by default and only offers firewall rules and private link on the Premium tier, so a registry that is both open and on a lower SKU has no network defence at all until someone changes both.

Finding registry exposure across a subscription

Sam is the security lead at a scale-up preparing for its first ISO 27001 audit. Defender for Cloud shows container-registry findings on several registries across two subscriptions, all created from the portal quickstart with default networking.

Rather than work the findings one by one, Sam starts by listing which registries still accept public network traffic and which SKU they are on, because the SKU decides whether private link is even available before anything can be locked down.

Start by listing every registry with its SKU and public-network setting. The Premium registries can be locked down in place; the others need an upgrade first.

$ az acr list --query "[].{name:name, sku:sku.name, publicNet:publicNetworkAccess}" -o table
Name Sku PublicNet
---------------- -------- ----------
prodimagesacr Premium Enabled
sandboxacr Basic Enabled
# prodimagesacr is Premium and public: lock it down in place with a private endpoint.
# sandboxacr is Basic: firewall and private link need a Premium upgrade first.

A Premium registry that still accepts public traffic is the highest-value target: it can be closed in place. A Basic or Standard registry has to be upgraded to Premium before any network control applies.

How Defender for Cloud decides a registry is exposeddeep dive

Most registry recommendations resolve to one of three properties. The first is 'publicNetworkAccess' together with the network rule set's default action: when public access is Enabled and the default action is Allow, the registry answers over its public endpoint from any network, so anyone with a credential can reach it from anywhere. The second is whether the registry has an approved private endpoint connection: with no private endpoint, even your own workloads resolve and pull the registry over the public internet rather than over the Azure backbone, which is what 'Container registries should use private link' checks for. The third is the encryption block: by default image layers rest under a Microsoft-managed key, and the customer-managed-key recommendation looks for an encryption status of enabled with a Key Vault key you supplied.

Two structural facts shape the remediation. Firewall rules, the ability to disable public access, and private link are all Premium-tier features, so a Basic or Standard registry cannot be network-restricted at all until it is upgraded to Premium. And a customer-managed key can only be set when the registry is created, on a Premium registry, using a user-assigned managed identity granted the Key Vault Crypto Service Encryption User role (or get, wrapKey and unwrapKey key permissions); the key must be an RSA or RSA-HSM key, and once CMK is enabled it cannot be disabled. That means CMK is a create-time decision for a registry, not a switch you flip later.

Defender for Cloud evaluates these against the Microsoft Cloud Security Benchmark on a periodic cycle, so a fix does not flip the recommendation to Healthy instantly: the control-plane change is immediate but the posture catches up on the next assessment. One detail saves an outage: when you disable public access, the 'allow trusted services' setting (on by default) lets Defender for Cloud, ACR Tasks and image import keep reaching the registry, so leave it enabled unless you have a specific reason not to.

What is the impact of leaving a registry exposed?

The direct impact is a compromised supply chain. A registry reachable over the public internet is a target for any leaked or sprayed credential, and push access means an attacker can replace a trusted image with a poisoned one that every downstream cluster then pulls and runs. Unlike a single exposed data store, a tampered registry propagates: the damage runs wherever those images are deployed. Pulls that cross the public internet rather than a private endpoint also widen the surface that has to be defended and complicate proving where your images actually travelled.

The second-order impact is blast radius and provenance. When the source of your images is reachable from anywhere, you cannot cleanly assert which images are trustworthy, and an incident turns into a forensic exercise across every image and every workload that pulled one. Routing pulls through a private endpoint and closing the public door shrinks that to the registries you operate inside your own network, which are the ones you can monitor and reason about.

On the compliance and encryption side, regulated workloads frequently require that data at rest, including container image layers, is encrypted under a key the organisation controls and can revoke. A customer-managed key on the registry is how you evidence that for the workloads whose data class demands it. Across frameworks such as ISO 27001, SOC 2, PCI DSS and the UK and EU data-protection regimes, a passing set of registry recommendations is a cheap and defensible artefact that the supply chain is not open to the internet.

How do you lock a registry down safely?

Work the capability as one loop rather than chasing individual findings. The order matters: confirm the SKU and keep the trusted-services bypass on before you close the public door, so you do not cut off Defender's scanning or your own build pipeline.

1. Inventory every registry by SKU and exposure

List every registry with its SKU and its public-network setting, and note which have a private endpoint. The SKU is the gate: firewall rules, disabling public access and private link are Premium-only, so a Basic or Standard registry has to be upgraded before any network control applies. Treat this inventory as the source of truth, not the Defender finding count, because one registry can trigger several recommendations at once.

2. Prioritise by what each registry feeds

Map each registry to the workloads downstream of it. A registry supplying production images to an internet-facing service is the highest blast radius and earns the Premium upgrade and a private endpoint first. Sandbox and throwaway registries are low value and can often be consolidated away rather than hardened. Spend the bounded budget where the supply chain actually matters.

3. Add a private endpoint, then close the public door

Create a private endpoint into your virtual network so workloads pull over the Azure backbone, then set the network default action to Deny and turn public network access off. Leave 'allow trusted services' enabled so Defender for Cloud can keep scanning images and ACR Tasks and image import keep working. Confirm your clusters and pipelines resolve the registry's private IP before you flip the public switch off.

4. Use customer-managed keys for the regulated registries, and audit the rest with policy

For the registries whose data class requires a key the organisation controls, create the registry as Premium with a user-assigned identity and a customer-managed key (this is a create-time decision and cannot be undone). Then assign Azure Policy to audit for unrestricted network access and private-link use across the estate, so a registry created open in future is flagged rather than missed.

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

Quick quiz

Question 1 of 5

Defender for Cloud shows findings on a registry across unrestricted network access, missing private link and platform-managed encryption. What is the most efficient way to think about them?

You can now treat Azure Container Registry as one capability rather than a scatter of findings: inventory every registry by SKU and exposure, prioritise by what each one feeds, add a private endpoint and close the public door (keeping trusted services on so Defender keeps scanning), reserve customer-managed keys for the regulated registries at create time, and audit the estate with Azure Policy. The Controls this lesson covers section below links every recommendation in this group to its deep page and fix.

Back to the library

Controls this lesson covers

One capability, many Microsoft Defender for Cloud recommendations. This lesson is the shared playbook; each control below keeps its own deep page with the exact check, severity and a copy-and-paste fix.