Blog
Securing your secrets using Azure Key Vault and Virtual Machine Managed Identity
25 January 2019 | Posted by Thomas Thornton

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

Let’s 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

Key Vault secret has now been created and will be accessible further in the tutorial by the virtual machine using a managed identity

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:

  1. Invoke the web request from the AD tenant to get a token for host
  2. Response will be extracted in JSON formatted string
  3. 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!

No comments
Leave a Comment