Azure Key Vault is used to safeguard and manage cryptographic keys, certificates and secrets used by cloud applications and services (you can still consume these on-premise though). This allows other application, services or users in an Azure subscription to store and retrieve these cryptographic keys, certificates and secrets.
Once cryptographic keys, certificates and secrets have been stored in a Azure Key Vault access policies can be configured to provide access to them by other users or applications.
Azure Key Vault also stores all past versions of a cryptographic key, certificate or secret when they are updated. So this allows easily rolling back if anything breaks.
This post is going to show how:
- Set up an Azure Key Vault using the PowerShell Azure Module.
- Set administration access policies on the Azure Key Vault.
- Grant other users or applications access to cryptographic keys, certificates or secrets.
- Add, retrieve and remove a cryptographic key from the Azure Key Vault.
- Add, retrieve and remove a secret from the Azure Key Vault.
Requirements
Before getting started there is a few things that will be needed:
- An Azure account. I’m sure you’ve already got one, but if not create a free one here.
- The Azure PowerShell module needs to be installed. Click here for instructions on how install it.
Install the Key Vault
The first task is to customize and install the Azure Key Vault using the following PowerShell script.
# The name of the Azure subscription to install the Key Vault into | |
$subscriptionName = 'MySubscription' | |
# The resource group that will contain the Key Vault to create to contain the Key Vault | |
$resourceGroupName = 'MyKeyVaultRG' | |
# The name of the Key Vault to install | |
$keyVaultName = 'MyKeyVault' | |
# The Azure data center to install the Key Vault to | |
$location = 'southcentralus' | |
# These are the Azure AD users that will have admin permissions to the Key Vault | |
$keyVaultAdminUsers = @('Joe Boggs','Jenny Biggs') | |
# Login to Azure | |
Login-AzureRMAccount | |
# Select the appropriate subscription | |
Select-AzureRmSubscription -SubscriptionName $subscriptionName | |
# Make the Key Vault provider is available | |
Register-AzureRmResourceProvider -ProviderNamespace Microsoft.KeyVault | |
# Create the Resource Group | |
New-AzureRmResourceGroup -Name $resourceGroupName -Location $location | |
# Create the Key Vault (enabling it for Disk Encryption, Deployment and Template Deployment) | |
New-AzureRmKeyVault -VaultName $keyVaultName -ResourceGroupName $resourceGroupName -Location $location ` | |
-EnabledForDiskEncryption -EnabledForDeployment -EnabledForTemplateDeployment | |
# Add the Administrator policies to the Key Vault | |
foreach ($keyVaultAdminUser in $keyVaultAdminUsers) { | |
$UserObjectId = (Get-AzureRmADUser -SearchString $keyVaultAdminUser).Id | |
Set-AzureRmKeyVaultAccessPolicy -VaultName $keyVaultName -ResourceGroupName $resourceGroupName -ObjectId $UserObjectId ` | |
-PermissionsToKeys all -PermissionsToSecrets all -PermissionsToCertificates all | |
} |
But first, the variables in the PowerShell script need to be customized to suit. The variables in the PowerShell script that needs to be set are:
- $subscriptionName – the name of the Azure subscription to install the Key Vault into.
- $resourceGroupName – the name of the Resource Group to create to contain the Key Vault.
- $keyVaultName – the name of the Key Vault to create.
- $location – the Azure data center to install the Key Vault to (use Get-AzureRMLocation to get a list of available Azure data centers).
- $keyVaultAdminUsers – an array of users that will be given administrator (full control over cryptographic keys, certificates and secrets). The user names specified must match the full name of users found in the Azure AD assigned to the Azure tenancy.
It will take about 30 seconds for the Azure Key Vault to be installed. It will then show up in the Azure Subscription:
Assigning Permissions
Once the Azure Key Vault is setup and an administrator or two have been assigned, other access policies will usually need to be assigned to users and/or application or service principal.
To create an access policy to allow a user to get and list cryptographic keys, certificates and secrets if you know the User Principal Name:
Set-AzureRmKeyVaultAccessPolicy -VaultName $keyVaultName -ResourceGroupName $resourceGroupName ` | |
-UserPrincipalName 'Joe.Boggs@contoso.com' ` | |
-PermissionsToCertificates list,get ` | |
-PermissionsToKeys list,get ` | |
-PermissionsToSecrets list,get |
Note: the above code assumes you still have the variables set from the ‘Install the Key Vault’ section.
If you only have the full name of the user then you’ll need to look up the Object Id for the user in the Azure AD:
$userObjectId = (Get-AzureRmADUser -SearchString 'Joe Bloggs').Id | |
Set-AzureRmKeyVaultAccessPolicy -VaultName $keyVaultName -ResourceGroupName $resourceGroupName ` | |
-ObjectId $userObjectId ` | |
-PermissionsToCertificates list,get ` | |
-PermissionsToKeys list,get ` | |
-PermissionsToSecrets list,get |
Note: the above code assumes you still have the variables set from the ‘Install the Key Vault’ section.
To create an access policy to allow a service principal or application to get and list cryptographic keys if you know the Application Id (a GUID):
Set-AzureRmKeyVaultAccessPolicy -VaultName $keyVaultName -ResourceGroupName $resourceGroupName ` | |
-ServicePrincipalName 'e9b1bc3c-4769-4a98-9014-b315fd2adf53' ` | |
-PermissionsToCertificates list,get ` | |
-PermissionsToKeys list,get ` | |
-PermissionsToSecrets list,get |
Note: the above code assumes you still have the variables set from the ‘Install the Key Vault’ section.
Changing the values of the PermissionsToKeys, PermissionsToCertificates and PermissionsToSecrets parameters in the cmdlets above allow different permissions to be set for each policy.
The available permissions for certificates, keys and secrets are:
An access policy can be removed from users or service principals using the Remove-AzureRmKeyVaultAccessPolicy cmdet:
Remove-AzureRmKeyVaultAccessPolicy -VaultName $keyVaultName -ResourceGroupName $resourceGroupName ` | |
-UserPrincipalName 'Joe.Boggs@contoso.com' |
Note: the above code assumes you still have the variables set from the ‘Install the Key Vault’ section.
Working with Secrets
Secrets can be created, updated, retrieved and deleted by users or applications that have been assigned with the appropriate policy.
Creating/Updating Secrets
To create a new secret, use the Set-AzureKeyVaultSecret cmdlet:
Set-AzureKeyVaultSecret -VaultName $keyVaultName -Name 'MyAdminPassword' ` | |
-SecretValue (ConvertTo-SecureString -String 'P@ssword!1' -AsPlainText -Force) |
Note: the above code assumes you still have the variables set from the ‘Install the Key Vault’ section.
This will create a secret called MyAdminPassword with the value P@ssword!1 in the Azure Key Vault.
The secret can be updated to a new value using the same cmdlet:
Set-AzureKeyVaultSecret -VaultName $keyVaultName -Name 'MyAdminPassword' ` | |
-SecretValue (ConvertTo-SecureString -String 'Sup3rS3cr3tP4ss!' -AsPlainText -Force) |
Additional parameters can also be assigned to each version of a secret to control how it can be used:
- ContentType – the type of content the secret contains (e.g. ‘txt’)
- NotBefore – the date that the secret is valid after.
- Expires – the date the secret is valid until.
- Disable – marks the secret as disabled.
- Tag – assigns tags to the secret.
For example:
Set-AzureKeyVaultSecret -VaultName $keyVaultName -Name 'MyAdminPassword' ` | |
-SecretValue (ConvertTo-SecureString -String 'Sup3rS3cr3tP4ss!' -AsPlainText -Force) ` | |
-ContentType 'txt' ` | |
-NotBefore ((Get-Date).ToUniversalTime()) ` | |
-Expires ((Get-Date).AddYears(2).ToUniversalTime()) ` | |
-Disable:$false ` | |
-Tags @{ 'Risk' = 'High'; } |
Retrieving Secrets
To retrieve the latest (current) version of a secret, use the Get-AzureKeyVaultSecret cmdlet:
$secretText = (Get-AzureKeyVaultSecret -VaultName $keyVaultName -Name 'MyAdminPassword').SecretValue |
This will assign the stored secret to the variable $secretText as a SecureString. This can then be passed to any other cmdlets that require a SecureString.
To list all the versions of a secret, add the IncludeVersions parameter:
Get-AzureKeyVaultSecret -VaultName $keyVaultName -Name 'MyAdminPassword' -IncludeVersions |
To retrieve a specific version of a secret, use the Get-AzureKeyVaultSecret cmdlet with the Version parameter specified:
$secretText = (Get-AzureKeyVaultSecret -VaultName $keyVaultName -Name 'MyAdminPassword' -Version '02218af0521749b084bb08bd13184efb') |
Removing Secrets
Finally, to remove a secret use the Remove-AzureKeyVaultSecret cmdlet:
Remove-AzureKeyVaultSecret -VaultName $keyVaultName -Name 'MyAdminPassword' -Force |
That pretty much covers managing and using secrets in Azure Key Vault using PowerShell.
Cryptographic keys and Certificates
In the next part of this series I’ll cover using Azure Key Vault to use and manage cryptographic keys and certificates. Thanks for sticking with me this far.
Many thanks – looking forward to part 2
LikeLike
I better get to finishing it then! I’m working with my teams on our Key Vault automation at the moment so that should be the basis for the next one. Cheers!
LikeLike
Hi Daniel,
Is it possible to use keyVault secrets with Login-azurermaccount ??
thanks
LikeLike
Hi Umer,
Do you mean use KeyVault secrets to authenticate using Login-AzureRmAccount or to retrieve secrets from a KeyVault after logging in using Login-AzureRmAccount?
The answer to the former is no, and the answer to the latter is yes.
Does that help?
Thanks
Dan
LikeLike
yea I was talking about the possibility of using KeyVault secrets to authenticate using Login-AzureRmAccount which is impossible.
Thanks for the timely reply.
LikeLike
Hey Daniel,
I was hoping to find part 2 of this post after combing through your blog. Have you got guides relating to key vault automation?
Cheers
LikeLike
HI There, unfortunately Part 2 got lost on my backlog. It is still planned, but AKV has changed a significant amount and there are many new options for automation that I need to document.
LikeLike
Hey Daniel
Thanks for writing this post!
I was looking for a way to manage secrets for ci/cd. I wanted to use the same approach for multiple different build systems. Also for local testing, sometimes I use multiple different subscriptions and access tokens for one solution, so key vault seems to work very well for this.
I’ve created a very simple PowerShell module and I pushed it to PSGallery. It’s called PSBuildSecrets (https://github.com/synax/PSBuildSecrets)
Cheers Stefan
LikeLike
Awesome stuff Stefan! Thanks for sharing this! Very helpful indeed – and thank you for the shout out! 🙂
I can see that being really useful too. I’d love to see you do more with this too – such as perhaps pulling down certs or other things that could be required during a deployment. For example, for a deployment of Azure API Management you’ve usually got to inject a PFX file into the ARM template (after converting to Base 64) to get it to load. So being able to specify the “prod” or “test” cert could be handy.
Lots of use cases here and great work with the project!
LikeLike
How do you push TXT file as a secret via Azure powershell module. it’s possible to specify –file parameter to azure `azure keyvault secret get -u -s –file file.rsa`. This will create secret with SSH key. I can not find a way to do that with Powershell module.
LikeLike
Hi Artisticcheese,
This will work:
Set-AzureKeyVaultSecret -VaultName MyKeyVault -Name MySecret -SecretValue (ConvertTo-SecureString -String (Get-Content -Path ‘C:\Users\Dan\.ssh\file.rsa’ -Raw) -AsPlainText -Force)
Cheers!
LikeLike
Thank you Daniel. This is a great article. Do you know when can we expect part 2 ? 🙂
LikeLiked by 1 person
Ah now that is a good question. I’ve been spending a large amount of time working with Key Vault and Azure API Management + App Gateway and I’d like the second part to focus on automatic issuance of self-signed and public CA certs (as they is one of the more confusing tasks). I’m hoping to have something soon 🙂
LikeLiked by 1 person
That would be appreciated.
T
LikeLiked by 2 people
Hi Daniel Scott,
Thanks for the nice post. Is there a way we can delete the secrets in key vault based on the expiration date of the different versions. let says if I have a secret that is set to expire in next 2 days and once that is expired I want to delete that particular version instead of deleting the whole secret.
LikeLike
Hi Arun,
I’d have to do some digging but I am fairly certain the current PowerShell cmdlets would allow for that. I’ll see if I can put something together for you as an example.
LikeLike
Thanks Daniel, this was really helpful
LikeLike
Glad to help! 🙂
LikeLike