Compare KeyVault Secrets
  • Updated on 05 Jan 2020
  • 3 minutes to read
  • Contributors
  • Print
  • Comments
  • Share
  • Dark
    Light

Compare KeyVault Secrets

  • Print
  • Comments
  • Share
  • Dark
    Light

If your working with Key Vault for your Azure solutions there is a chance you may have multiple Key Vault instances with 1 per environment. This may mean you have Key Vault instances for the following environments:

  1. Development
  2. Build
  3. System Test
  4. UAT
  5. Production

While this is a good thing to be doing, one of the challenges you will get is how to ensure all of the secrets you create are managed effectively across all instances of Key Vault. Lets say you have a secret which is in 3 out of 5 environments. This means your solution wont always work when its deployed.

The problem gets even more challenging when your team are working on multiple concurrent projects, how do you manage the potential dependancy between projects using the same key and similar challenges.

I wanted to be able to compare my Key Vault instances and check which secret was in which vault. I am not at this point interested in the values, they are secret. I just want to make sure that all secrets are defined in all Key Vaults so that they are in sync.

To do this I have implemented a Powershell script you can run to produce a csv file so you can easily compare the Key Vault instances.

First off run the below snippets to ensure you have the Az modules installed and available if you need to.

Install-Module -Name Az -AllowClobber 
Uninstall-AzureRM

The full script to run in Powershell is below. Simply add the names of your key vault instances to the list and then run it.

Connect-AzAccount

$keyVaults = @('Acme-KV-Dev','Acme-KV-Build', 'Acme-KV-SysTest', 'Acme-KV-UAT', 'Acme-KV-Prod')

$hashTable = $null
$hashTable = @{}
$resourceKey = ''

foreach($keyVaultName in $keyVaults)
{
    Write-Host 'Getting secrets from keyvault: ' $keyVaultName

    $secrets = Get-AzKeyVaultSecret -VaultName $keyVaultName

    foreach($secret in $secrets)
    {
        $secretName = $secret.Name

        if($hashTable.ContainsKey($secretName) -eq $false)
        {
            Write-Host 'Adding new secret to model'


            $azureResource = New-Object -TypeName psobject
            $azureResource | Add-Member -MemberType NoteProperty -Name 'Secret' -Value $secretName

            foreach($v in $keyVaults)
            {
                $azureResource | Add-Member -MemberType NoteProperty -Name $v -Value ''
            }                

            $hashTable.add($secretName, $azureResource)

            Write-Host 'New Resource added: ' $secretName
        }


        $azureResource = $hashTable[$secretName]
        $azureResource.$keyVaultName = 'YES'
    }
}


$hashTable.GetEnumerator() | sort name
$resourceList = [System.Collections.ArrayList]::new(); 
foreach($val in $hashTable.Values)
{
    $resourceList.Add($val)    
}

$resourceList | Export-Csv -Path C:\Temp\KeyVaultSecretMatrix.csv

At the end when the script is finished you will get a CSV like below. You can see how the secret names are listed in column 1 and you get a column for each Key Vault instance and a YES if the secret exists in that instance.

image.png

You could probably extend this further by using a similar script to compare keys in Key Vault and you could potentially automate it to regularly report missing keys.

Hopefully this will inspire you to consider ideas to provide good governance around a consistent and synchronised use of Key Vault in your projects.

Update - 2020-01-05

Following the initial release of this article I had a twitter conversation with Matt Short (details below for Matt) who suggested the idea of extending this idea to use Pester which is a testing framework and approach for Powershell which would allow you to define expectations on secrets you should have in Key Vault and then you would execute tests to check they are all there. You could then manage the secrets by making sure that the secrets were there. Matt wrote an example script and put it on GitHub below:
https://github.com/bytejunkie/kv-pester/blob/master/tests/keyvaults.tests.ps1

I really like this idea and its something I will explore further.

More info on Matt is on the below links:

If you are not familiar with Pester, More info -
https://www.red-gate.com/simple-talk/sysadmin/powershell/testing-powershell-modules-with-pester/

Was this article helpful?