{"id":67467,"date":"2023-09-11T00:01:30","date_gmt":"2023-09-11T08:01:30","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/devops\/?p=67467"},"modified":"2023-09-14T08:50:52","modified_gmt":"2023-09-14T16:50:52","slug":"public-preview-of-workload-identity-federation-for-azure-pipelines","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/devops\/public-preview-of-workload-identity-federation-for-azure-pipelines\/","title":{"rendered":"Public preview of Workload identity federation for Azure Pipelines"},"content":{"rendered":"<p>Do you want to stop storing secrets and certificates in Azure service connections? Are you tired rotating these secrets whenever they expire? We are now announcing a public preview of workload identity federation for Azure service connections. <a href=\"https:\/\/learn.microsoft.com\/azure\/active-directory\/workload-identities\/workload-identity-federation\">Workload identity federation<\/a> uses an industry-standard technology, Open ID Connect (OIDC), to simplify the authentication between Azure Pipelines and Azure. Instead of secrets, a federation subject is used to facilitate this authentication.<\/p>\n<h3>How it works<\/h3>\n<p>As part of this feature, the Azure (ARM) service connection has been updated with an additional scheme to support workload identity federation. This allows Pipeline tasks that use the Azure service connection to authenticate using a federation subject (<code>sc:\/\/&lt;org&gt;\/&lt;project&gt;\/&lt;service connection name&gt;<\/code>). The main benefits of using this scheme over existing authentication schemes are as follows:<\/p>\n<ul>\n<li>Simplified management: You do not need to generate, copy, and store secrets from service principals in Azure Entra ID to Azure DevOps anymore. Secrets that are used in other authentication schemes of Azure service connections (e.g., service principal) expire after a certain period (2 years currently). When they expire, pipelines fail. You have to generate a new secret and update the service connection. Switching to workload identity federation eliminates the need to manage these secrets and improves the overall experience of creating and managing service connections. <\/li>\n<li>Improved security: With workload identity federation, the federation subject (<code>sc:\/\/&lt;org&gt;\/&lt;project&gt;\/&lt;service connection name&gt;<\/code>) uniquely identifies what the identity can be used for, which provides a better constraint than a (shared) secret. There is no persistent secret involved in the communication between Azure Pipelines and Azure. As a result, tasks running in pipeline jobs cannot leak or exfiltrate secrets that have access to your production environments. This has often been a concern for our customers. <\/li>\n<\/ul>\n<h3>How can I use it?<\/h3>\n<p>You can take advantage of workload identity federation in two ways:<\/p>\n<ul>\n<li><a href=\"https:\/\/aka.ms\/azdo-rm-workload-identity-conversion\">Convert<\/a> your existing Azure service connections based on secrets to the new scheme. You can perform this conversion one connection at a time. Best of all, you do not have to modify any of the pipelines that use those service connections. They will automatically leverage the new scheme once you complete the conversion.<\/li>\n<li>Use the <a href=\"https:\/\/aka.ms\/azdo-rm-workload-identity\">new workload identity federation scheme<\/a> whenever you create a new Azure service connection. Moving forward, this will be the recommended method.<\/li>\n<\/ul>\n<h4>Converting an existing Azure service connection<\/h4>\n<p>To convert a previously created Azure service connection, select the &#8220;Convert&#8221; action after selecting the connection:<\/p>\n<p><center>\n  <img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2023\/09\/convert-service-connection.png\" width=\"870\" \/>\n<\/center><\/p>\n<p>You can roll back from a conversion to use a secret by clicking the <em>revert<\/em> link on the service connection details page:<\/p>\n<p><center>\n  <img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2023\/09\/revert-service-connection.png\" width=\"292\" \/>\n<\/center><\/p>\n<h4>Create a new Azure service connection<\/h4>\n<p>To create a new Azure service connection using workload identity federation, simply select Workload identity federation (automatic) in the Azure service connection creation experience:<\/p>\n<p><center>\n  <img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2023\/09\/create-service-connection1-1.png\" width=\"459\" \/>\n<\/center><\/p>\n<p><center>\n  <img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2023\/09\/create-service-connection2-1.png\" width=\"457\" \/>\n<\/center><\/p>\n<h4>Create manually with a Managed Identity or Service Principal<\/h4>\n<p>You can also create an Azure service connection using workload identity federation manually with either a Service Principal or Managed Identity. Developers that do not have permission to create App Registrations in Azure Entra ID (AAD) can create Azure service connections with Workload identity federation by <a href=\"https:\/\/learn.microsoft.com\/cli\/azure\/identity\/federated-credential?view=azure-cli-latest\">configuring the federation on a Managed Identity<\/a> instead of a Service Principal. Using a Managed Identity in federation does not require assignment and works across all agent hosting models (Hosted, Self-hosted, Scale set agents). See <a href=\"https:\/\/aka.ms\/azdo-rm-workload-identity-manual\">manual configuration instructions<\/a> for a step by step guide.<\/p>\n<h3>Built-in Pipeline tasks<\/h3>\n<p>Azure Pipelines <a href=\"https:\/\/learn.microsoft.com\/azure\/devops\/pipelines\/tasks\/reference\/?view=azure-pipelines\">built-in tasks<\/a> that target Azure have been updated to take advantage of workload identity federation. This is the complete list: AzureAppServiceManage, AzureAppServiceSettings, AzureCLI, AzureCloudPowerShellDeployment, AzureContainerApps, AzureFunctionAppContainer, AzureFunctionApp, AzureKeyVault, AzureMonitor, AzureMysqlDeployment, AzurePolicy, AzurePowerShell, AzureResourceGroupDeployment, AzureResourceManagerTemplateDeployment, AzureRmWebAppDeployment, AzureSpringCloud, AzureVmssDeployment, AzureWebAppContainer, AzureWebApp, DockerCompose, Docker, HelmDeploy, InvokeRestApi, JavaToolInstaller, JenkinsDownloadArtifacts, Kubernetes.<\/p>\n<h4>Azure CLI task support for inline authentication<\/h4>\n<p>If a tool does not have a task or you prefer to use tools directly inside a script you provide, you can use the <a href=\"https:\/\/learn.microsoft.com\/azure\/devops\/pipelines\/tasks\/reference\/azure-cli-v2?view=azure-pipelines\">AzureCLI@2 task<\/a> task to access the federated token used during authentication. Setting property <code>addSpnToEnvironment: true<\/code> will populate the <code>idToken<\/code>, <code>servicePrincipalId<\/code> and <code>tenantId<\/code> environment variables.<\/p>\n<p>This example shows inline configuration of Terraform azuread\/azurerm providers:<\/p>\n<pre><code class=\"yml\">  - task: AzureCLI@2\n    inputs:\n      addSpnToEnvironment: true\n      azureSubscription: 'my-azure-service-connection'\n      scriptType: bash\n      scriptLocation: inlineScript\n      inlineScript: |\n        # Inherit Azure CLI service connection\n        export ARM_CLIENT_ID=$servicePrincipalId\n        export ARM_OIDC_TOKEN=$idToken\n        export ARM_TENANT_ID=$tenantId\n        export ARM_SUBSCRIPTION_ID=$(az account show --query id -o tsv)\n        export ARM_USE_OIDC=true\n\n        terraform init\n        terraform apply -auto-approve\n<\/code><\/pre>\n<p>The idToken has a lifetime of 10 minutes.<\/p>\n<h3>Custom Azure tasks and extensions<\/h3>\n<p>If you are using a task from the Marketplace or a home-grown custom task to deploy to Azure, then it may not support workload identity federation yet. In these cases, we ask task developers to support workload identity federation to improve security.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2023\/09\/oidc-collaboration-4.png\" alt=\"Image oidc collaboration\" width=\"1250\" height=\"543\" class=\"aligncenter size-full wp-image-67562\" srcset=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2023\/09\/oidc-collaboration-4.png 2500w, https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2023\/09\/oidc-collaboration-4-300x130.png 300w, https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2023\/09\/oidc-collaboration-4-1024x445.png 1024w, https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2023\/09\/oidc-collaboration-4-768x334.png 768w, https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2023\/09\/oidc-collaboration-4-1536x668.png 1536w, https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2023\/09\/oidc-collaboration-4-2048x890.png 2048w\" sizes=\"(max-width: 1250px) 100vw, 1250px\" \/><\/p>\n<p>Tasks that take a <code>connectedService:AzureRM<\/code> input in <a href=\"https:\/\/learn.microsoft.com\/azure\/devops\/extend\/develop\/integrate-build-task?view=azure-devops#custom-build-task-json\">task.json<\/a> can be updated so support workload identity federation with the following steps:<\/p>\n<ul>\n<li>Request an idToken using the new <a href=\"https:\/\/learn.microsoft.com\/rest\/api\/azure\/devops\/distributedtask\/oidctoken\/create?view=azure-devops-rest-7.1\">Oidctoken REST API<\/a> (arrow 1 in above diagram). <\/li>\n<li>Exchange the idToken for an access token using the federated credential flow of the <a href=\"https:\/\/learn.microsoft.com\/azure\/active-directory\/develop\/v2-oauth2-client-creds-grant-flow#third-case-access-token-request-with-a-federated-credential\">OAuth API<\/a>, specifying the idToken as <code>client_assertion<\/code> (arrows 2 &amp; 4 in above diagram);<br \/>\nor:<\/li>\n<li>For tasks that act as a wrapper around a tool that performs authentication itself, use the tools&#8217; authentication method to specify the federated token.<\/li>\n<\/ul>\n<p>You can also publish extensions to the Marketplace with Workload identity federation. <a href=\"https:\/\/jessehouwing.net\/publish-azure-devops-extensions-using-workload-identity-oidc\/\">This blog post<\/a> explains how.<\/p>\n<h4>Terraform tasks<\/h4>\n<p>The <a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=ms-devlabs.custom-terraform-tasks\">Terraform DevLabs<\/a> and <a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=JasonBJohnson.azure-pipelines-tasks-terraform\">Azure Pipelines Terraform Tasks<\/a> extensions have been updated to support workload identity federation. The <a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=ms-devlabs.custom-terraform-tasks\">Terraform DevLabs<\/a> extension uses the <a href=\"https:\/\/www.npmjs.com\/package\/azure-pipelines-tasks-artifacts-common?activeTab=explore\">azure-pipelines-tasks-artifacts-common<\/a> npm package to get the idToken, see <a href=\"https:\/\/github.com\/microsoft\/azure-pipelines-terraform\/blob\/main\/Tasks\/TerraformTask\/TerraformTaskV4\/src\/id-token-generator.ts\">code example<\/a>.<\/p>\n<p>If you are a Terraform user, you should review <a href=\"https:\/\/techcommunity.microsoft.com\/t5\/azure-devops-blog\/introduction-to-azure-devops-workload-identity-federation-oidc\/ba-p\/3908687\">this great walkthrough on the Tech Community<\/a> that uses the <a href=\"https:\/\/github.com\/Azure-Samples\/azure-devops-terraform-oidc-ci-cd\">Azure-Samples\/azure-devops-terraform-oidc-ci-cd<\/a> repository to create and use Azure service connections with Terraform.<\/p>\n<h3>Public preview<\/h3>\n<p>The feature will roll out over the next few weeks. For this preview, we support workload identity federation only for Azure service connections. This scheme does not work with any other types of service connections. See <a href=\"https:\/\/aka.ms\/azdo-rm-workload-identity\">our docs<\/a> for more details.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Do you want to stop storing secrets and certificates in Azure service connections? Are you tired rotating these secrets whenever they expire? We are now announcing a public preview of workload identity federation for Azure service connections. Workload identity federation uses an industry-standard technology, Open ID Connect (OIDC), to simplify the authentication between Azure Pipelines [&hellip;]<\/p>\n","protected":false},"author":26231,"featured_media":67562,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[224,226],"tags":[7259,7282,7280,7281],"class_list":["post-67467","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure","category-ci","tag-azure","tag-authentication","tag-managed-identity","tag-service-principal"],"acf":[],"blog_post_summary":"<p>Do you want to stop storing secrets and certificates in Azure service connections? Are you tired rotating these secrets whenever they expire? We are now announcing a public preview of workload identity federation for Azure service connections. Workload identity federation uses an industry-standard technology, Open ID Connect (OIDC), to simplify the authentication between Azure Pipelines [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts\/67467","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/users\/26231"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/comments?post=67467"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts\/67467\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/media\/67562"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/media?parent=67467"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/categories?post=67467"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/tags?post=67467"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}