Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
The Azure Key Vault virtual machine (VM) extension automatically refreshes certificates stored in an Azure key vault. The extension monitors a list of observed certificates stored in key vaults. When the extension detects a change, it retrieves and installs the corresponding certificates. This article describes the supported platforms, configurations, and deployment options for the Key Vault VM extension for Linux.
Note
Try VM assist for faster diagnostics. We recommend that you run VM assist for Windows or VM assist for Linux. These script-based diagnostic tools help you to identify common issues that affect the Azure VM Guest Agent and overall VM health.
If you're experiencing performance problems with virtual machines, before contacting support, run these tools.
Operating systems
The Key Vault VM extension for Linux supports the following distributions, on both AMD64 and ARM64:
- Ubuntu 24.04
- Azure Linux 3.0 and 4.0
- Red Hat Enterprise Linux (RHEL) 9
Note
The extension selects a distribution-specific binary at install time from /etc/os-release. Installing on any other distribution fails with a "distribution is not supported" error that appears in the extension status.
Supported certificate content types
The Key Vault VM extension supports the following certificate content types:
- PKCS #12
- PEM
Note
The Key Vault VM extension downloads all certificates to the location you specify in the certificateStoreLocation property in the VM extension settings, or to the default store location /var/lib/waagent/Microsoft.Azure.KeyVault.Store/ when you don't specify one.
Features
The Key Vault VM extension for Linux version 4.x:
- Installs the two newest versions of each certificate.
- Installs each certificate as split files: a full-chain
.pemfile and a separate.keyidprivate key file, each written as a versioned file with a stable symbolic link that points to the latest version. - Performs certificate chain validation before installing any certificate that carries the TLS Server Authentication Extended Key Usage (EKU). Validation is fail-open: a certificate is still installed if validation can't complete because of transient network issues. Certificates without the Server Authentication EKU aren't subject to this check.
- Applies POSIX ACLs to grant configured users and groups read access to the private key. ACL enforcement is always on.
- Supports an optional per-certificate authentication override, which allows individual observed certificates to authenticate to Key Vault with a different managed identity than the extension default. For more information, see Extension schema.
- Supports VM extension logging integration through Fluentd. For more information, see Logging with Fluentd.
Upgrading from 3.0
If you're updating from 3.0, the following features are changed or removed.
General breaking changes:
pollingIntervalInSis now limited to between 5 and 60 minutes. By default, the extension polls once each hour.requireInitialSyncis removed. The extension only reports success if it installs all configured certificates.- You can no longer configure a specific version of a certificate. Observed certificate URLs must be versionless.
- The legacy schema where
observedCertificatesis a list of URL strings is no longer supported. Each entry must be an object with aurlproperty.
Linux-specific breaking changes:
- The certificate chain and private key are now written to separate files. In 3.0, the full chain and the private key were combined into a single PEM file. In 4.x, the extension writes the full chain to
<vaultname>.<certname>.pemand the private key to a separate<vaultname>.<certname>.keyidfile. This change is breaking: applications that expect the key and chain in one file must be updated to read the chain from the.pemfile and the private key from the.keyidfile. The.lumafile is updated after the symbolic links are updated, so applications should monitor changes to this metadata file. customSymbolicLinkNameis removed. The extension always uses the default symbolic link name<vaultname>.<certname>.aclEnabledis removed. ACL functionality is now always enabled.certificateStoreNameis ignored on Linux and has no effect.
Note
Upgrading from the previous extension version doesn't delete certificates that were already downloaded to disk. Additionally, 4.x uses a different file name format, so any existing files remain untouched.
Prerequisites
Review the following prerequisites for using the Key Vault VM extension for Linux:
An Azure Key Vault instance with a certificate. For more information, see Create a key vault by using the Azure portal.
A VM with an assigned managed identity.
Assign the Key Vault Secrets User role at the Key Vault scope level to the managed identity for the VM or Azure Virtual Machine Scale Sets. This role retrieves the secret portion of a certificate. For more information, see the following articles:
Configure Virtual Machine Scale Sets with the following
identityconfiguration:"identity": { "type": "UserAssigned", "userAssignedIdentities": { "[parameters('userAssignedIdentityResourceId')]": {} } }Configure the Key Vault VM extension with the following
authenticationSettingsconfiguration:"authenticationSettings": { "msiEndpoint": "[parameters('userAssignedIdentityEndpoint')]", "msiClientId": "[reference(parameters('userAssignedIdentityResourceId'), variables('msiApiVersion')).clientId]" }
Note
You can also use the old access policy permission model to provide access to VMs and Virtual Machine Scale Sets. This method requires a policy with get and list permissions on secrets. For more information, see Assign a Key Vault access policy.
Extension schema
The following JSON shows the schema for the Key Vault VM extension. Before you consider the schema implementation options, review the following important notes.
The extension doesn't require protected settings. All settings are public information.
Observed certificate URLs must use the form
https://myVaultName.vault.azure.net/secrets/myCertName.This form is required because the
/secretspath returns the full certificate, including the private key, but the/certificatespath doesn't. For more information about certificates, see Azure Key Vault keys, secrets and certificates overview. You can't specify a specific version of the certificate.The URL host must be a recognized Azure Key Vault host.
The
authenticationSettingsproperty is required for VMs with any user assigned identities, and for Azure Arc-enabled VMs.Omit this property when you use a system-assigned identity. For Azure Arc-enabled VMs, set
msiEndpointtohttp://localhost:40342/metadata/identity.
{
"type": "Microsoft.Compute/virtualMachines/extensions",
"name": "KVVMExtensionForLinux",
"apiVersion": "2025-04-01",
"location": "<location>",
"dependsOn": [
"[concat('Microsoft.Compute/virtualMachines/', <vmName>)]"
],
"properties": {
"publisher": "Microsoft.Azure.KeyVault",
"type": "KeyVaultForLinux",
"typeHandlerVersion": "4.0",
"autoUpgradeMinorVersion": true,
"enableAutomaticUpgrade": true,
"settings": {
"secretsManagementSettings": {
"pollingIntervalInS": <Optional. Polling interval in seconds, between 300 (5 min) and 3600 (60 min). Example: "3600">,
"certificateStoreLocation": <Optional. Default disk path where certificates are stored. Example: "/var/lib/waagent/Microsoft.Azure.KeyVault.Store">,
"observedCertificates": <An array of Key Vault URIs that represent monitored certificates, including per-certificate store location and ACL permissions on the certificate private key. Example:
[
{
"url": <A Key Vault URI to the secret portion of the certificate. Example: "https://myvault.vault.azure.net/secrets/mycertificate1">,
"certificateStoreLocation": <The disk path where the certificate is stored. Example: "/var/lib/waagent/Microsoft.Azure.KeyVault/app1">,
"acls": <Optional. An array of users and groups to grant read access to the certificate private key. Example:
[
{ "user": "app1", "group": "appGroup1" },
{ "user": "service1" }
]>
},
{
"url": <Example: "https://myvault.vault.azure.net/secrets/mycertificate2">,
"certificateStoreLocation": <Example: "/var/lib/waagent/Microsoft.Azure.KeyVault/app2">,
"authenticationOverride": <Optional. Overrides authenticationSettings for this certificate only, so it can authenticate with a different managed identity. Example: {"msiClientId": "11112222-bbbb-3333-cccc-4444dddd5555"}>
}
]>
},
"authenticationSettings": {
"msiEndpoint": <Required when the msiClientId property is used. Specifies the MSI endpoint. Example for most Azure VMs: "http://169.254.169.254/metadata/identity">,
"msiClientId": <Required when the VM has any user assigned identities. Specifies the MSI identity. Example: "00001111-aaaa-2222-bbbb-3333cccc4444">
}
}
}
}
Property values
The JSON schema includes the following properties.
| Name | Value/Example | Data type |
|---|---|---|
apiVersion |
2025-04-01 | date |
publisher |
Microsoft.Azure.KeyVault | string |
type |
KeyVaultForLinux | string |
typeHandlerVersion |
"4.0" | string |
pollingIntervalInS (optional) |
"3600" (clamped to 300–3600) | string |
certificateStoreLocation (optional) |
"/var/lib/waagent/Microsoft.Azure.KeyVault.Store" | string |
observedCertificates |
[{...}, {...}] | array |
observedCertificates/url |
"https://myvault.vault.azure.net/secrets/mycertificate" | string |
observedCertificates/certificateStoreLocation (optional) |
"/var/lib/waagent/Microsoft.Azure.KeyVault/app1" | string |
observedCertificates/acls (optional) |
[{"user": "app1", "group": "appGroup1"}] | object array |
observedCertificates/authenticationOverride (optional) |
{"msiClientId": "00001111-aaaa-2222-bbbb-3333cccc4444"} | object |
authenticationSettings/msiEndpoint |
"http://169.254.169.254/metadata/identity" | string |
authenticationSettings/msiClientId |
"00001111-aaaa-2222-bbbb-3333cccc4444" | string |
Note
The schema accepts certificateStoreName for compatibility but Linux ignores it. If you don't specify certificateStoreLocation for a certificate, the system uses the top-level secretsManagementSettings.certificateStoreLocation, and if that's not set, it uses the default /var/lib/waagent/Microsoft.Azure.KeyVault.Store/.
Template deployment
Deploy Azure VM extensions by using Azure Resource Manager (ARM) templates. Templates are ideal when you deploy one or more virtual machines that require post-deployment refresh of certificates. You can deploy the extension to individual VMs or Virtual Machine Scale Sets instances. The schema and configuration are common to both template types.
The JSON configuration for a key vault extension is nested inside the VM or Virtual Machine Scale Sets template. For a VM resource extension, the configuration is nested under the "resources": [] virtual machine object. For a Virtual Machine Scale Sets instance extension, the configuration is nested under the "virtualMachineProfile":"extensionProfile":{"extensions" :[] object.
The following JSON snippet provides example settings for an ARM template deployment of the Key Vault VM extension.
{
"type": "Microsoft.Compute/virtualMachines/extensions",
"name": "KeyVaultForLinux",
"apiVersion": "2025-04-01",
"location": "<location>",
"dependsOn": [
"[concat('Microsoft.Compute/virtualMachines/', <vmName>)]"
],
"properties": {
"publisher": "Microsoft.Azure.KeyVault",
"type": "KeyVaultForLinux",
"typeHandlerVersion": "4.0",
"autoUpgradeMinorVersion": true,
"enableAutomaticUpgrade": true,
"settings": {
"secretsManagementSettings": {
"pollingIntervalInS": "3600",
"certificateStoreLocation": "/var/lib/waagent/Microsoft.Azure.KeyVault.Store",
"observedCertificates": [
{
"url": "https://<examplekv>.vault.azure.net/secrets/mycertificate1",
"certificateStoreLocation": "/var/lib/waagent/Microsoft.Azure.KeyVault.Store",
"acls": [
{ "user": "app1", "group": "appGroup1" },
{ "user": "service1" }
]
},
{
"url": "https://<examplekv>.vault.azure.net/secrets/mycertificate2",
"certificateStoreLocation": "/var/lib/waagent/Microsoft.Azure.KeyVault.Store"
}
]
},
"authenticationSettings": {
"msiEndpoint": "http://169.254.169.254/metadata/identity",
"msiClientId": "00001111-aaaa-2222-bbbb-3333cccc4444"
}
}
}
}
Extension automatic upgrade
The Key Vault VM extension supports automatic extension upgrade for virtual machines and scale sets in Azure. Azure keeps the extension up to date automatically when you set the autoUpgradeMinorVersion and enableAutomaticUpgrade properties in the preceding examples to true.
Extension dependency ordering
The Key Vault VM extension supports extension dependency ordering. The extension reports a successful start after it downloads and installs all certificates.
If you use other extensions that require installation of certificates before they start, you can use extension dependency ordering to declare a dependency on the Key Vault VM extension.
On startup, the Key Vault VM extension retries download and install of certificates up to 25 times with increasing backoff periods, during which it remains in a Transitioning state. If the retries are exhausted, the extension reports an Error state. After all certificates are successfully installed, the Key Vault VM extension reports a successful start.
For more information about setting up dependencies between extensions, see Sequence extension provisioning in Virtual Machine Scale Sets.
Important
The extension dependency ordering feature isn't compatible with an ARM template that creates a system-assigned identity and updates a Key Vault access policy with that identity. If you attempt to use the feature in this scenario, a deadlock occurs because the Key Vault access policy can't update until after all extensions start. Instead, use a single user-assigned managed identity and grant that identity access to your key vaults before you deploy.
Azure PowerShell deployment
Deploy the Azure Key Vault VM extension by using Azure PowerShell. Save Key Vault VM extension settings to a JSON file (settings.json).
Warning
PowerShell clients often add \ before " in settings.json. This behavior causes akvvm_service to fail with the error [CertificateManagementConfiguration] Failed to parse the configuration settings with:not an object.. Use the Azure CLI, or pass the settings as a raw string as shown in the following example.
The following JSON snippet provides example settings for deploying the Key Vault VM extension by using PowerShell.
{
"secretsManagementSettings": {
"pollingIntervalInS": "3600",
"observedCertificates": [
{
"url": "https://<examplekv>.vault.azure.net/secrets/mycertificate1",
"certificateStoreLocation": "/var/lib/waagent/Microsoft.Azure.KeyVault.Store",
"acls": [
{ "user": "app1", "group": "appGroup1" },
{ "user": "service1" }
]
},
{
"url": "https://<examplekv>.vault.azure.net/secrets/mycertificate2",
"certificateStoreLocation": "/var/lib/waagent/Microsoft.Azure.KeyVault.Store"
}
]
},
"authenticationSettings": {
"msiEndpoint": "http://169.254.169.254/metadata/identity",
"msiClientId": "00001111-aaaa-2222-bbbb-3333cccc4444"
}
}
Deploy on a VM
# Build settings
$settings = (Get-Content -Raw ".\settings.json")
$extName = "KeyVaultForLinux"
$extPublisher = "Microsoft.Azure.KeyVault"
$extType = "KeyVaultForLinux"
# Start the deployment
Set-AzVmExtension -TypeHandlerVersion "4.0" -ResourceGroupName <ResourceGroupName> -Location <Location> -VMName <VMName> -Name $extName -Publisher $extPublisher -Type $extType -SettingString $settings
Deploy on a Virtual Machine Scale Sets instance
# Build settings
$settings = (Get-Content -Raw ".\settings.json")
$extName = "KeyVaultForLinux"
$extPublisher = "Microsoft.Azure.KeyVault"
$extType = "KeyVaultForLinux"
# Add extension to Virtual Machine Scale Sets
$vmss = Get-AzVmss -ResourceGroupName <ResourceGroupName> -VMScaleSetName <VmssName>
Add-AzVmssExtension -VirtualMachineScaleSet $vmss -Name $extName -Publisher $extPublisher -Type $extType -TypeHandlerVersion "4.0" -Setting $settings
# Start the deployment
Update-AzVmss -ResourceGroupName <ResourceGroupName> -VMScaleSetName <VmssName> -VirtualMachineScaleSet $vmss
Azure CLI deployment
Deploy the Azure Key Vault VM extension by using the Azure CLI. Save Key Vault VM extension settings to a JSON file (settings.json).
The following JSON snippet provides example settings for deploying the Key Vault VM extension by using the Azure CLI.
{
"secretsManagementSettings": {
"pollingIntervalInS": "3600",
"observedCertificates": [
{
"url": "https://<examplekv>.vault.azure.net/secrets/mycertificate1",
"certificateStoreLocation": "/var/lib/waagent/Microsoft.Azure.KeyVault.Store",
"acls": [
{ "user": "app1", "group": "appGroup1" },
{ "user": "service1" }
]
},
{
"url": "https://<examplekv>.vault.azure.net/secrets/mycertificate2",
"certificateStoreLocation": "/var/lib/waagent/Microsoft.Azure.KeyVault.Store"
}
]
},
"authenticationSettings": {
"msiEndpoint": "http://169.254.169.254/metadata/identity",
"msiClientId": "00001111-aaaa-2222-bbbb-3333cccc4444"
}
}
Deploy on a VM
# Start the deployment
az vm extension set --name "KeyVaultForLinux" \
--publisher Microsoft.Azure.KeyVault \
--resource-group "<resourcegroup>" \
--vm-name "<vmName>" \
--version "4.0" \
--enable-auto-upgrade true \
--settings "@settings.json"
Deploy on a Virtual Machine Scale Sets instance
# Start the deployment
az vmss extension set --name "KeyVaultForLinux" \
--publisher Microsoft.Azure.KeyVault \
--resource-group "<resourcegroup>" \
--vmss-name "<vmssName>" \
--version "4.0" \
--enable-auto-upgrade true \
--settings "@settings.json"
Tip
If the extension deployment fails, you might need to delete the existing extension before reinstalling with the correct version. Azure doesn't allow extension downgrades, so you might need to remove the faulty extension first:
az vm extension delete --name "KeyVaultForLinux" --resource-group "<resourcegroup>" --vm-name "<vmName>"
Logging with Fluentd
The Key Vault VM extension can forward its logs to a Fluentd log collector. Make sure your log collector is running and listening at the endpoint you specify in the settings.
Add the following section to your extension settings:
"loggingSettings": {
"logger": "fluentd",
"endpoint": "unix:///var/run/azuremonitoragent/sometenant/default_fluent.socket",
"format": "forward",
"servicename": "akvvm_service"
}
| Name | Value/Example | Data type |
|---|---|---|
loggingSettings/logger |
"fluentd" | string |
loggingSettings/endpoint |
"unix:///var/run/azuremonitoragent/sometenant/default_fluent.socket" or "tcp://localhost:24224" | string |
loggingSettings/format |
"forward" | string |
loggingSettings/servicename |
"akvvm_service" | string |
Troubleshoot problems
Use these suggestions to troubleshoot deployment problems.
Check frequently asked questions
Is there a limit on the number of observed certificates?
No. The Key Vault VM extension doesn't limit the number of observed certificates (observedCertificates).
What is the default location where certificates are installed?
If you don't specify certificateStoreLocation, the extension writes certificates to /var/lib/waagent/Microsoft.Azure.KeyVault.Store/.
How do I force the extension to pull a new certificate?
Restart the akvvm_service service (display name Key Vault VM Extension).
How do I use a different identity for a specific certificate?
Add an authenticationOverride object with the target msiClientId to that certificate's entry in observedCertificates. Certificates without an override use the top-level authenticationSettings.
View extension status
Check the status of your extension deployment in the Azure portal, or by using PowerShell or the Azure CLI.
To see the deployment state of extensions for a given VM, run the following commands.
Azure PowerShell:
Get-AzVMExtension -ResourceGroupName <myResourceGroup> -VMName <myVM> -Name <myExtensionName>The Azure CLI:
az vm get-instance-view --resource-group <myResourceGroup> --name <myVM> --query "instanceView.extensions"
The Azure CLI can run in several shell environments, but with slight format variations. If you have unexpected results with Azure CLI commands, see How to use the Azure CLI successfully.
Review logs and configuration
The Key Vault VM extension logs exist only locally on the VM. Review the log details to help with troubleshooting.
| Log file | Description |
|---|---|
/var/log/waagent.log |
Shows when updates occur to the extension. |
/var/log/azure/Microsoft.Azure.KeyVault.KeyVaultForLinux/* |
Shows the status of the akvvm_service service and certificate download. The PEM file download location appears in entries named certificate file name. |
/var/lib/waagent/Microsoft.Azure.KeyVault.KeyVaultForLinux-<most recent version>/config/* |
The configuration and binaries for the Key Vault VM extension service. |
Certificate installation on Linux
The Key Vault VM extension for Linux installs certificates as PEM files. When the extension downloads a certificate from Key Vault, it:
- Creates a storage folder based on the
certificateStoreLocationsetting. If you don't specify this setting, the location defaults to/var/lib/waagent/Microsoft.Azure.KeyVault.Store/. - Writes the certificate chain (leaf, then intermediates, then root if present in Key Vault) to a versioned full-chain
.pemfile, and writes the corresponding private key to a versioned.keyidfile. - Applies POSIX ACLs to the private key based on the
aclsspecified in the configuration, which grants read access to the listed users and groups. Files are otherwise owner-only. - Creates or updates a stable symbolic link (
<vaultname>.<certname>.pemand<vaultname>.<certname>.keyid) that points to the latest version of the certificate. Linking always occurs.
Default certificate store location
If you don't specify a location, the extension installs certificates under /var/lib/waagent/Microsoft.Azure.KeyVault.Store/. The extension ignores certificateStoreName on Linux.
Certificate output files
For vault mykv and secret server-tls, a successful sync produces:
/var/lib/waagent/Microsoft.Azure.KeyVault.Store/
├── mykv.server-tls.pem -> mykv.server-tls.<version>.pem.<timestamp> # symlink to latest full chain
├── mykv.server-tls.keyid -> mykv.server-tls.<version>.keyid.<timestamp> # symlink to latest private key
├── mykv.server-tls.<version>.pem.<timestamp> # full chain PEM (mode 600)
├── mykv.server-tls.<version>.keyid.<timestamp> # private key (mode 600)
└── mykv.server-tls.luma # certificate management metadata (mode 644)
Configure applications to reference the stable symbolic link path (for example, /var/lib/waagent/Microsoft.Azure.KeyVault.Store/mykv.server-tls.pem) so they always read the most current certificate version without reconfiguration on renewal.
Certificate access control
By default, certificate and private key files are readable only by their owner. Grant read access to additional users and groups by using the acls array in the certificate configuration:
"acls": [
{ "user": "app1", "group": "appGroup1" },
{ "user": "service1" }
]
Each entry can specify a user, a group, or both. ACL enforcement is always enabled and currently grants read access.
Certificate renewal
When certificates are renewed in Key Vault, the extension automatically performs the following actions on the next poll:
- Downloads the new certificate version.
- Writes the new versioned
.pemand.keyidfiles. - Updates the stable symbolic link to point to the new version so existing application paths continue to resolve to the latest certificate.
Get support
Microsoft provides support only for major version 3.0 and later of the Key Vault VM extension. If you're using version 1.0, upgrade to the latest version before requesting support.
Use these other options to help resolve deployment problems:
For assistance, contact the Azure experts in Microsoft Q&A.
If you don't find an answer on the site, you can post a question for input from Microsoft or other members of the community.
You can also Contact Microsoft Support. For information about using Azure support, see How to create an Azure support request.