Vault
Sync secrets from Vault to Azure Key Vault
The Azure Key Vault destination enables Vault to sync and unsync secrets of your choosing into an external Azure account. When configured, Vault will actively maintain the state of each externally-synced secret in realtime. This includes sending new secrets, updating existing secret values, and removing secrets when they either get dissociated from the destination or deleted from Vault.
Prerequisites:
- Ability to read or create KVv2 secrets
- Ability to create Azure AD user credentials with access to an Azure Key Vault, or configure workload identity federation (WIF)
- Ability to create sync destinations and associations on your Vault server
Setup
If you do not already have an Azure Key Vault instance, navigate to the Azure Portal to create a new Key Vault.
Configure authentication credentials for Azure Key Vault. You can use one of the following methods:
Client secret authentication: Follow Azure instructions to create a service principal the use the service principle with a client ID and client secret.
Workload identity federation (WIF): Configure a trust relationship between Vault and Azure. Use WIF to eliminate the need to manage long-lived client secrets.
Managed identity: If you run Vault on Azure infrastructure, use Azure managed identity to infer authentication from the environment with minimal configuration.
Once the service principal is created, the next step is to grant the service principal access to Azure Key Vault. To quickly get started, we recommend using the "Key Vault Secrets Officer" built-in role, which gives sufficient access to manage secrets. For more information, see the Permissions section.
Configure a sync destination with the Key Vault URI and authentication credentials.
Client secret authentication:
$ vault write sys/sync/destinations/azure-kv/my-azure-1 \ key_vault_uri="$KEY_VAULT_URI" \ client_id="$CLIENT_ID" \ client_secret="$CLIENT_SECRET" \ tenant_id="$TENANT_ID"Output:
Key Value --- ----- connection_details map[client_id:uuid client_secret:***** identity_token_audience:***** identity_token_ttl:***** key_vault_uri:https://keyvault-1234abcd.vault.azure.net tenant_id:uuid] name my-azure-1 options map[custom_tags:map[] granularity_level:secret-path secret_name_template:vault-{{ .MountAccessor | replace "_" "-" }}-{{ .SecretPath }}] type azure-kvWorkload identity federation (WIF) authentication:
$ vault write sys/sync/destinations/azure-kv/my-azure-1 \ key_vault_uri="$KEY_VAULT_URI" \ client_id="$CLIENT_ID" \ tenant_id="$TENANT_ID" \ identity_token_audience="api://AzureADTokenExchange" \ identity_token_ttl="1h"Output:
Key Value --- ----- connection_details map[client_id:uuid identity_token_audience:***** identity_token_ttl:***** key_vault_uri:https://keyvault-1234abcd.vault.azure.net tenant_id:uuid] name my-azure-1 options map[custom_tags:map[] granularity_level:secret-path secret_name_template:vault-{{ .MountAccessor | replace "_" "-" }}-{{ .SecretPath }}] type azure-kv
Usage
If you do not already have a KVv2 secret to sync, mount a new KVv2 secrets engine.
$ vault secrets enable -path='my-kv' kv-v2Output:
Success! Enabled the kv-v2 secrets engine at: my-kv/Create secrets you wish to sync with a target Azure Key Vault.
$ vault kv put -mount='my-kv' my-secret foo='bar'Output:
==== Secret Path ==== my-kv/data/my-secret ======= Metadata ======= Key Value --- ----- created_time 2023-09-19T13:17:23.395109Z custom_metadata <nil> deletion_time n/a destroyed false version 1Create an association between the destination and a secret to synchronize.
$ vault write sys/sync/destinations/azure-kv/my-azure-1/associations/set \ mount='my-kv' \ secret_name='my-secret'Output:
Key Value --- ----- associated_secrets map[kv_7532a8b4/my-secret:map[accessor:kv_7532a8b4 secret_name:my-secret sync_status:SYNCED updated_at:2023-09-21T13:53:24.839885-07:00]] store_name my-azure-1 store_type azure-kvNavigate to Azure Key Vault in the Azure portal to confirm your secret was successfully created.
Moving forward, any modification on the Vault secret will be propagated in near real time to its Azure Key Vault counterpart. Creating a new secret version in Vault will create a new version in Azure Key Vault. Deleting the secret or the association in Vault will delete the secret in your Azure Key Vault as well.
Workload identity federation (WIF)
Workload identity federation (WIF) lets the Azure Key Vault sync destination authenticate to Azure by having Vault exchange short-lived identity tokens for Azure access tokens instead of managing long-lived client secrets.
To configure WIF for Azure Key Vault sync:
Ensure that Vault openid-configuration and public JWKS APIs are network-reachable by Azure. We recommend using an API proxy or gateway if you need to limit Vault API exposure.
Configure a federated identity credential on a dedicated application registration in Azure to establish a trust relationship with Vault.
The issuer URL must point at your Vault identity token issuer with the
/.well-known/openid-configurationsuffix removed. For example:https://host:port/v1/identity/oidc/secrets-sync.The subject identifier must match the unique
subclaim issued by identity tokens and have the formsecrets-sync:<NAMESPACE_PATH>:<STORE_TYPE>:<STORE_NAME>.The audience should be under 600 characters. The default value in Azure is
api://AzureADTokenExchange.
Configure the Azure Key Vault sync destination with the subscription, client and tenant IDs and the OIDC audience value, as shown in the Setup section above.
By default, WIF credentials have a time-to-live of 1 hour and automatically refresh when they expire.
For more information about the WIF-related configuration parameters, refer to the API documentation.
Permissions
For a more minimal set of permissions, you can create a custom role using the following JSON role definition. Be sure to replace the subscription ID placeholder.
{
"properties": {
"roleName": "Key Vault Secrets Reader Writer",
"description": "Custom role for reading and updating Azure Key Vault secrets.",
"permissions": [
{
"actions": [
"Microsoft.KeyVault/vaults/secrets/read",
"Microsoft.KeyVault/vaults/secrets/write"
],
"notActions": [],
"dataActions": [
"Microsoft.KeyVault/vaults/secrets/delete",
"Microsoft.KeyVault/vaults/secrets/backup/action",
"Microsoft.KeyVault/vaults/secrets/purge/action",
"Microsoft.KeyVault/vaults/secrets/recover/action",
"Microsoft.KeyVault/vaults/secrets/restore/action",
"Microsoft.KeyVault/vaults/secrets/readMetadata/action",
"Microsoft.KeyVault/vaults/secrets/getSecret/action",
"Microsoft.KeyVault/vaults/secrets/setSecret/action"
],
"notDataActions": []
}
],
"assignableScopes": [
"/subscriptions/{subscriptionId}/"
]
}
}
Access management
You can allow or restrict access to secrets by using a separate Azure Key Vault instance for Vault sync destinations. This corresponds with Microsoft's currently-recommended best practices for managing secrets in Key Vault. Maintaining a boundary between Vault-managed secrets and other secrets through separate Key Vaults provides increased security and access control.
Azure roles can be created to grant the necessary permissions for the service principal to access the Key Vault with role-based access control. A role assignment can be set for the Vault user principal to provide it the role's permissions within the Key Vault instance, its resource group, or subscription. Additionally, Azure policies may further refine access control limitations, such as denying the Vault user principal access to non-Vault related Key Vaults. The inverse, denying other users any write-access to the Vault-related Key Vault, may be another choice.
API
Please see the secrets sync API for more details.