Posting on behalf of the Key Vault Team.
When we launched Azure Key Vault a few years ago, it solved a major problem users had which was that storing sensitive and/or secret information in code or config files in plain text causes multiple problems including security exposure. Users stored their secrets in a safe store like Key Vault and used a URI to fetch the secret material. This service has been wildly popular and has become a standard for cloud applications. It is used by fledgling startups to Fortune 500 companies world over. Developers use Key Vault to store their ad-hoc secrets, certificates and keys used for encryption. And to follow best security practices they create secrets that are short lived.
An example of typical flow in this case could be:
Step 1: Developer creates a certificate in Key Vault
Step 2: Developer sets the lifetime of the secret to be 30 day. In other words developer asks Key Vault to re-create the certificate every 30 days. Developer also chooses to receive an email when a certificate is about to expire
Step 3: Developer writes a polling service to check if the certificate has indeed expired In the above scenario there are few challenges for the customer. They would have to write a polling service that constantly checks if the certificate has expired and if so they wait for the new certificate, retrieve and then install it in Windows Certificate manager.
Now what if developer doesn’t have to poll and if the developer doesn’t have to bind the new certificate in Windows Certificate manager? To solve this exact problem we built a Key Vault Virtual Machine Extension. Azure virtual machine (VM) extensions are small applications that provide post-deployment configuration and automation tasks on Azure VMs. For example, if a virtual machine requires software installation, anti-virus protection, or to run a script inside of it, a VM extension can be used. Azure VM extensions can be run with the Azure CLI, PowerShell, Azure Resource Manager templates, and the Azure portal. Extensions can be bundled with a new VM deployment, or run against any existing system.
To learn more about VM Extensions please click here
Key Vault VM Extension is supposed to do just that as explained in the steps below:
Step 1: Create a Key Vault and create an Azure Windows Virtual Machine
Step 2: Install the Key Vault VM Extension on the VM
Step 3: Configure Key Vault VM Extension to monitor the set of secrets (based on the vault URL), by specifying how often it should fetch the certificate. If a monitored (‘observed’) Key Vault url corresponds to a certificate, it is retrieved (including its corresponding private key) and installed in the designated local certificate store. Non-certificate secrets are ignored. By doing the above steps the latest certificate is correctly installed in Windows Certificate Manager.
This feature enables auto-rotation of SSL certificates to ensure the latest certificate is installed. In the life-cycle of secrets management fetching the latest version of the secret (for the purpose of this article a certificate) is just as important as storing it securely. To solve this problem, on an Azure Virtual Machine, we’ve created a VM Extension for Windows (find out more here). A Linux version is also available here. Virtual Machine Extensions are small applications that provide post-deployment configuration and automation tasks on Azure VMs. In this case the Key Vault Virtual Machine extension once installed fetches the latest version of the certificate at a specified interval and automatically binds the latest version of the certificate in the certificate store on Windows. As you can see this feature enables auto-rotation of SSL certificates, assuming you have bound your initial cert correctly (or upon a new VM deployment).
Before we begin going through the tutorial, we need to understand a concept called Managed Identities. Your code needs credentials to authenticate to cloud services, but you want to limit the visibility of those credentials as much as possible. Ideally, they never appear on a developer’s workstation or get checked-in to source control. Azure Key Vault can store credentials securely so they aren’t in your code, but to retrieve them you need to authenticate to Azure Key Vault. To authenticate to Key Vault, you need a credential! A classic bootstrap problem. Through the magic of Azure and Azure AD, MI provides a “bootstrap identity” that makes it much simpler to get things started. Here’s how it works: When you enable MI for an Azure resource such as a virtual machine, Azure creates a Service Principal (an identity) for that resource in Azure AD, and can be retrieved by the VM from the underlying hosting service/hosting platform.
- Your code calls the MI endpoint to get an access token
- MI uses the credentials to get an access token from Azure AD
- Your code uses this access token to authenticate to an Azure service
Now within Managed Identities there are 2 types:
-
System Assigned managed identity is enabled directly on an Azure service instance. When the identity is enabled, Azure creates an identity for the instance in the Azure AD tenant that’s trusted by the subscription. The life-cycle of the identity is managed by Azure and is tied to the Azure service instance.
-
User Assigned managed identity is created as a standalone Azure resource. Users first create an identity and then assign that identity to one or more Azure resources. In this tutorial I will demonstrate how to create a Azure Virtual Machine with an ARM template which also includes creating a Key Vault VM Extension on the VM.
To learn more on using managed identities and IMDS, see here:
If you were using the deprecated MSI VM Extension, see here to migrate to IMDS:
Prerequisites
- Create a key vault by following any of the 5 minute Quick-starts
- Create a certificate within the key vault on Azure Portal
Step 1
After the prerequisites are complete, create an System Assigned identity by following this tutorial
Step 2
Assign the newly created System Assigned identity to access to your Key Vault
- Go to https://portal.azure.com and navigate to your Key Vault
- Select Access Policies section and Add New by searching for the User Assigned identity
Step 3
Create or Update a VM with the following ARM template You can view full the ARM template here. The most minimal settings in the ARM template are shown below:
{ "secretsManagementSettings": { "observedCertificates": [ "<keyvault URI of a secret to be monitored/retrieved, in versionless format: https://myVaultName.vault.azure.net/secrets/myCertName">, "<more entries here>", "pollingIntervalInS": "[parameters('kvvmextPollingInterval')]", ] } } As you can see we only specify the observedCertificates parameter and polling Interval in seconds</more></keyvault>
**Note: Your observedCertificates urls should be of the form:
https://myVaultName.vault.azure.net/secrets/myCertName
It should not look like this: https://myVaultName.vault.azure.net/certificates/myCertName
This is due to /secrets path returns the full certificate, including the private key, while the /certificates path does not.
By following this tutorial you can create a VM with the above specified template. The above tutorial assumes that you are storing your certificates on Windows Certificate Manager. The VM Extension pulls down the latest certificates at a specified interval and automatically binds those certificates in your certificate manager.
That’s all folks!
Linux Version: The Linux version can also be found here. Please reach out to us and add your feature requests to the Azure feedback forum. If you run into issues using the VM extension please reach out to us on StackOverflow.
Great Article, Thanks a lot. Bookmarked
Great article, but the links to the ARM template point to a Git Repo in Azure DevOps that the public does not have access to, so could you post it elsewhere? Also, does this work for Virtual Machine Scale Sets. If so, I owe you dinner.
Link(s) updated. Yes, this does work on VM Scale Sets as well.