Certificate authentication into Azure Key Vault

If you haven't, you should better Get started with Azure Key Vault first.

Azure Key Vault is amazing for keeping secrets and cryptographic keys. But I don’t understand why authentication via application secret (a string) is offered as an option. Having Azure Key Vault accessed via a secret string in your application settings is as good as having all your secrets in the config as well. Once the secret is compromised, the whole thing is vulnerable.

Having a certificate as a means for authentication? Especially if you don’t check it in the same place as your secret-accessing code? And if checked in, being as a pfx whose password is shared privately off-line? Sounds a little bit better doesn’t it?

I like particularly the idea of being the machine (through its certificate store) the one that has access, instead of a user with a string. At the end of the day X509 certificates are a little bit more complex that a 32 char string, right? A certificate in a machine store is not going to be accidentally be forwarded in an email to the wrong individual. Nor being left in a post it.

Enough with the sales work, I’m here for the code, not for being door to door with a vacuum cleaner.

Creating the vault

As for any other exercise, some warm-up. Before working on any Azure Powershell task remember to:

  1. Log into Azure Resource manager with the Login-AzureRmAccount commandlet.
  2. Make sure your Azure Rm is pointing to the right place using Select-AzureRmSubscription -SubscriptionName {your subscription}

Done with the stretches, let’s create the vault.

 New-AzureRmKeyVault -VaultName '{your vault name}' -ResourceGroupName '{your resource group name}' -Location 'South Central US'

Setting up an AD application and service principal to access the vault

Access to the Azure Key Vault is granted through Azure Active Directory, so you have to have an AD account you either own or have permissions to. Specifically permissions to create AD applications.

This will create an application in your AD which is accessed with the certificate you just loaded into Powershell.

 $certificate = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2

$certificate.Import('c:\location\certificate.cer')

$startDate = $certificate.GetEffectiveDateString()
$endDate = $certificate.GetExpirationDateString()
$credValue = [System.Convert]::ToBase64String($certificate.GetRawCertData())
$azureADApplication = New-AzureRmADApplication -DisplayName "{application name}" -HomePage "{application page}" -IdentifierUris "{application page}" -KeyValue $credValue -KeyType "AsymmetricX509Cert" -KeyUsage "Verify" -StartDate $startDate -EndDate $endDate

You can use $azureADApplication.ApplicationId to use it as “client Id” when authenticating into the key vault.

Now let’s create a service principal to access the application.

 $principal= New-AzureRmADServicePrincipal -ApplicationId $azureADApplication.ApplicationId

Granting access to the service principal into the Azure key vault

Finally, we have to tell the vault that the service principal is authorized to perform these operations.

 Set-AzureRmKeyVaultAccessPolicy -VaultName '{vault name}' -ServicePrincipalName $principal.ServicePrincipalName -PermissionsToSecrets all -ResourceGroupName '{resource group name}'

Also use -PermissionsToKeys for grating permissions to keys as well as secrets.

Full usage here Set-AzureRmKeyVaultAccessPolicy

And that’s all folks.