cloudarchitected

Logging into ACR with Azure credentials in GitHub Actions

The azure/docker-login action requires an admin account to push images to an Azure Container Registry. Enabling such an account is not recommended per the least privilege principle, and it is an additional secret you need to manage.

A better alternative is to use Azure credentials, especially if your workflow is already using the azure/login task. For that, we need to get an ACR token from an AAD token.

name: CI

on:
  pull_request:
    branches: [ main ]

jobs:
  build_and_push:
    runs-on: ubuntu-latest
    env:
      REGISTRY: my_repository_name.azurecr.io
      TAG: my_image_name:${{ github.run_id }}
    steps:
      - uses: actions/checkout@v2
      - name: "Build image"
        run: docker build -t $REGISTRY/$TAG .
      - uses: azure/login@v1
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}
      - name: "Login to ACR"
        run: |
          set -euo pipefail
          # see /2021/09/logging-into-acr-in-github-actions/
          # see https://github.com/Azure/acr/blob/main/docs/AAD-OAuth.md#calling-post-oauth2exchange-to-get-an-acr-refresh-token
          access_token=$(az account get-access-token --query accessToken -o tsv)
          refresh_token=$(curl https://$REGISTRY/oauth2/exchange -v -d "grant_type=access_token&service=$REGISTRY&access_token=$access_token" | jq -r .refresh_token)
          # The null GUID 0000... tells the container registry that this is an ACR refresh token during the login flow
          docker login -u 00000000-0000-0000-0000-000000000000 --password-stdin $REGISTRY <<< "$refresh_token"
      - name: "Push image to ACR"
        run: |
          docker push $REGISTRY/$TAG

Software Engineer at Microsoft, Data & AI, open source fan