I thought I'd add to this with a twist on the solution that Prodip provided. This one relies on the fact that when you request a secret, the az client is kind enough to tell you what your client IP address is, i.e:
az keyvault secret show -n "a-known-client-secret" --vault-name "$keyVaultName"
Attempting to get value for known secret from key vault: '******'
ERROR: Client address is not authorized and caller is not a trusted service.
Client address: 1.1.1.1
Caller: appid=***;oid=****;iss=https:
Vault: ******;location=******
So here's my bash script (whitelist-agent-for-key-vault.sh):
#!/usr/bin/env bash
if [[ $(uname -s) == "Linux" ]]; then
azcmd="az"
else
azcmd=$(where az.cmd)
fi
if [[ $1 == "-r" ]]; then
if [[ -z "$3" ]]; then
echo "Build agent IP address is empty, no whitelist entry to remove from key vault: '$2'"
else
echo "Removing key vault '$2' network rule for DevOps build agent IP address: '$3'"
"$azcmd" keyvault network-rule remove -n $2 --ip-address $3/32
fi
exit 0
fi
keyVaultName=$1
knownSecret="<My known secret>"
echo "Attempting to get value for known secret from key vault: '$keyVaultName'"
secretOutput=$("$azcmd" keyvault secret show -n "$knownSecret" --vault-name "$keyVaultName" 2>&1)
buildAgentIpAddress=$(echo $secretOutput | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b")
set -euo pipefail
if [[ ! -z "$buildAgentIpAddress" ]]; then
echo "Azure DevOps IP address '$buildAgentIpAddress' is blocked. Attempting to whitelist..."
"$azcmd" keyvault network-rule add -n $keyVaultName --ip-address $buildAgentIpAddress/32
echo "##vso[task.setvariable variable=buildAgentIpAddress]$buildAgentIpAddress"
else
secretValue=$(echo $secretOutput | grep -o "value")
if [[ -z "$secretValue" ]]; then
echo "Unexpected response from key vault whitelist request, json attribute 'value' not found. Unable to whitelist build agent - response was: '$secretOutput'"
exit 1
fi
fi
Here's how I add the IP to the white list:
- task: AzureCLI@2
displayName: Add Azure DevOps build agent IP to key vault white list
inputs:
azureSubscription: ${{ parameters.azureSubscription }}
scriptType: bash
scriptLocation: scriptPath
scriptPath: $(Pipeline.Workspace)/server-build-tools/drop/build-scripts/whitelist-agent-for-key-vault.sh
arguments: '$(keyVaultName)'
Here's how I remove the IP from the white list
- task: AzureCLI@2
displayName: Remove Azure DevOps build agent IP from key vault white list
condition: always()
inputs:
azureSubscription: ${{ parameters.azureSubscription }}
scriptType: bash
scriptLocation: scriptPath
scriptPath: $(Pipeline.Workspace)/server-build-tools/drop/build-scripts/whitelist-agent-for-key-vault.sh
arguments: '-r "$(keyVaultName)" "$(buildAgentIpAddress)"'
Caveats:
- This relies on the Azure DevOps service principal having been granted read access to the key vault secrets
- Replace the
knownSecret
value with the name of your known secret
Bonus:
This works using Azure CLI and has been tested on Azure DevOps for Linux and Windows build agents running under Git bash for the latter. Normally if you try running 'az' commands in Git Bash, you just get 'Command not found'. I wanted a solution that would work on both, since I need to share code because of the Linux / Windows build requirement.