Using Azure Key Vault with PowerShell – Part 1

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 keyscertificates 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:

  1. Set up an Azure Key Vault using the PowerShell Azure Module.
  2. Set administration access policies on the Azure Key Vault.
  3. Grant other users or applications access to cryptographic keyscertificates or secrets.
  4. Add, retrieve and remove a cryptographic key from the Azure Key Vault.
  5. Add, retrieve and remove a secret from the Azure Key Vault.

Requirements

Before getting started there is a few things that will be needed:

  1. An Azure account. I’m sure you’ve already got one, but if not create a free one here.
  2. 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.

ss_akv_create

It will take about 30 seconds for the Azure Key Vault to be installed. It will then show up in the Azure Subscription:

ss_akv_createcompleteportal

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'; }

ss_akv_secretupdatewithparameters

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

ss_akv_secretallhistory

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.

 

 

 

19 thoughts on “Using Azure Key Vault with PowerShell – Part 1

  1. 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

    Like

    • 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!

      Like

  2. 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.

    Like

  3. Arun says:

    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.

    Like

Leave a comment