Skip to content

How to Access Restricted Azure Key Vault from Azure DevOps

Image of safe generated with DALLE

Azure Key Vault is a great product to store secrets like connection strings and passwords. It is relatively cheap, easy to use and integr… well quite easy to integrate if you run for example .NET Core application. If you use Key Vault with .NET Framework configuration manager, or you want to access secrets at DevOps pipeline, then things are getting bit more trickier. Let me explain why.

Security is Everything

Accessing Key Vault from Azure application is pretty straight forward. You enable the App Identity, define a Key Vault policy for it and profit. You can use virtual networks to restrict unwanted access and private endpoints to securely access your secrets, but what if you have defined access restrictions and you want to access Key Vault outside of Azure? For example from Azure DevOps.

Allow public access from specific virtual networks rules out Azure DevOps access.

First thing to note is, that you cannot add Azure DevOps into virtual network, which blocks our access into Key Vault. Well luckily we have this little checkbox right down under.

Allow trusted Microsoft services to bypass firewall…?

Or not. Azure DevOps is not trusted Microsoft service, so you won’t get far with that.

What we can do next is of course add network rules for Azure DevOps build agent IP-addresses. That will solve it! Problem is that there are lots of IP-addresses to add AND they might change in the future. So that would work, but not in the best way. I hope that there would be a way to define private endpoint for DevOps or use service tags, but those are not an option at this time. Luckily we can automate this like a real DevOps expert.

Access restriction prevents DevOps from accessing Key Vault

Automate Things

So the problem is, that our build agent IP-address is blocked at Key Vault. In our release pipeline we can set agent’s IP as allow network rule, read our secrets and remove the IP afterwards. To get started we need to first find out what is our agents IP address and most importantly, what is our outgoing IP address. To do that we can use curl command to execute HTTP call into ipinfo.io/ip and get our visible IP as response.

ipaddr=$(curl -s http://ipinfo.io/ip)

Next we need to define a variable where we store this IP-address, so that we can use it in other release steps. To store variables during runtime and use them in another tasks, we need to use pretty complex vso task. These two steps can be done in bash script.

echo "##vso[task.setvariable variable=address;]$ipaddr"

The VSO task creates a variable, which is called address. We can later use this variable to get access to the agents outgoing IP-address.

Finally to open up the restrictions we can use Azure CLI task with proper ARM connection to access our Key Vault network rules. Use script type Shell and Inline script to add and remove network rules. Note that we are using the variable name $(address) here.

# Add IP-address into Key Vault access restrictions
az keyvault network-rule add --name (name of the keyvault) --ip-address "$(address)/32"

# Remove IP-address from Key Vault access restrictions
#az keyvault network-rule remove --name (name of the keyvault) --ip-address "$(address)/32"

Now that the rule is applied (and not removed of course), we can access key vault during our release runtime and have access restrictions set so that no one can access our Key Vault outside of Virtual Network.

Use Azure CLI task with inline shell script to set network rules easily through Azure Resource Manager connection

Summary

We can and we should protect our Key Vaults with access restrictions, even though that they make things a bit more complicated. Azure DevOps is not trusted Microsoft service, because we have Azure DevOps market place full of 3rd party plugins, which are not created and maintained by Microsoft. To access Key Vault with restrictions, we can temporary set network rules to allow build agents to access the secrets and finally remove the restrictions. This is not perfect way to do it, but at this point I think this is tolerable solution.