Posting on behalf of Prashanth Yerramilli
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 fledling startups to Fortune 500 companies world over.
Developers use Key Vault to store their adhoc 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 and then bind it in Windows Certificate manager.
Now what if developer doesn’t have to poll. And also 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 a specific vault by specifying how often it should fetch the certificate
By doing the above steps the latest certificate is bound correctly in Windows Certificate Manager. This feature enables auto-rotation of SSL certificates, without necessitating a re-deployment or binding.
In the lifecycle 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. A Linux version is coming soon.
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, without necessitating a re-deployment or binding.
Also 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 injects the credentials (of that identity) into the resource (in this case a virtual machine).
- Your code calls a local MI endpoint to get an access token
- MI uses the locally injected 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 lifecycle 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.
Prerequisites
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 and the ARM Parameters file 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
Note: Your observedCertificates urls should be of the form:
https://myVaultName.vault.azure.net/secrets/myCertName
and not:
https://myVaultName.vault.azure.net/certificates/myCertName
Reason being the /secrets path returns the full certificate, inluding 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. And so 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: We’re actively working on a VM Extension for Linux and would love to hear any feedback you might have.
We are eager to hear from you about your use cases and how we can evolve the VM Extension to help you. So 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.
Prashanth Yerramilli, Senior Program Manager, Azure Key Vault
Prashanth Yerramilli is the Key Vault Program Manager on the Azure Security team. He has over 10 years of Software Engineering experience and brings to the team love for creating the ultimate development experience.
Prashanth can be reached at:
-Twitter @yvprashanth1
-GitHub https://github.com/yvprashanth