How to authenticate to Microsoft Graph from Azure DevOps Pipeline using Workload identity federation

Managed identity for Azure DevOps Pipeline? Yes please 😍


3 min read

With the introduction of the Workload Identity Federation feature (currently in preview but functioning well), we can leverage the identity associated with our Pipeline for authentication with Microsoft Graph and other Azure services, eliminating the need for additional Service Principals.

This means we no longer have to deal with the inconvenience of renewing saved secrets πŸ’—.

To get more details about the Workload Identity Federation check the official documentation.

Create the Workload Identity Federation Service Connection

In your Azure DevOps project: Project settings >> Service connections >> Create service connection >> Azure Resource Manager >> Workload Identity federation (automatic)

Now you need to specify to what resource you will grant this newly created identity permissions to.

For this particular use case, I tend to use Subscription (Resource Group), which means that identity will be granted a Contributor role over the selected Resource Group.

It is a good idea to have a separate subscription with some dummy Resource Group just for this!

The Contributor role can be substituted with a less privileged role, such as Reader. However, it’s important to remember that workload identity must be assigned some role, otherwise all authentication attempts will fail!

Service connection name will be used in the pipeline as an identity identifier later.

Grant required Graph permissions to our identity

Now when the identity is created

We can assign it the required API permissions

As you can see, a new App registration was created in our Azure tenant named as <DevOps Organization>-<DevOps Project>-<GUID>

To grant permissions programmatically, you can use Grant-AzureServicePrincipalPermission (part of the AzureApplicationStuff module)

Authenticate to Microsoft Graph within the Pipeline using the created Workload Identity

Now the last part where we use created workload identity to authenticate against Graph API.

Getting the access token

To get the access token, add following AzurePowerShell@5 step to your pipeline.

- task: AzurePowerShell@5
        displayName: "Get Graph Token for Workload Federated Credential"
          azureSubscription: "workload_identity_for_graph_api"
          azurePowerShellVersion: "LatestVersion"
          ScriptType: "inlineScript"
          Inline: |
            $accessToken = (Get-AzAccessToken -ResourceTypeName MSGraph -ErrorAction Stop).Token
            Write-Host "##vso[task.setvariable variable=accessToken;issecret=true]$accessToken"

Don't forget to change the value of azureSubscription to match your Service connection name created in the previous step!

This task will get the Graph access token and save it to the pipeline variable accessToken for later use.

Using the access token to authenticate

Now that we have the access token, add the following step to your Pipeline

 - task: PowerShell@2
        displayName: "Authenticate"
          targetType: "inline"
          script: |
            Write-Host "Authenticating to Graph API"
            $secureToken = ConvertTo-SecureString -String $(accessToken) -AsPlainText -Force
            Connect-MgGraph -AccessToken $secureToken -NoWelcome

This step converts the string from the accessToken pipeline variable to the secure string required by the Connect-MgGraph command and use it to authenticate.

Happy scripting πŸ˜‰

Did you find this article valuable?

Support Ondrej Sebela by becoming a sponsor. Any amount is appreciated!