Azure Container Registry authentication with service principals

You can use an Azure Active Directory (Azure AD) service principal to provide container image docker push and pull access to your container registry. By using a service principal, you can provide access to "headless" services and applications.

What is a service principal?

Azure AD service principals provide access to Azure resources within your subscription. You can think of a service principal as a user identity for a service, where "service" is any application, service, or platform that needs access to the resources. You can configure a service principal with access rights scoped only to those resources you specify. Then, configure your application or service to use the service principal's credentials to access those resources.

In the context of Azure Container Registry, you can create an Azure AD service principal with pull, push and pull, or other permissions to your private registry in Azure. For a complete list, see Azure Container Registry roles and permissions.

Why use a service principal?

By using an Azure AD service principal, you can provide scoped access to your private container registry. You can create different service principals for each of your applications or services, each with tailored access rights to your registry. And, because you can avoid sharing credentials between services and applications, you can rotate credentials or revoke access for only the service principal (and thus the application) you choose.

For example, your web application can use a service principal that provides it with image pull access only, while your build system can use a service principal that provides it with both push and pull access. If development of your application changes hands, you can rotate its service principle credentials without affecting the build system.

When to use a service principal

You should use a service principal to provide registry access in headless scenarios. That is, any application, service, or script that must push or pull container images in an automated or otherwise unattended manner.

For individual access to a registry, such as when you manually pull a container image to your development workstation, you should instead use your own Azure AD identity for registry access (for example, with az acr login).

Create a service principal

To create a service principal with access to your container registry, run the following script in the Azure Cloud Shell or a local installation of the Azure CLI. The script is formatted for the Bash shell.

Before running the script, update the ACR_NAME variable with the name of your container registry. The SERVICE_PRINCIPAL_NAME value must be unique within your Azure Active Directory tenant. If you receive an "'http://acr-service-principal' already exists." error, specify a different name for the service principal.

You can optionally modify the --role value in the az ad sp create-for-rbac command if you want to grant different permissions. For a complete list of roles, see ACR roles and permissions.

After you run the script, take note of the service principal's ID and password. Once you have its credentials, you can configure your applications and services to authenticate to your container registry as the service principal.

#!/bin/bash

# Modify for your environment.
# ACR_NAME: The name of your Azure Container Registry
# SERVICE_PRINCIPAL_NAME: Must be unique within your AD tenant
ACR_NAME=<container-registry-name>
SERVICE_PRINCIPAL_NAME=acr-service-principal

# Obtain the full registry ID for subsequent command args
ACR_REGISTRY_ID=$(az acr show --name $ACR_NAME --query id --output tsv)

# Create the service principal with rights scoped to the registry.
# Default permissions are for docker pull access. Modify the '--role'
# argument value as desired:
# acrpull:     pull only
# acrpush:     push and pull
# owner:       push, pull, and assign roles
SP_PASSWD=$(az ad sp create-for-rbac --name http://$SERVICE_PRINCIPAL_NAME --scopes $ACR_REGISTRY_ID --role acrpull --query password --output tsv)
SP_APP_ID=$(az ad sp show --id http://$SERVICE_PRINCIPAL_NAME --query appId --output tsv)

# Output the service principal's credentials; use these in your services and
# applications to authenticate to the container registry.
echo "Service principal ID: $SP_APP_ID"
echo "Service principal password: $SP_PASSWD"

Use an existing service principal

To grant registry access to an existing service principal, you must assign a new role to the service principal. As with creating a new service principal, you can grant pull, push and pull, and owner access, among others.

The following script uses the az role assignment create command to grant pull permissions to a service principal you specify in the SERVICE_PRINCIPAL_ID variable. Adjust the --role value if you'd like to grant a different level of access.

#!/bin/bash

# Modify for your environment. The ACR_NAME is the name of your Azure Container
# Registry, and the SERVICE_PRINCIPAL_ID is the service principal's 'appId' or
# one of its 'servicePrincipalNames' values.
ACR_NAME=mycontainerregistry
SERVICE_PRINCIPAL_ID=<service-principal-ID>

# Populate value required for subsequent command args
ACR_REGISTRY_ID=$(az acr show --name $ACR_NAME --query id --output tsv)

# Assign the desired role to the service principal. Modify the '--role' argument
# value as desired:
# acrpull:     pull only
# acrpush:     push and pull
# owner:       push, pull, and assign roles
az role assignment create --assignee $SERVICE_PRINCIPAL_ID --scope $ACR_REGISTRY_ID --role acrpull

Sample scripts

You can find the preceding sample scripts for Azure CLI on GitHub, as well versions for Azure PowerShell:

Next steps

Once you have a service principal that you've granted access to your container registry, you can use its credentials in your applications and services for headless registry interaction. You can use service principal credentials from any Azure service that can authenticate with an Azure container registry. Examples include: