Configure workload identity federation in Azure DevOps

When dealing with cloud services, it’s essential to handle authentication in a secure and manageable way. Federation allows you to connect services without needing to deal with credentials like secrets or certificates directly. Here is how you can configure workload identity federation in Azure DevOps service connections. I promise, it’s a huge improvement and easy to configure.

What is workload identity federation?

In Azure DevOps, which is technically not fully integrated in Azure, managed identities could not be used for service connections. The use of a service principal and a secret was required, which obviously isn’t the most secure. Secrets could leak and service principals typically have a lot of permissions on Azure. These secrets need to be kept very safe, and you have to change them often to stay secure. Also, if you forget to update them, your service might stop working when they expire.

Federation for DevOps service connections

Luckily, there’s another way called workload identity federation that helps you when your software is outside of Azure. With this, you set up something like a user-assigned managed identity and configure federation. Microsoft Entra ID then trusts your Azure DevOps organization and issues (access) tokens back to Azure DevOps to authenticate with Azure Resource Manager.

Basically, your service connection sends a request to the DevOps organization. Then, Azure DevOps sends a request for a token to Microsoft Entra ID. Since they both trust each other, a token is given back and lets your service connection use the permissions of the user-assigned managed identity on Azure. By doing this, you don’t have to worry about keeping secrets safe or expiring.

workload identity federation overview
Overview of the federation process referenced from the Microsoft Docs.

Deployment & configuration

Let’s dive right into the configuration of workload identity federation.

Deploy user-assigned managed identity

Requirements for the deployment:

  • Azure subscription: Access to an Azure subscription is a prerequisite to create resources including managed identities.
  • Resource group: A resource group within the Azure subscription to hold the managed identity and related resources.
  • Permissions: Contributor permissions within the Azure subscription to create the managed identity.
  • Azure PowerShell or portal access: Installation of the Azure PowerShell module for command line management, or access to the Azure portal for a GUI interface.

To deploy a user-assigned managed identity, you can follow these steps using the command line:

  1. Login to Azure: Authenticate with Azure PowerShell using Connect-AzAccount.
PowerShell
Connect-AzAccount
  1. Set subscription context: (If needed) Set the correct Azure subscription where the identity will be created using Set-AzContext.
PowerShell
Set-AzContext -Subscription <SubscriptionName>
  1. Create the identity: Use the New-AzUserAssignedIdentity command with the resource group and the desired name for your managed identity.
    • Replace <ResourceGroupName> with the name of your Azure resource group.
    • Replace <IdentityName> with the name you want to assign to the new managed identity.
PowerShell
New-AzUserAssignedIdentity -ResourceGroupName <ResourceGroupName> -Name <IdentityName>
  1. Verify the identity: Ensure that the managed identity has been created successfully and retrieve its details such as the ClientId and Id.
PowerShell
Get-AzUserAssignedIdentity -ResourceGroupName <ResourceGroupName> -Name <IdentityName>

Assign any RBAC permissions in Azure for your service connection. In my example, I use the Contributor role.

PowerShell
$identity = Get-AzUserAssignedIdentity -ResourceGroupName <ResourceGroupName> -Name <IdentityName>

New-AzRoleAssignment -ObjectId $identity.PrincipalId -RoleDefinitionName <RoleDefinitionName>

Configure a new service connection in Azure DevOps

Requirements for the configuration:

  • Azure DevOps organization and project: Access to an Azure DevOps organization and a project is a prerequisite to create a service connection.
  • Permissions: Permissions to access and create service connection within the project.

To configure federation for Azure DevOps, we need to add a new service connection and configure federation properties on the user-assigned managed identity.

  1. Login to Azure DevOps: Authenticate with your user credentials and navigate to the project you wish to configure federation for.
  2. Navigate to project settings: In the portal, navigate to Project settings and click on Service connections.
service connections overview in DevOps project
  1. Create new service connection: When asked to select the type of service connection, choose Azure Resource Manager. Click Next, and now select Workload identity federation (manual).

Warning: Please do not select to automatically configure. This would result in the creation of an Enterprise Application in Microsoft Entra ID. It is currently not possible to automatically select a user-assigned managed identity.

  1. Configure the basics: Give the connection a name and optionally add a description. If required, check the box to grant permissions to all pipelines. Click Next.

Configure federation on the user-assigned managed identity

You are presented with a draft configuration of the connection. The details of the Issuer and Subject identifier are now available. We now configure this information on the user-assigned managed identity.

workload identity federation details in devops

To configure federation for a user-assigned managed identity, you can follow this step using the command line. However, it also possible to use the Azure portal. Simply navigate to the user-assigned managed identity and click on Federation.

PowerShell
New-AzFederatedIdentityCredentials `
    -ResourceGroupName <ResourceGroupName> `
    -IdentityName <IdentityName> `
    -Name <YourConnectionName> `
    -Issuer <IssuerUrl> `
    -Subject <SubjectIdentifier>

Note: The connection name must be within 3 and 120 characters, only contains letters (A-Z, a-z), numbers, hyphens and dashes and must start with a number or letter.

Complete the service connection configuration in Azure DevOps

Now hop back to the Azure DevOps portal and fill in the remaining fields.

  • Subscription Id: The unique ID of the subscription.
  • Subscription Name: Display name of the subscription.
  • Service Principal Id: The Client ID of the user-assigned managed identity.
  • Tenant ID: Tenant ID of the Azure tenant.

Click on Verify and save to complete the configuration of the service connection in Azure DevOps. Now, it automatically validates your connection and report back when the validation succeeds.

overview of the service connection configuration parameters

That’s it

Congratulations! You now have successfully configured your first connection using workload identity federation in Azure DevOps. There is nothing more to it. The usage of service connections doesn’t differ when using service principals but without the hassle of credential management. Great, isn’t it?!

What about Security & Governance?

Yes, I am thinking about it too. When it’s just as simple to configure for you, why wouldn’t it be for someone else? There are no special role assignments needed. As long as you have the permission to create and configure a user-assigned managed identity, you can simply federate with any third-party system that supports OpenID Connect. But no worries, there is (always) a solution.

Stay tuned because I will be posting about the governance of federation for user-assigned managed identities very soon.

Update March 2024: Post about governance of federation for user-assigned managed identities is found here.

Conclusion

By following these steps, you can configure workload identity federation for your Azure DevOps service connections, create a secure and controlled environment that harmonizes with your organization’s compliance standards. No more secrets that force you to find solutions to keep them safe and/or regularly rotated.

Leave a Reply

Your email address will not be published. Required fields are marked *