2. Core Concepts
Everything in this page is a noun you will meet in the portal, in az acr output, or in an error
message. Each one gets an analogy first, then the precise definition.
The resource and what's inside it
Registry — the building; one address on the street.
A regional ARM resource of type Microsoft.ContainerRegistry/registries, with a globally unique
name of 5–50 alphanumeric characters (no hyphens — unusual for Azure, and a frequent surprise). The
name becomes the DNS login server <name>.azurecr.io, in a namespace shared by all of Azure,
so it collides across tenants. The registry owns the SKU, the network rules, the identity
configuration, the policies, and the bill. It is the only ARM resource in the picture: everything
below is data, not infrastructure. Scoped to a resource group like any other resource — see
the scope hierarchy.
Repository — a folder in the building, with no lock of its own.
A slash-delimited path inside the registry: myregistry.azurecr.io/team-a/api. It is created
implicitly by the first push and destroyed by deleting its last manifest. Critically, it is not an
ARM resource. There is no resource ID for it, no tags on it, and — the consequence that catches
everyone — no Azure RBAC scope at the repository level. AcrPull on the registry is AcrPull
on all of it.
Tag — a sticky label on a shelf.
A mutable, human-readable pointer from a name to a manifest digest: api:v1.2, api:latest. Two
pushes with the same tag leave the second one winning and the first one untagged but still
stored (and still billed). Tags can be made immutable per-registry via the tag-immutability
policy, or per-repository ⚠️ verify current scope of the policy in Azure docs.
Manifest — the packing list.
A small JSON document (per the OCI Image Manifest spec) naming the config blob and the ordered
list of layer blobs that make up one image for one platform, each by digest and size. The
manifest itself has a digest — sha256:… — and that digest is the immutable identity of the
image. A manifest list (OCI "image index") is a manifest of manifests: one digest that resolves
to a different image per CPU architecture and OS, which is how linux/amd64 and linux/arm64
share the tag v1.2.
Digest — the fingerprint.
The SHA-256 of the content. myregistry.azurecr.io/api@sha256:9f86d0… addresses exactly one thing
forever. Deploy by digest; debug by tag. Nearly every "but it worked yesterday" registry
incident is a tag being trusted as if it were a digest.
Layer — one diff of a filesystem, shared by everyone who used the same base. A gzipped tarball blob, stored once per registry regardless of how many manifests reference it. This is why pushing your tenth image built on the same base costs almost nothing extra, and why "my image is 800 MB" and "my push transferred 12 MB" are both true.
OCI artifact — anything else that agreed to be shaped like an image. Because the manifest format allows arbitrary media types, ACR stores more than containers: Helm 3 charts, SBOMs, Notation signatures, WASM modules, and arbitrary blobs pushed with the ORAS CLI. They live in repositories, carry tags and digests, and are billed identically.
[Image Prompt: 2D minimalistic labelled hierarchy diagram of Azure Container Registry showing a registry resource containing repositories, each repository containing tags that point to manifests, and manifests referencing shared deduplicated layer blobs, flat design, clean vector art style, white background]
| Term | Analogy | Technical definition |
|---|---|---|
| Registry | The building, with one street address | Regional ARM resource Microsoft.ContainerRegistry/registries; globally unique alphanumeric name; owns SKU, network rules, policies, and quotas |
| Repository | A folder inside it, with no lock of its own | A path string namespacing manifests within a registry; not an ARM resource, so not an RBAC scope |
| Tag | A sticky label you can move | A mutable pointer from a name to a manifest digest; the previous target becomes an untagged manifest |
| Manifest | The packing list | OCI JSON listing the config blob and ordered layer blobs for one platform; its SHA-256 is the image's true identity |
| Manifest list / index | A packing list of packing lists | One digest resolving to per-architecture manifests, so one tag serves amd64 and arm64 |
| Digest | The fingerprint | sha256:… content address; immutable and unforgeable |
| Layer | One filesystem diff, shared | Compressed tarball blob, deduplicated registry-wide by digest |
| Login server | The DNS name on the door | <name>.azurecr.io; the data-plane endpoint every client talks to |
The SKU axis — this is the whole design decision
Azure services are defined by their tier more than by anything else, and ACR is a clean example: the tiers are not "the same thing, faster." They are different feature sets.
| Basic | Standard | Premium | |
|---|---|---|---|
| Included storage | ~10 GiB ⚠️ verify | ~100 GiB ⚠️ verify | ~500 GiB ⚠️ verify |
| Relative throughput (read/write ops per minute, bandwidth) | Lowest | Middle | Highest ⚠️ verify current figures |
| Webhooks | Few (~2) | More (~10) | Many (~500) ⚠️ verify |
| Geo-replication | — | — | ✅ |
| Private endpoints / Private Link | — | — | ✅ |
| Public network access disable | — | — | ✅ (follows from private endpoints) |
| Customer-managed keys (CMK) | — | — | ✅ |
| Zone redundancy | — | — | ✅ |
| Scope maps & tokens (repository-scoped access) | — | — | ✅ |
| Connected registry (on-prem / edge) | — | — | ✅ |
| Dedicated data endpoints | — | — | ✅ |
| Anonymous pull | — | ✅ | ✅ |
| Repository-scoped retention of untagged manifests | — | — | ✅ ⚠️ verify |
| ACR Tasks | ✅ | ✅ | ✅ (higher concurrency) |
Read the table as one sentence: the interesting features are all Premium, and most of them are networking or governance features. Basic and Standard differ mainly in size and speed; Standard and Premium differ in what is possible.
Which one is the trap? Basic — not because it's bad, but because it is the tier you pick for a
proof of concept and then inherit in production, and the day a security baseline says "no public
network access," Basic cannot comply. Tier changes are online, non-destructive, and take
seconds (az acr update --sku Premium), which is the mitigation; what doesn't change cheaply is
the network architecture you designed around a public endpoint.
Where the money goes: a fixed daily rate per tier — charged whether or not anything pulls — plus per-GiB/day above the included allowance, plus egress out of the region, plus a full additional daily rate for each geo-replica region, plus ACR Tasks compute beyond a free monthly allowance ⚠️ verify all figures against current Azure pricing.
Identity and authentication vocabulary
Microsoft Entra ID identity — the default and correct answer. A user, service principal, or managed identity authenticates to Entra, then exchanges that token for a registry-specific token. No password anywhere. See Architecture for the exchange.
Data-plane roles — Azure RBAC roles that grant registry content permissions:
| Role | What it grants |
|---|---|
AcrPull |
Pull manifests and blobs. The role you assign to AKS, Container Apps, App Service, and anything that runs an image |
AcrPush |
Pull and push. The role for build pipelines |
AcrDelete |
Delete repositories, manifests, and tags |
AcrImageSigner |
Sign images (content-trust era; check current guidance for Notation-based signing ⚠️) |
AcrQuarantineReader / AcrQuarantineWriter |
Read/manage quarantined images where the quarantine policy is enabled ⚠️ verify current preview status |
Control-plane roles — Owner, Contributor, Reader, and the built-in AcrPull-adjacent
composites. Reader on the registry lets you see it in the portal and cannot pull an image.
This is the most common confusion in the whole topic.
Admin user — the master key taped under the doormat. A single built-in account with two
rotatable passwords, disabled by default, whose username is the registry name. It is a shared
secret with full push/pull, it cannot be attributed to a person in logs, and anyone with
Contributor can read it with az acr credential show. Disable it and enforce that with Azure
Policy. It exists for tools that genuinely cannot do Entra auth; that list is now very short.
Token + scope map (Premium) — a numbered key that opens three doors. A scope map is a
named list of repository-level actions (repositories/team-a/api/content/read); a token is a
credential bound to one scope map, with up to two passwords and an expiry. This is the only
repository-granular access control ACR has. It is a password, not an identity: no Conditional
Access, no managed identity, weaker audit trail. Use it for narrow cases (a partner, an appliance,
an air-gapped puller), not as your general access model.
Repository-scoped anonymous pull — Standard and Premium; turns the whole registry's read path public. There is no per-repository anonymous setting.
Features that are nouns you'll meet
Replication (.../registries/replications, Premium) — a regional copy of the registry's
content behind the same login server. You push to the home region; ACR syncs to replicas
asynchronously, and Traffic Manager routes each client to the nearest healthy one. Consequence
worth remembering: a pull immediately after a push in another region may miss, because
replication is eventual. Architecture covers the window.
ACR Task (.../registries/tasks) — a managed build. Three flavours:
- Quick task —
az acr build, a one-off build in Azure with no local Docker daemon. - Triggered task — rebuild on a source commit, on a schedule, or — the genuinely valuable one — on a base image update, so your image is rebuilt automatically when the base it depends on is patched.
- Multi-step task — a YAML file chaining build, test, push, and arbitrary container steps.
Cache rule (.../registries/cacheRules) + credential set — pull-through caching from an
upstream registry (Docker Hub, MCR, ghcr.io, Quay). You pull myregistry.azurecr.io/dockerhub/nginx
and ACR fetches and caches from upstream on first request. This is the clean answer to Docker Hub
rate limits ⚠️ verify which tiers support cache rules against current Azure docs.
Connected registry (Premium) — a synchronised, nested ACR deployed on-premises or at the edge (commonly on IoT Edge or Arc-enabled Kubernetes), for sites with poor or no connectivity.
Webhook (.../registries/webhooks) — an HTTP POST on push, delete, or chart events. Regional in
a geo-replicated registry, so you can wire per-region reactions.
Policies on the registry — the ones worth knowing by name:
- Tag immutability —
v1.2can never be repointed. Turn this on. - Retention (untagged manifests) — auto-delete manifests that no tag points at after N days ⚠️ verify tier availability. Without it, a busy CI pipeline grows storage forever.
- Soft delete — deleted artifacts recoverable for a retention window ⚠️ verify current preview/GA status.
- Quarantine — newly pushed images are unpullable until a scanner marks them clean ⚠️ verify current preview status.
- Export policy — block
az acr import/export out of the registry, for data-exfiltration control on a locked-down Premium registry.
Dedicated data endpoint (Premium) — by default the data (layer blobs) is served from shared
Azure storage endpoints, which means a client-side firewall allow-list can't be written precisely.
Enabling dedicated data endpoints gives you <registry>.<region>.data.azurecr.io per region, which
is allow-listable. If someone hands you a strict egress firewall, this is the setting they need.
The vocabulary traps
- "Repository" vs. "registry" — people say "push to the repo" meaning the registry. In ACR they are different in a way that matters for RBAC.
latestis not special. It's a tag like any other; nothing auto-updates it except your push.- Image size vs. transferred size. A pull only transfers layers the host doesn't already have.
az acr loginis notdocker login. It performs the Entra exchange and then writes Docker credentials for you. Without a Docker daemon, useaz acr login --expose-token.- Registry names take no hyphens.
my-registryis invalid;myregistryis not. This breaks most organisations' naming conventions and is worth deciding once. - ACR ≠ ACI. Registry, not runtime.
Next: Architecture →
← Back to the Azure Container Registry overview · ← Previous: What & Why