Overview
The Azure secrets engine in HashiCorp Vault enables dynamic creation of Azure service principals, along with role and group assignments, and ties their lifecycle to Vault leases. In this setup, Vault must authenticate to Azure using static credentials (like a client ID and secret), which requires careful handling, storage, and rotation of sensitive information.
Workload Identity Federation (WIF) enhances this flow by removing the need for static credentials entirely. With WIF, Vault acts as an identity provider, issuing internally signed plugin identity tokens (JWTs). When a trust relationship is established between Vault and Azure, Vault can exchange these tokens for short-lived Azure access tokens, allowing the Azure secrets engine to perform actions securely.
Prerequisites
An HTTPS-enabled Vault cluster using a certificate from a public Certificate Authority (CA) trusted by Azure. Azure supports WIF only with OIDC issuers that use publicly trusted CAs. A list of such supported CAs is available here.
An Azure subscription with sufficient permissions to create App Registrations and manage API permissions.
Vault CLI access and administrative privileges.
Configuration Steps
-
Create an App Registration in Azure
- Navigate to: Azure Portal → App registrations → New registration
Provide a name and complete the registration
-
Assign API Permissions
Open the App Registration
- Go to Manage → API permissions
- Select Add a permission → Microsoft Graph
- Add the required permissions as shown in the reference screenshot
-
Click "Grant admin consent for Default Directory"
-
Enable the Azure Secrets Engine in Vault
$ vault secrets enable azure Success! Enabled the azure secrets engine at: azure/
-
Retrieve the OIDC Issuer detail from Vault OIDC Plugin
$ vault read identity/oidc/plugins/.well-known/openid-configuration Key Value --- ----- id_token_signing_alg_values_supported [RS256 RS384 RS512 ES256 ES384 ES512 EdDSA] issuer https://my-new-vault.test.aws.sbx.hashicorpdemo.com:8200/v1/identity/oidc/plugins jwks_uri https://my-new-vault.test.aws.sbx.hashicorpdemo.com:8200/v1/identity/oidc/plugins/.well-known/keys response_types_supported [id_token] subject_types_supported [public]
-
Set the OIDC Issuer Config
$ vault write -f identity/oidc/config issuer=https://my-new-vault.test.aws.sbx.hashicorpdemo.com:8200
Use the
issuer
value retrieved in the previous step. -
Configure Federated Credentials in Azure
Navigate to App Registration → Certificates & Secrets → Federated Credentials
Click Add Credential
-
Set the following values:
Field
Value
Federated credential scenario Other issuer Issuer https://vault.example.com:8200/v1/identity/oidc/plugins
Value identity:<NAMESPACE_ID>:secret:<AZURE_MOUNT_ACCESSOR>
Audience api://AzureADTokenExchange
Issuer value can be retrieved from the well known openid configuration in Step 4.
NAMESPACE_ID can be retrieved using:
$ vault namespace list -detailed
AZURE_MOUNT_ACCESSOR can be retrieved using the below output for the azure mount:
$ vault secrets list
Reference screenshot:
-
Create Azure secret engine config for WIF
$ vault write azure/config \ subscription_id=$AZURE_SUBSCRIPTION_ID \ tenant_id=$AZURE_TENANT_ID \ client_id=$AZURE_CLIENT_ID \ identity_token_audience="api://AzureADTokenExchange" and client_id are available from the App Registration overview
tenant_id and client_id are available from the App Registration overview page
subscription_id is available from the Azure portal under the Subscriptions
-
Create a role for this Azure config
$ vault write azure/roles/my-role \ application_object_id=<existing_app_obj_id> \ ttl=1h
application_object_id is located in the App Registration overview page
-
Verify Credential Generation
$ vault read azure/creds/my-role Key Value --- ----- lease_id azure/creds/my-role/dLZDUCW0GxqIR7n3us63WAzv lease_duration 1h lease_renewable true client_id 99e21143-509a-44c0-9ef3-44be01bfef4b client_secret 6Y48Q~vk7q.C8QrOEtSiPrHBhe_8ywcUF1hhqa~V
Once the setup is complete and trust is established, Vault is able to dynamically generate Azure credentials via Workload Identity Federation, without storing static secrets.