In my previous blog I gave an overview of Azure Managed Identity, specifically around virtual machines and managed identities.
In this, I will be detailing the process of implementing a secure use of Key Vault with this virtual machine and how Identity Management can be used to retrieve secrets.
There are two types of managed identities, I will be using system-assigned managed identity for this example.
Azure Resources used for my scenario:-
- Windows Server 2012 R2 Virtual Machine
- Virtual network (vNet) with 1 subnet
- Azure Key Vault
Securing the Azure Key Vault
Lets begin by securing the Key Vault so only the vNet subnet will have access along with your current public IP and Microsoft trusted services.
Select your Azure Key Vault resource -> Select Firewalls and virtual networks
Select radio button: Allow access from: Selected networks
+Add existing virtual networks
Enter your vNet details
Click Add once vNet details have been entered
Now enter your Public IP in Firewall:
Click save
Keyvault is now only accessible via:-
- Subnet of vNet
- Your Public IP Address
- Trusted Microsoft Services
Creating the Key Vault Secret
Open Key Vault
Select Secrets -> Generate/Import
Configure as below:
- Upload Options: Manual
- Name: name of your secret, I used usercred for example
- Password: Enter password or secret value, I have used HelloTesting for example
Select Create
Enabling Managed Identity on Virtual Machine
Select Virtual Machine
Select Identity -> Set Status to On & Save
Log onto Virtual Machine
Now that managed identity has been enabled, an access token using the Virtual Machine identity is required to retrieve the secret from the Key Vault.
This PowerShell snippet will:
- Invoke the web request from the AD tenant to get a token for host
- Response will be extracted in JSON formatted string
- Access token will be extracted as $KeyVaultToken
$response = Invoke-WebRequest -Uri 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fvault.azure.net' -Method GET -Headers @{Metadata="true"}
$content = $response.Content | ConvertFrom-Json
$KeyVaultToken = $content.access_token
Using PowerShell Invoke-WebRequest with the above access token you can retrieve the secret value previously added.
$kvname = "tamops-kv"
$secretname = "usercred"
(Invoke-WebRequest -Uri https://$kvname.vault.azure.net/secrets/$($secretname)?api-version=2016-10-01 -Method GET -Headers @{Authorization="Bearer $KeyVaultToken"}).Content
Output:
{"value":"HelloTesting","id":"https://tamops-kv.vault.azure.net/secrets/usercred/93c08fb152e540c98556bc560ad1452c","attributes":{"enabled":true,"created":1547045609,"updated":1547045609,"recoveryLevel":"Purgeable"}}
As you can see from the above, the secret value that was created previously is displayed, we can now take this further to have this value converted to a usable variable by extracting the JSON response
Rerun your code with the additional $output_secret variable
$kvname = "tamops-kv"
$secretname = "usercred"
$output_secret = (Invoke-WebRequest -Uri https://$kvname.vault.azure.net/secrets/$($secretname)?api-version=2016-10-01 -Method GET -Headers @{Authorization="Bearer $KeyVaultToken"}).Content | ConvertFrom-Json
Now your secret can be used as variable $output_secret.value , super handy for your code!
A great way to keep your passwords & secrets out of code, thanks for reading!
About the Author:
A passion in IT, specifically all things cloud – whether it be a virtual machine taken from a local environment and implemented into the cloud or a fully scalable infrastructure stack built with the cloud in mind – I will enjoy it
Currently focusing on Microsoft Azure including heavily automation on the Azure platform..
Reference:
Thorton, T. (2019). Securing your secrets using Azure Key Vault and Virtual Machine Managed Identity. Available at:
https://thomasthornton.cloud/2019/01/09/seciuring-your-secrets-using-azure-key-vault-and-virtual-machine-identity/ [Accessed: 16th May 2019].