Azure Workload identity federation with Azure DevOps
Overview
About 2 months ago I wrote a blog post about workload identity federation with GitHub Actions. When an application needs to access cloud based resources it often needs to think about authentication and authorization. Using workload identity federation there is no need to use any keys or secrets. For example, Google Cloud Platform and Microsoft Azure are providing this great feature. And now this feature has also been released for Azure DevOps! This means that organizations can now take advantage of this to provide an even more secure way to connect to Azure from Azure DevOps, or rather Azure Pipelines, via a Service Connection.
In my scenario the workload identity federation works as follows: Azure Pipelines requests a token from the external identity provider (Azure DevOps), the external IdP issues a token to the external workload, for example Azure CLI to access the Azure Key Vault. The external workload sends the token to Microsoft identity platform to request an access token. Microsoft will perform a check of the trust relationship on the App Registration and validates the external token against the OpenID Connect (OIDC) issuer URL on Azure DevOps. If the checks succeeds, Microsoft identity platform will issue an access token to the external workload, in this case Azure CLI.
I actually got started right away and set up a short demo to show how you can use this feature.
In my demo I show the following:
- Create a new App Registration (Service Principal) in Microsoft Entra ID (the successor to Azure AD)
- Create a new Service Connection in Azure DevOps project with Workload identity capability
- Create federated identity credentials for the Service Princpal, establishing a trusted relationship between Azure DevOps and Azure
- Create a new Azure KeyVault and grant rights to the Service Principal as Key Vault Reader to view secrets
- A demo pipeline in Azure Pipelines that uses the new Service Connection with Workload identity federation
Please note that the Azure DevOps Service Connection with workload identity federation can be configured automatically or manually. I'll show how this works manually to understand what is happening behind the scenes.
Prerequisites
You must have an Azure subscription. You can create a free account if you don't have one.
An Azure DevOps organization. If your team already has one, then make sure you're an administrator of the Azure DevOps project that you want to use.
App Registration in Azure
To list or access secrets in Azure Key Vault an App Registration is required. By registering an application in Azure a trust relationship is created between the application and the Microsoft identity platform. This application will be consumed by the Service Connection in Azure DevOps (later on) and added as Key Vault Reader to the Azure Key Vault to have sufficient permissions to list secrets.
Create App Registration
For the purpose of this demo I will create a new App Registration in the Azure portal. If you have an existing registration you wish to use you can skip this step and continue to the next one. If not, continue reading. In Azure cloud go to Microsoft Entra ID and create an app registration. Click on the button New registration. Give the new registration a name and you can keep the default settings. At the end of the page click Register.
Add role assignment
Now the App Registration needs permission to list secrets in the Azure Key Vault. If you don't have an Azure Key Vault yet you can create one with the quickstart tutorial of Microsoft. In the Azure portal search for key vault or the name of your key vault and go to Access control (IAM) and click Add -> Add role assignment. To add role assignments, you must have Microsoft.Authorization/roleAssignments/write permission. If you're Owner of the resource this should be good enough.
Select the Key Vault Reader
as role assignment and click Next.
Assign access to Service Princpal (the App Registration) and click Members. Search for the name of the Service Princpal and hit the Select button. Now click on Review + assign. The Service Principal does now have permission to list secrets in the Key Vault.
Azure DevOps Service Connection with workload identity federation
I will now create a new Service Connection in Azure DevOps. The Service Connection settings can be found in the Azure DevOps Project Settings -> Pipelines -> Service connections. E.g.: https://dev.azure.com/{yourOrganization}/{yourProject}/_settings/adminservices
. Just replace the organization and project with the correct values.
Click on the New service connection button -> Azure Resource Manager -> Workload Identity federation (manual). Fill in the name and give this service connection permission to all pipelines. Click Next.
In Step 2 the Service Principal Details are shown. These details should be added to the App Registration (Service Principal) in Azure. You can keep this window open and open an extra tab in the browser so you can copy paste the values in Azure.
If you scroll down in the Step 2 window in Azure DevOps some input is required:
Property | Description |
---|---|
Subscription Id | The subscription where the Azure Key Vault resides. Can be found on the Overview page of the Key Vault in Azure |
Subscription Name | The subscription where the Azure Key Vault resides. Can be found on the Overview page of the Key Vault in Azure |
Service Principal Id | The Application (client) id of the App Registration in Microsoft Entra ID. Can be found on the Overview page of the registration |
Tenant ID | This is a Microsoft Entra ID entity. Can be found on the Overview page of the App Registration or Microsoft Entra ID |
Federated credentials
A trust relationship should now be created between the external IdP (Azure DevOps) and the app registration in Azure. For that, federated credentials can be used. In Azure I will create these credentials. Under Federated credential scenario choose Other issuer. Copy paste the details from the opened window in Azure DevOps in Azure. Give the credential a logical name and click the Add button.
Azure Pipelines
In Azure DevOps create a new YAML pipeline.
- Go to Pipelines, and then select New pipeline.
- Do the steps of the wizard by first selecting Azure Repos Git as the location of your source code.
- Select the desired repository and click Starter pipeline
- Replace everything with the YAML snippet below. Also replace {yourKeyVault} with the correct value
- When you're ready, select Save and run
1trigger:
2- main
3
4pool:
5 vmImage: ubuntu-latest
6
7steps:
8- script: |
9 echo "Workload identity demo pipeline"
10 displayName: 'Run a script task'
11
12- task: AzureCLI@2
13 displayName: List secrets demo
14 inputs:
15 azureSubscription: 'test-automatic'
16 scriptType: 'pscore'
17 scriptLocation: 'inlineScript'
18 inlineScript: 'az keyvault secret list --id https://{yourKeyVault}.vault.azure.net/'
Result: