Skip to content

Azure Container Registry

The Azure Container Registry (ACR) generator creates a short-lived refresh or access token for accessing ACR. The token is generated for a particular ACR registry defined in spec.registry.

Output Keys and Values

Key Description
username username for the docker login command
password password for the docker login command

Authentication

You must choose one out of three authentication mechanisms:

  • service principal
  • managed identity
  • workload identity

The generated token will inherit the permissions from the assigned policy. I.e. when you assign a read-only policy all generated tokens will be read-only. You must assign a Azure RBAC role, such as AcrPush or AcrPull to the service principal or managed identity in order to be able to authenticate with the Azure container registry API.

You can also use a kubelet managed identity with the default AcrPull role to authenticate to the integrated Azure Container Registry.

You can scope tokens to a particular repository using spec.scope.

Scope

First, an Azure Active Directory access token is obtained with the desired authentication method. This AAD access token will be used to authenticate against ACR to issue a refresh token or access token. If spec.scope if it is defined it obtains an ACR access token. If spec.scope is missing it obtains an ACR refresh token:

  • access tokens are scoped to a specific repository or action (pull,push)
  • refresh tokens can are scoped to whatever policy is attached to the identity that creates the acr refresh token

The Scope grammar is defined in the Docker Registry spec. Note: You can not use wildcards in the scope parameter -- you can match exactly one repository and can define multiple actions like pull or push.

Example scopes:

repository:my-repository:pull,push
repository:my-repository:pull

Example Manifest

apiVersion: generators.external-secrets.io/v1alpha1
kind: ACRAccessToken
metadata:
  name: my-azurecr
spec:
  tenantId: 11111111-2222-3333-4444-111111111111
  registry: example.azurecr.io

  # optional; scope token down to a single repository/action
  # if set, it will generate an access token instead of an refresh token.
  scope: "repository:foo:pull,push"

  # Specify Azure cloud type, defaults to PublicCloud.
  # This is used for authenticating with Azure Active Directory.
  # available options: PublicCloud, USGovernmentCloud, ChinaCloud, GermanCloud
  environmentType: "PublicCloud"

  # choose one authentication method
  auth:

    # option 1: point to a secret that contains a client-id and client-secret
    servicePrincipal:
      secretRef:
        clientSecret:
          name: az-secret
          key: clientsecret
        clientId:
          name: az-secret
          key: clientid

    # option 2: use a managed identity Client ID
    managedIdentity:
      identityId: 11111111-2222-3333-4444-111111111111

    # option 3:
    workloadIdentity:
      # note: you can reference service accounts across namespaces.
      serviceAccountRef:
        name: "my-service-account"
        audiences: []

Example ExternalSecret that references the ACR generator:

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: azurecr-credentials
spec:
  dataFrom:
    - sourceRef:
        generatorRef:
          apiVersion: generators.external-secrets.io/v1alpha1
          kind: ACRAccessToken
          name: my-azurecr
  refreshInterval: 3h
  target:
    name: azurecr-credentials
    template:
      type: kubernetes.io/dockerconfigjson
      data:
        .dockerconfigjson: |
          {
            "auths": {
              "myregistry.azurecr.io": {
                "username": "{{ .username }}",
                "password": "{{ .password }}"
              }
            }
          }

Example using AKS kubelet managed identity to create Argo CD helm chart repository secret:

apiVersion: generators.external-secrets.io/v1alpha1
kind: ACRAccessToken
metadata:
  name: azurecr
spec:
  tenantId: 11111111-2222-3333-4444-111111111111
  registry: example.azurecr.io
  auth:
    managedIdentity:
      identityId: 11111111-2222-3333-4444-111111111111
---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: azurecr-credentials
spec:
  dataFrom:
    - sourceRef:
        generatorRef:
          apiVersion: generators.external-secrets.io/v1alpha1
          kind: ACRAccessToken
          name: azurecr
  refreshInterval: 3h
  target:
    name: azurecr-credentials
    template:
      metadata:
        labels:
          argocd.argoproj.io/secret-type: repository
      data:
        name: "example.azurecr.io"
        url: "example.azurecr.io"
        username: "{{ .username }}"
        password: "{{ .password }}"
        enableOCI: "true"
        type: "helm"