Access Azure Key Vault secrets using a Service Principle with certificate within an Azure DevOps pipeline
Azure Key Vault is a cloud service that provides secure storage for secrets, keys, and certificates of your applications. Integrating Key Vault with Azure DevOps pipelines enhances security by managing sensitive information efficiently.
This article will guide you through the process of accessing secrets from an Azure Key Vault using a Service Principal with a certificate within an Azure pipeline. We will start for the very first steps of creating all the needed resources in Azure, before going back to Azure DevOps. For training reasons, we will perform all the configuration steps with CLI commands, avoiding the Azure Portal UI.
1. Create a new resource group in Azure with Azure CLI
-
open an Azure Shell, either on the Azure Portal or on your local Linux machine.
-
log in to Azure with
az login
and follow the instructions. You can also use the--use-device-code
property to login with a string via browser. -
create a new resource group using the following command. You can replace the name and location with your preferred values:
az group create --name TestResourceGroup --location switzerlandnorth
2. Create a new Key Vault
Use the following command and replace the name and location with your preferred values. The name of the Key Vault must be globally unique, so it is possible that the name you chose is already taken:
az keyvault create --name ThisIsANewTestKeyVault --resource-group TestResourceGroup --location switzerlandnorth
3. Add a new role in the resource group
This is an important step, as without the new role permission you will receive the Caller is not authorized to perform action on resource
or the The operation is not allowed by RBAC
errors when you try to perform operations on the Key Vault, such as adding new secrets.
In the following command:
- The value for the
assignee
property is the fully qualified name of your user which has the format:XXX#EXT#@XXX.onmicrosoft.com
where XXX is your registered email in Azure Portal. - You will need the
Key Vault Administrator
value for therole
property. - The value of the
scope
property can be found in the Settings > Properties page of your Key Vault. Copy the value of theResource ID
and paste it into the command.
az role assignment create \
--assignee "XXX#EXT#@XXX.onmicrosoft.com" \
--role "Key Vault Administrator" \
--scope /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/TestResourceGroup/providers/Microsoft.KeyVault/vaults/ThisIsNewATestKeyVault
4. Create a new Service Principal which uses a certificate
We will create a new identity for accessing our Key Vault from our Azure DevOps account. We can achieve that by creating a new Service Principal. We will use certificate authentication, as recommended by Microsoft, instead of a password.
Pay attention to the following points before running the command:
- You can use another name if you prefer.
- The role for using secrets from the Key Vault is
Key Vault Secrets User
. This is important for our Azure pipelines, so that they can access the data inside the Key Vault. - Use the same value for the
scopes
property as in step 3. - The
create-cert
property creates a new certificate-based instead of a password-based Service Principal. - The certificate name is in the
cert
property. - We store the newly created certificate inside our Key Vault.
az ad sp create-for-rbac \
--name TestKeyVaultServicePrincipal \
--role "Key Vault Secrets User" \
--scopes /subscriptions/3a916bd3-e232-4120-bb00-ea087ee791c0/resourceGroups/TestResourceGroup/providers/Microsoft.KeyVault/vaults/ThisIsANewTestKeyVault \
--create-cert \
--cert TestCertificate \
--keyvault ThisIsANewTestKeyVault
After the command executes, keep the resulting JSON object somewhere safe, as we will need its values in the next steps.
5. Download the .pem certificate on your computer
We will use the content of the created certificate when we wire Azure DevOps to our Key Vault. To do this, we will create a .pem file containing the value of the certificate created in step 4.
First download the stored certificate from the Key Vault:
az keyvault secret download \
--file cert.pfx \
--vault-name ThisIsANewTestKeyVault \
--name TestCertificate \
--encoding base64
Then, create a .pem certificate from the downloaded .pfx file:
openssl pkcs12 -in cert.pfx -passin pass: -passout pass: -out cert.pem -nodes
The certificate is now stored in the cert.pem
You can view its contents with the cat cert.pem
command.
6. Add a new secret into the Key Vault
Use the following command to add a new secret. We will retrieve this secret in our Azure pipeline shortly. Feel free to choose another dummy name and value:
az keyvault secret set --vault-name ThisIsNewATestKeyVault --name "TestSecret" --value "123456789"
7. Add a new Service Connection in Azure DevOps
-
In you Azure DevOps application, click on the
Project Settings
option and then onService Connections
-
Click on
New Service Connection
, select theAzure Resource Manager
option and click onNext
-
Select the
Service principal (manual)
option and click onNext
-
Fill in the input fields using the following values:
- The Subscription Id is the GUID of your account, which you used in the previous CLI commands.
- The Subscription Name is the name of your account, found in the Properties of your Resource Group on the Azure Portal.
- The Service Principal Id is the value of the
appId
property from the JSON object from step 4. - For Credential, select the
Certificate
option. - The Certificate contains the value of the certificate you saved as
cert.pem
in step 5. Copy the text from-----BEGIN PRIVATE KEY-----
to-----END CERTIFICATE-----
and paste it into the input field. - The tenant is the value of the
tenant
property from the JSON object from step 4. - Click on
Verify
to check if the connection works as expected. - Choose a Service connection name you like. This name will appear in the drop-down boxes when you later wire your pipelines with the Key Vault.
- Choose the
Grant access permission to all pipelines
checkbox and click onVerify and save
.
8. Create a new Azure DevOps pipeline
We will now create a new pipeline and access the Key Vault from it. In your Azure DevOps project, navigate to Pipelines > Pipelines
and click on New Pipeline
. Add the following configuration in the newly opened YAML editor.
- We named the stage
Prepare
, as accessing the Key Vault usually happens at the beginning of the pipeline. - We named the job
Secrets
. - The
azureSubscription
property contains the name of the Service Connection we defined in step 7. In my case, it is called KeyVaultWithCertificate. - The
KeyVaultName
property contains the name of the Key Vault we created in step 2. - The script stores the value of the secret TestSecret in a variable with the same name. For more information on setting variables in scripts, check this documentation from Microsoft
trigger:
- master
resources:
- repo: self
stages:
- stage: Prepare
displayName: Prepare
jobs:
- job: Secrets
displayName: Get Secrets
steps:
- task: AzureKeyVault@2
inputs:
azureSubscription: 'KeyVaultWithCertificate'
KeyVaultName: 'ThisIsANewTestKeyVault'
SecretsFilter: '*'
RunAsPreJob: false
- script: |
echo "##vso[task.setvariable variable=TestSecret;isOutput=true]$(TestSecret)"
name: SecretVariables
Save the pipeline and check for the first automated run. The connection to Azure should work.
9. Access the stored variable from another job
A common scenario after retrieving secrets and storing them in variables is to access their values from other jobs. To achieve this, edit your pipeline and add an extra dummy job that echoes the value of the TestSecret secret. Add the following YAML configuration at the end of the pipeline:
- job: EchoTestSecret
displayName: Echoes the value of TestSecret
variables:
varFromJobSecrets: $[ dependencies.Secrets.outputs['SecretVariables.TestSecret'] ]
steps:
- bash: echo $(varFromJobSecrets)
Conclusion
This guide has described all the necessary steps for creating a Key Vault, a new Service Principal with certificate and an Azure pipeline which uses all this information. Feel free to leave a comment if you liked my step-by-step guide.