Adding KeyVault secrets from a Azure DevOps pipeline

If you in your Azure DevOps pipeline create a KeyVault resource and want to add secrets to it, you are faced with the task of adding an Access Policy for the Service Principal (SP) that the DevOPs pipeline is using to connect with your Azure subscription. If the SP doesn’t have access rights, the following will happen – you will get a status code “Forbidden”, which is a HTTP Status Code 403 stating that your access token is valid but you don’t have access rights to perform the requested operation. This may seem weird since you are the creator, but being the creator of the resource isn’t enough here. The identity interacting with KeyVault needs to have an access policy that permits the type of operation it is doing.


So the first question is how do you create an access policy that grants access and the second is, who should it be granted to for it to be running as part of an Azure DevOps pipeline?

We can dynamically get the ObjectID of the Service Principal that is being used to run the pipeline with the below code. First we get the context from the login sequence that the Azure DevOps powershell task created for us, then we query Azure AD to get the ObjectID of that service principal.

$ctx = Get-AzContext
$sp = Get-AzADServicePrincipal -ApplicationId $ctx.Account.Id

To add an Access Policy to KeyVault you use the Powershell cmdlet Set-AzKeyVaultAccessPolicy which supports passing the ObjectID of an Service Principal.

Set-AzKeyVaultAccessPolicy -VaultName $keyVaultName -ResourceGroupName $resourceGroupName -ObjectID $sp.Id -PermissionsToSecrets get,list,set,delete

The complete script for the task would look like

param(
 [Parameter(Mandatory=$True)][string]$keyVaultName,
 [Parameter(Mandatory=$True)][string]$resourceGroupName
)

$rg = Get-AzResourceGroup -ResourceGroupName $resourceGroupName -ErrorAction SilentlyContinue
if ( $rg -eq $null ) {
    Write-Error 'ResourceGroup not found $resourceGroupName'
    $host.SetShouldExit(1)
}
 
$kv = Get-AzResource -Name $keyVaultName -ResourceGroupName $resourceGroupName -ErrorAction SilentlyContinue
if ( $kv -ne $null ) {
    write-output "KeyVault name $keyVauleName already exists"
} else {
    Write-Output "Creating Key Vault named $keyVauleName"
    New-AzKeyVault -VaultName $keyVaultName -ResourceGroupName $resourceGroupName -Location $rg.location
}

$ctx = Get-AzContext
$sp = Get-AzADServicePrincipal -ApplicationId $ctx.Account.Id

write-output "Set KeyVault Access Policy for SP"
Set-AzKeyVaultAccessPolicy -VaultName $keyVaultName -ResourceGroupName $resourceGroupName -ObjectID $sp.Id -PermissionsToSecrets get,list,set,delete