Using Azure Key vault with AzureDevOps
By Martin on Regards: Azure; Infrastructure;Connect Azure Key vault with AzureDevOps
As part of my ongoing efforts to enhance security and streamline processes, I’ve embarked on a project to migrate my credentials to Azure Key Vault. This move is a significant step towards centralizing and securing sensitive data. I’ve already made substantial progress, having established a service connection in Azure DevOps to Azure. You can learn more about this process in my previous post, see here.
For my legacy build pipelines I stored my certificates and secrets
under Library
/ Variable groups
and
Secure files
.
Switching to the Azure Key vault is fairly easy. You only need to
create a new Variable group
under Library
. I
named the variable group resize-image
.Then select
Link secrets from an Azure key vault as variables
and
choose the previously created service principal
(AzureDevOpsKeyVaultServiceConnection
see
here).
Afterwards, enter or select the name of your Azure Key Vault. Then,
click on +Add
under the Variables
section. A
dialog box will appear, displaying all the secrets and certificates
stored in your key vault. From this list, you can select which secrets
and certificates you want to make accessible under the Variable group
you created.
The next step is to “integrate” the created variable group in the
*.yml
pipeline by adding the group
group: resize-image
to variables
.
[...]
variables:
- group: resize-image
[...]
Now you can access the secret resizeappcenterid
with
$(resizeappcenterid)
. When you try to display the secrets
using echo
or a similar command you will only see
***
in order to not be exposed (it’s a security
feature).
Since I needed to sign my code with a certificate I had to adjust the
task which downloaded the certificate from the legacy task
secure files
. I didn’t know how to use the certificate
directly from the variable group, so I decided to write a powershell
script which will download the certificate from the azure Key vault and
convert it to a *.pfx file. In the pipeline you need to use the task
AzurePowerShell
(Using AzureCLI
will not work
as the command Get-AzKeyVaultSecret
will result in unknown
cmdlet).
The task itself looks like the following:
- task: AzurePowerShell@5
displayName: 'Download certificate & install'
inputs:
azurePowerShellVersion: 'LatestVersion'
azureSubscription: 'KeyVaultServiceConnection'
ScriptType: 'InlineScript'
Inline: |
#the name of the key vault
$keyvaultname='getkeyvault'
#the certificate name
$certname="$(resizesigningCert)"
#the path to the certificate (required in the next steps)
$certFilePath="$(Build.SourcesDirectory)\certName.pfx"
#create a pipeline variable so it can be used in the next tasks
Write-Host $certFilePath
Write-Host "##vso[task.setvariable variable=certFilePath]$certFilePath"
Add-Type -AssemblyName System.Security
#get certificate from azure
#$secret=az keyvault secret show -n $certname --vault-name $keyvaultname
$secret = Get-AzKeyVaultSecret -VaultName $keyvaultname -Name $certname
#convert secret to byte array
$pass = $secret.SecretValue | ConvertFrom-SecureString
$bstr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secret.SecretValue);
$PlainTextString = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr);
$secretByte = [Convert]::FromBase64String($PlainTextString)
$x509Cert = new-object System.Security.Cryptography.X509Certificates.X509Certificate2
#import certificate
$x509Cert.Import($secretByte, "", "Exportable,PersistKeySet")
echo "imported"
#store the pfx file
$exportedpfx=$x509Cert.Export('PFX',"$(resizesigningCertpassword)") Set-Content -Path $certFilePath -Value $exportedpfx -Encoding Byte
The *.pfx
file is now ready to use for code signing. In
uwp this can look like the following
[...]
/p:PackageCertificateThumbprint="$(resizesigningCertthumbprint)"
/p:PackageCertificateKeyFile="$(certFilePath)"
/p:PackageCertificatePassword="$(resizesigningCertpassword)"'
When running into problems in the build pipeline always examine the log and error message and try to reproduce it on your local device using the powershell command line.
Propose a change