For the complete documentation index, see llms.txt. This page is also available as Markdown.

AZ_ACR_LIST_CREDENTIALS

Summary

Forestall ACL Alias

AZ_ACR_LIST_CREDENTIALS

Azure Alias

ACR List Credentials / Generate Token Credentials

Affected Object Types

Container Registries (ACR)

Exploitation Certainty

Certain

Severity

High

Azure RBAC Roles

Owner (8e3af657-a8ff-443c-a75c-2fe8c4bcb635), Contributor (b24988ac-6180-42a0-ab88-20f7382dd24c), Container Registry Contributor and Data Access Configuration Administrator (3bc748fc-213d-45c1-8d91-9da5725539b9), Container Registry Configuration Reader and Data Access Configuration Reader (69b07be0-09bf-439a-b9a6-e73de851bd59), Container Registry Connected Registry Administrator (281928aa-9782-4d9a-954a-3f34c1ed9f95)

Custom Role Actions:

  • Microsoft.ContainerRegistry/registries/listCredentials/action

  • Microsoft.ContainerRegistry/registries/generateCredentials/action

  • Microsoft.ContainerRegistry/registries/tokens/write

Description

AZ_ACR_LIST_CREDENTIALS is the risk that an attacker (or insider) with the right Azure resource permissions can retrieve the registry admin username/password or mint scoped tokens with a generated password for an Azure Container Registry. Either path hands the attacker push/pull credentials, i.e. full control over the registry contents - they can plant or replace images that downstream consumers (AKS, App Service, Function Apps, build pipelines) then pull and execute.

Two abuse paths

Permission
What it returns
Consequence

Microsoft.ContainerRegistry/registries/listCredentials/action

Static admin username/password (only when Admin user is enabled on the registry).

Permanent push + pull credential good for the lifetime of the password rotation.

Microsoft.ContainerRegistry/registries/generateCredentials/action + tokens/write

A scoped token + generated password (works even when Admin user is disabled).

Token can be created with _repositories_admin scope = full registry access.

Pre-condition for listCredentials: the registry must have Admin user = Enabled (Access keys blade). If admin is disabled the call fails with 400 Bad Request and a message like "The admin user is disabled for the container registry".

generateCredentials does not require admin user to be enabled - this is the harder-to-mitigate path.

Built-in roles that grant these actions

Beyond the blanket Owner / Contributor roles (which win via wildcard), Azure ships purpose-built ACR roles that hand out the credential actions directly. Any assignment of these at registry, resource-group, or subscription scope is exploitable:

Built-in role

Role ID

Method 1 listCredentials

Method 2 generateCredentials + tokens/write

Owner

8e3af657-a8ff-443c-a75c-2fe8c4bcb635

✅ (via *)

✅ (via *)

Contributor

b24988ac-6180-42a0-ab88-20f7382dd24c

✅ (via * minus auth)

✅ (via * minus auth)

Container Registry Contributor and Data Access Configuration Administrator

3bc748fc-213d-45c1-8d91-9da5725539b9

✅

✅

Container Registry Configuration Reader and Data Access Configuration Reader

69b07be0-09bf-439a-b9a6-e73de851bd59

✅

❌ (has tokens/read only, not tokens/write)

Container Registry Connected Registry Administrator

281928aa-9782-4d9a-954a-3f34c1ed9f95

❌ (no listCredentials/action)

✅ (holds generateCredentials/action, tokens/write, scopeMaps/write)

Related edges: AZ_ACR_PUSH

AZ_EXECUTE_COMMAND (ACR Tasks section)

Identification

PowerShell (Az Module)

Azure CLI

Azure Portal

  1. Open the Azure Portal -> Container registries -> select the registry.

  2. Under Settings -> Access keys, check whether Admin user is Enabled (this enables listCredentials).

  3. Under Settings -> Tokens (Preview) + Repository permissions / Scope maps, list any tokens and the scope maps they reference.

  4. Under Access control (IAM) -> Role assignments, review Owner, Contributor, and any custom role with the actions above.

Exploitation

Replace <RegistryName> and <RGName> with your own values. These examples are for authorized testing only.

Method 1: List admin credentials - listCredentials/action

Returns the static admin username and the two passwords. Works only when Admin user is enabled on the registry.

Azure CLI

PowerShell

REST

The response returns the admin username plus both password values:

listCredentials REST call returning the admin username and password/password2

Use the returned credentials with docker login for full push/pull access:

Logging in with the admin credentials, then pulling a base image and pushing it into a prod/ repository - full push access confirmed:

docker login with admin credentials, then pull, tag, and push an image into prod/myapp:latest

Method 2: Generate a scoped token - generateCredentials/action + tokens/write

Works even when Admin user is disabled. Creates a registry token with a chosen scope map (e.g. _repositories_admin for full access) and returns a fresh password.

Azure CLI

az acr token create output showing rogue-token bound to _repositories_admin with generated password1 and password2

REST

Then docker login with the token name as username and the generated value as password:

Authenticating with the token name as the username and the generated password succeeds:

docker login with -u rogue-token and the generated token password returning Login Succeeded

Downstream impact - supply-chain poisoning

Once authenticated, an attacker can:

  • Replace existing tags that AKS / App Service / Function Apps / pipelines pull on the next deploy.

  • Push a new image under a name that matches an internal naming convention to bait an admin into deploying it.

  • Read every image in the registry to harvest secrets baked into image layers.

This pivots cleanly into AZ_ACR_PUSH / AZ_EXECUTE_COMMAND on whatever workload pulls the poisoned image.

Mitigation

  1. Disable Admin user (Properties blade -> Admin user = Disabled, or az acr update --name <RegistryName> --admin-enabled false). Removes the listCredentials path entirely.

  2. Prefer Microsoft Entra authentication (az acr login) and managed identities for downstream consumers; avoid static docker login with admin credentials.

  3. Restrict registry tokens - if you don't need the Tokens / Scope-map feature, leave it unused. If you do, scope tokens to a single repository (e.g. <repo>:content/read) instead of _repositories_admin.

  4. Limit Owner / Contributor at registry scope - assign AcrPull / AcrPush at fine scope rather than blanket Contributor.

  5. Enable resource locks on production registries to prevent unwanted token / scope-map creation.

  6. Rotate admin passwords on a schedule (az acr credential renew --name <RegistryName> --password-name password) and treat any unexpected rotation event as suspicious.

  7. Forward Activity Log + ACR audit logs to a SIEM and alert on listCredentials / generateCredentials calls.

Detection

Use the Azure Portal:

  1. Open Azure Portal -> target container registry (or scope to subscription / resource group).

  2. Open Activity log.

  3. Filter Operation for credential retrieval activity, such as List Registry Credentials, Generate Registry Credentials, and Create or Update Token.

  4. Review the Event initiated by, Timestamp, Resource, Status, and Change history fields for unexpected callers, brand-new tokens created right before the call, or generateCredentials calls against _repositories_admin scope maps.

  5. On the registry blade, open Tokens (Preview) and review the Created on + Expiration of every token. A token created moments before a credential generation event is a strong indicator.

  6. Cross-reference with Microsoft Entra sign-in logs for the calling principal to identify the source IP and session.

References

Last updated

Was this helpful?