{"id":100,"date":"2024-02-13T07:16:32","date_gmt":"2024-02-13T07:16:32","guid":{"rendered":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/2024\/02\/13\/workload-identity-federation-for-azure-deployments-is-now-generally-available\/"},"modified":"2024-03-17T18:34:32","modified_gmt":"2024-03-17T18:34:32","slug":"workload-identity-federation-for-azure-deployments-is-now-generally-available","status":"publish","type":"post","link":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/2024\/02\/13\/workload-identity-federation-for-azure-deployments-is-now-generally-available\/","title":{"rendered":"Workload identity federation for Azure deployments is now generally available"},"content":{"rendered":"<p>In September, we <a href=\"https:\/\/devblogs.microsoft.com\/devops\/public-preview-of-workload-identity-federation-for-azure-pipelines\/\">announced<\/a> the ability to configure Azure service connections that do not need a secret. Azure service connections that use workload identity federation are easier to manage and more secure. Many customers have adopted this feature and we\u2019re excited to announce it is now generally available!<\/p>\n\n<h3>Improved security<\/h3>\n<p>Workload identity federation enforces how an identity can be used. The federation subject (sc:\/\/&lt;org&gt;\/&lt;project&gt;\/&lt;service connection name&gt;) configured on the App Registration or Managed Identity can only be used in Azure DevOps, by the service connection the federation is configured for. This provides a stricter constraint than a secret, which could unintentionally be leaked and used for other purposes or from other locations.<\/p>\n<h3>No more worries about expiring secrets<\/h3>\n<p>Configuration of an Azure service connection with workload identity federation is a one-time setup. You don\u2019t have to worry about expiring secrets that have to be rotated in order for the service connection to stay operational.<\/p>\n<h3>Getting started<\/h3>\n<p>If you haven\u2019t used Workload identity federation yet, you can take advantage of worry-free Azure service connections in the following ways:<\/p>\n<p>To create a new Azure service connection using workload identity federation, select Workload identity federation (automatic) in the Azure service connection creation experience:<\/p>\n\n<p>To convert a previously created Azure service connection created with a secret, select the \u201cConvert\u201d action after selecting the connection:<\/p>\n\n<p>To convert multiple service connections that use a secret to use workload identity federation instead, you can use the below script as a basis:<\/p>\n<p>#!\/usr\/bin\/env pwsh<br \/>\n&lt;#<br \/>\n.SYNOPSIS<br \/>\n    Convert multiple Azure Resource Manager service connection(s) to use Workload identity federation<\/p>\n<p>.LINK<br \/>\n    https:\/\/aka.ms\/azdo-rm-workload-identity-conversion<\/p>\n<p>.EXAMPLE<br \/>\n    &lt;script&gt; -Project &lt;project&gt; -OrganizationUrl https:\/\/dev.azure.com\/&lt;organization&gt;<br \/>\n#&gt;<br \/>\n#Requires -Version 7.3<\/p>\n<p>param (<br \/>\n    [parameter(Mandatory=$true,HelpMessage=&#8221;Name of the Azure DevOps Project&#8221;)]<br \/>\n    [string]<br \/>\n    [ValidateNotNullOrEmpty()]<br \/>\n    $Project,<\/p>\n<p>    [parameter(Mandatory=$true,HelpMessage=&#8221;Url of the Azure DevOps Organization&#8221;)]<br \/>\n    [uri]<br \/>\n    [ValidateNotNullOrEmpty()]<br \/>\n    $OrganizationUrl<br \/>\n)<br \/>\n$apiVersion = &#8220;7.1&#8221;<\/p>\n<p>#&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br \/>\n# Log in to Azure<br \/>\naz account show -o json 2&gt;$null | ConvertFrom-Json | Set-Variable account<br \/>\nif (!$account) {<br \/>\n    az login &#8211;allow-no-subscriptions -o json | ConvertFrom-Json | Set-Variable account<br \/>\n}<br \/>\n$OrganizationUrl = $OrganizationUrl.ToString().Trim(&#8216;\/&#8217;)<\/p>\n<p>#&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br \/>\n# Retrieve the service connection<br \/>\n$getApiUrl = &#8220;${OrganizationUrl}\/${Project}\/_apis\/serviceendpoint\/endpoints?authSchemes=ServicePrincipal&amp;type=azurerm&amp;includeFailed=false&amp;includeDetails=true&amp;api-version=${apiVersion}&#8221;<br \/>\naz rest -u $getApiUrl -m GET &#8211;resource 499b84ac-1321-427f-aa17-267ca6975798 &#8211;query &#8220;sort_by(value[?authorization.scheme==&#8217;ServicePrincipal&#8217; &amp;&amp; data.creationMode==&#8217;Automatic&#8217; &amp;&amp; !(isShared &amp;&amp; serviceEndpointProjectReferences[0].projectReference.name!=&#8217;${Project}&#8217;)],&amp;name)&#8221; -o json `<br \/>\n        | Tee-Object -Variable rawResponse | ConvertFrom-Json | Tee-Object -Variable serviceEndpoints | Format-List | Out-String | Write-Debug<br \/>\nif (!$serviceEndpoints -or ($serviceEndpoints.count-eq 0)) {<br \/>\n    Write-Warning &#8220;No convertible service connections found&#8221;<br \/>\n    exit 1<br \/>\n}<\/p>\n<p>foreach ($serviceEndpoint in $serviceEndpoints) {<br \/>\n    # Prompt user to confirm conversion<br \/>\n    $choices = @(<br \/>\n        [System.Management.Automation.Host.ChoiceDescription]::new(&#8220;&amp;Convert&#8221;, &#8220;Converting service connection &#8216;$($serviceEndpoint.name)&#8217;&#8230;&#8221;)<br \/>\n        [System.Management.Automation.Host.ChoiceDescription]::new(&#8220;&amp;Skip&#8221;, &#8220;Skipping service connection &#8216;$($serviceEndpoint.name)&#8217;&#8230;&#8221;)<br \/>\n        [System.Management.Automation.Host.ChoiceDescription]::new(&#8220;&amp;Exit&#8221;, &#8220;Exit script&#8221;)<br \/>\n    )<br \/>\n    $prompt = $serviceEndpoint.isShared ? &#8220;Convert shared service connection &#8216;$($serviceEndpoint.name)&#8217;?&#8221; : &#8220;Convert service connection &#8216;$($serviceEndpoint.name)&#8217;?&#8221;<br \/>\n    $decision = $Host.UI.PromptForChoice([string]::Empty, $prompt, $choices, $serviceEndpoint.isShared ? 1 : 0)<\/p>\n<p>    if ($decision -eq 0) {<br \/>\n        Write-Host &#8220;$($choices[$decision].HelpMessage)&#8221;<br \/>\n    } elseif ($decision -eq 1) {<br \/>\n        Write-Host &#8220;$($PSStyle.Formatting.Warning)$($choices[$decision].HelpMessage)$($PSStyle.Reset)&#8221;<br \/>\n        continue<br \/>\n    } elseif ($decision -ge 2) {<br \/>\n        Write-Host &#8220;$($PSStyle.Formatting.Warning)$($choices[$decision].HelpMessage)$($PSStyle.Reset)&#8221;<br \/>\n        exit<br \/>\n    }<\/p>\n<p>    # Prepare request body<br \/>\n    $serviceEndpoint.authorization.scheme = &#8220;WorkloadIdentityFederation&#8221;<br \/>\n    $serviceEndpoint.data.PSObject.Properties.Remove(&#8216;revertSchemeDeadline&#8217;)<br \/>\n    $serviceEndpoint | ConvertTo-Json -Depth 4 -Compress | Set-Variable serviceEndpointRequest<br \/>\n    $putApiUrl = &#8220;${OrganizationUrl}\/${Project}\/_apis\/serviceendpoint\/endpoints\/$($serviceEndpoint.id)?operation=ConvertAuthenticationScheme&amp;api-version=${apiVersion}&#8221;<\/p>\n<p>    # Convert service connection<br \/>\n    az rest -u $putApiUrl -m PUT -b $serviceEndpointRequest &#8211;headers content-type=application\/json &#8211;resource 499b84ac-1321-427f-aa17-267ca6975798 -o json `<br \/>\n            | ConvertFrom-Json | Set-Variable updatedServiceEndpoint<\/p>\n<p>    $updatedServiceEndpoint | ConvertTo-Json -Depth 4 | Write-Debug<br \/>\n    if (!$updatedServiceEndpoint) {<br \/>\n        Write-Debug &#8220;Empty response&#8221;<br \/>\n        Write-Error &#8220;Failed to convert service connection &#8216;$($serviceEndpoint.name)'&#8221;<br \/>\n        exit 1<br \/>\n    }<br \/>\n    Write-Host &#8220;Successfully converted service connection &#8216;$($serviceEndpoint.name)'&#8221;<br \/>\n}<\/p>\n<h3>Resources<\/h3>\n<p><a href=\"https:\/\/aka.ms\/azdo-rm-workload-identity\">Creating Azure service connections with Workload identity federation<\/a><br \/>\n<a href=\"https:\/\/aka.ms\/azdo-rm-workload-identity-conversion\">Converting Azure service connections<\/a><br \/>\n<a href=\"https:\/\/devblogs.microsoft.com\/devops\/public-preview-of-workload-identity-federation-for-azure-pipelines\">Public preview of Workload identity federation for Azure Pipelines<\/a><\/p>\n<p>The post <a href=\"https:\/\/devblogs.microsoft.com\/devops\/workload-identity-federation-for-azure-deployments-is-now-generally-available\/\">Workload identity federation for Azure deployments is now generally available<\/a> appeared first on <a href=\"https:\/\/devblogs.microsoft.com\/devops\">Azure DevOps Blog<\/a>.<\/p>","protected":false},"excerpt":{"rendered":"<p>In September, we announced the ability to configure Azure service connections that do not need a secret. Azure service connections [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":101,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[3],"tags":[],"class_list":["post-100","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure"],"_links":{"self":[{"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/posts\/100","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/comments?post=100"}],"version-history":[{"count":1,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/posts\/100\/revisions"}],"predecessor-version":[{"id":265,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/posts\/100\/revisions\/265"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/media\/101"}],"wp:attachment":[{"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/media?parent=100"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/categories?post=100"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/tags?post=100"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}