---
layout: docs
page_title: Azure - Auth Methods
description: |-
The azure auth method plugin allows automated authentication of Azure Active
Directory.
---
> [!IMPORTANT]
> **Documentation Update:** Product documentation, which were located in this repository under `/website`, are now located in [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs), colocated with all other product documentation. Contributions to this content should be done in the `web-unified-docs` repo, and not this one. Changes made to `/website` content in this repo will not be reflected on the developer.hashicorp.com website.
# Azure auth method
The `azure` auth method allows authentication against Vault using
Azure Active Directory credentials. It treats Azure as a Trusted Third Party
and expects a [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519)
signed by Azure Active Directory for the configured tenant.
This method supports authentication for system-assigned and user-assigned
managed identities. See [Managed identities for Azure resources](https://learn.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview)
for more information about these resources.
This documentation assumes the Azure method is mounted at the `/auth/azure`
path in Vault. Since it is possible to enable auth methods at any location,
please update your API calls accordingly.
## Token validation ((#token-validation))
Vault validates the resource group (`resource_group_name`), VM name (`vm_name`)
and VM scale set name (`vmss_name`) parameters against token claims. Depending
on the identities attached to the machine generating the MSI token, the
associated claims must include at least one of the following claims
to pass validation: "xms_mirid" or "xms_az_rid".
System-assigned management identity | "xms_mirid" | "xms_az_rid"
----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------| ---------------
Enabled | `/subscriptions/{subscription-id}/resourcegroups/{resource-group-name}/providers/Microsoft.Compute/virtualMachines/{virtual-machine-name}` | Does not exist
Not enabled | `/subscriptions/{subscription-id}/resourcegroups/{resource-group-name}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{user-assigned-managed-identity}` |`/subscriptions/{subscription-id}/resourcegroups/{resource-group-name}/providers/Microsoft.Compute/virtualMachines/{virtual-machine-name}`
See [Azure managed identity REST endpoint reference](https://learn.microsoft.com/en-us/azure/app-service/overview-managed-identity?tabs=portal%2Chttp#rest-endpoint-reference) and
[Managed identities for Azure resources frequently asked questions](https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/managed-identities-faq#what-identity-will-imds-default-to-if-i-dont-specify-the-identity-in-the-request) for more details on how to request MSI tokens.
When Vault evaluates the token claims, it checks the validation parameter values
against the claim parameters:
- `{resource-group-name}` must match `resource_group_name`.
- `{virtual-machine-name}` must match `vm_name` or `{vmss_name}_{instance-id}` if `vmss_name` is provided.
If either check fails, the login also fails.
## Prerequisites
The Azure auth method requires client credentials to access Azure APIs. The following
are required to configure the auth method:
- A configured [Azure AD application](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-integrating-applications)
which is used as the resource for generating MSI access tokens.
- Client credentials (shared secret) with read access to particular Azure Resource Manager
resources. See [Azure AD Service to Service Client Credentials](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-oauth-service-to-service).
If Vault is hosted on Azure, Vault can use MSI to access Azure instead of a shared secret.
A managed identity must be [enabled](https://learn.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/)
on the resource that acquires the access token.
The following Azure [role assignments](https://learn.microsoft.com/en-us/azure/role-based-access-control/overview#role-assignments)
must be granted to the Azure AD application in order for the auth method to access Azure
APIs during authentication.
### Role assignments
~> **Note:** The role assignments are only required when the
[`vm_name`](/vault/api-docs/auth/azure#vm_name), [`vmss_name`](/vault/api-docs/auth/azure#vmss_name),
or [`resource_id`](/vault/api-docs/auth/azure#resource_id) parameters are used on login.
| Azure Environment | Login Parameter | Azure API Permission |
| ----------- | --------------- | -------------------- |
| Virtual Machine | [`vm_name`](/vault/api-docs/auth/azure#vm_name) | `Microsoft.Compute/virtualMachines/*/read` |
| Virtual Machine Scale Set ([Uniform Orchestration][vmss-uniform]) | [`vmss_name`](/vault/api-docs/auth/azure#vmss_name) | `Microsoft.Compute/virtualMachineScaleSets/*/read` |
| Virtual Machine Scale Set ([Flexible Orchestration][vmss-flex]) | [`vmss_name`](/vault/api-docs/auth/azure#vmss_name) | `Microsoft.Compute/virtualMachineScaleSets/*/read` `Microsoft.ManagedIdentity/userAssignedIdentities/*/read` |
| Services that ([support managed identities][managed-identities]) for Azure resources | [`resource_id`](/vault/api-docs/auth/azure#resource_id) | `read` on the resource used to obtain the JWT |
[vmss-uniform]: https://learn.microsoft.com/en-us/azure/virtual-machine-scale-sets/virtual-machine-scale-sets-orchestration-modes#scale-sets-with-uniform-orchestration
[vmss-flex]: https://learn.microsoft.com/en-us/azure/virtual-machine-scale-sets/virtual-machine-scale-sets-orchestration-modes#scale-sets-with-flexible-orchestration
[managed-identities]: https://learn.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/managed-identities-status
### API permissions
The following [API permissions](https://learn.microsoft.com/en-us/azure/active-directory/develop/permissions-consent-overview#types-of-permissions)
must be assigned to the service principal provided to Vault for managing the root rotation in Azure:
| Permission Name | Type |
| ----------------------------- | ----------- |
| Application.ReadWrite.All | Application |
## Authentication
### Via the CLI
The default path is `/auth/azure`. If this auth method was enabled at a different
path, specify `auth/my-path/login` instead.
```shell-session
$ vault write auth/azure/login \
role="dev-role" \
jwt="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
subscription_id="12345-..." \
resource_group_name="test-group" \
vm_name="test-vm"
```
The `role` and `jwt` parameters are required. The JWT must contain all role binding information (except for `vm_name`, `vmss_name`, and `resource_id`). When using additional `bound_*` parameters beyond `bound_service_principal_ids` or `bound_group_ids`, Azure API calls will be made and
`subscription_id`, `resource_group_name`, and `vm_name`/`vmss_name` are all required
and can be obtained through instance metadata.
For example:
```shell-session
$ vault write auth/azure/login role="dev-role" \
jwt="$(curl -s 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fmanagement.azure.com%2F' -H Metadata:true | jq -r '.access_token')" \
subscription_id=$(curl -s -H Metadata:true "http://169.254.169.254/metadata/instance?api-version=2017-08-01" | jq -r '.compute | .subscriptionId') \
resource_group_name=$(curl -s -H Metadata:true "http://169.254.169.254/metadata/instance?api-version=2017-08-01" | jq -r '.compute | .resourceGroupName') \
vm_name=$(curl -s -H Metadata:true "http://169.254.169.254/metadata/instance?api-version=2017-08-01" | jq -r '.compute | .name')
```
### Via the API
The default endpoint is `auth/azure/login`. If this auth method was enabled
at a different path, use that value instead of `azure`.
```shell-session
$ curl \
--request POST \
--data '{"role": "dev-role", "jwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}' \
https://127.0.0.1:8200/v1/auth/azure/login
```
The response will contain the token at `auth.client_token`:
```json
{
"auth": {
"client_token": "f33f8c72-924e-11f8-cb43-ac59d697597c",
"accessor": "0e9e354a-520f-df04-6867-ee81cae3d42d",
"policies": ["default", "dev", "prod"],
"lease_duration": 2764800,
"renewable": true
}
}
```
## Configuration
Auth methods must be configured in advance before machines can authenticate.
These steps are usually completed by an operator or configuration management
tool.
### Via the CLI
1. Enable Azure authentication in Vault:
```shell-session
$ vault auth enable azure
```
1. Configure the Azure auth method:
```shell-session
$ vault write auth/azure/config \
tenant_id=7cd1f227-ca67-4fc6-a1a4-9888ea7f388c \
resource=https://management.azure.com/ \
client_id=dd794de4-4c6c-40b3-a930-d84cd32e9699 \
client_secret=IT3B2XfZvWnfB98s1cie8EMe7zWg483Xy8zY004=
```
For the complete list of configuration options, please see the API
documentation.
In some cases, you cannot set sensitive account credentials in your
Vault configuration. For example, your organization may require that all
security credentials are short-lived or explicitly tied to a machine identity.
To provide managed identity security credentials to Vault, we recommend using Vault
[plugin workload identity federation](#plugin-workload-identity-federation-wif)
(WIF) as shown below.
1. Alternatively, configure the audience claim value and the Client, Tenant IDs for plugin workload identity federation:
```text
$ vault write azure/config \
tenant_id=7cd1f227-ca67-4fc6-a1a4-9888ea7f388c \
client_id=dd794de4-4c6c-40b3-a930-d84cd32e9699 \
identity_token_audience=vault.example/v1/identity/oidc/plugins
```
The Vault identity token provider signs the plugin identity token JWT internally.
If a trust relationship exists between Vault and Azure through WIF, the auth
method can exchange the Vault identity token for a federated access token.
To configure a trusted relationship between Vault and Azure:
- You must configure the [identity token issuer backend](/vault/api-docs/secret/identity/tokens#configure-the-identity-tokens-backend)
for Vault.
- Azure must have a
[federated identity credential](https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation-create-trust?pivots=identity-wif-apps-methods-azp#configure-a-federated-identity-credential-on-an-app)
configured with information about the fully qualified and network-reachable
issuer URL for the Vault plugin
[identity token provider](/vault/api-docs/secret/identity/tokens#read-plugin-identity-well-known-configurations).
Establishing a trusted relationship between Vault and Azure ensures that Azure
can fetch JWKS
[public keys](/vault/api-docs/secret/identity/tokens#read-active-public-keys)
and verify the plugin identity token signature.
1. Create a role:
```shell-session
$ vault write auth/azure/role/dev-role \
policies="prod,dev" \
bound_subscription_ids=6a1d5988-5917-4221-b224-904cd7e24a25 \
bound_resource_groups=vault \
bound_service_principal_ids=3cb88732-1356-4782-b671-4877166be01a
```
Roles are associated with an authentication type/entity and a set of Vault
policies. Roles are configured with constraints specific to the
authentication type, as well as overall constraints and configuration for
the generated auth tokens.
Note: Each role must specify either `bound_service_principal_ids` or `bound_group_ids` to restrict which Azure identities (service principals or group members) can authenticate to this role.
Here's an alternative example using `bound_group_ids`:
```shell-session
$ vault write auth/azure/role/prod-role \
policies="prod" \
bound_subscription_ids=6a1d5988-5917-4221-b224-904cd7e24a25 \
bound_resource_groups=vault \
bound_group_ids=12345678-1234-1234-1234-123456789012
```
For the complete list of role options, please see the [API documentation](/vault/api-docs/auth/azure).
### Via the API
1. Enable Azure authentication in Vault:
```shell-session
$ curl \
--header "X-Vault-Token: ..." \
--request POST \
--data '{"type": "azure"}' \
https://127.0.0.1:8200/v1/sys/auth/azure
```
1. Configure the Azure auth method:
```shell-session
$ curl \
--header "X-Vault-Token: ..." \
--request POST \
--data '{"tenant_id": "...", "resource": "..."}' \
https://127.0.0.1:8200/v1/auth/azure/config
```
1. Create a role:
```shell-session
$ curl \
--header "X-Vault-Token: ..." \
--request POST \
--data '{"policies": ["dev", "prod"], ...}' \
https://127.0.0.1:8200/v1/auth/azure/role/dev-role
```
## Root credential rotation
Mounts can rotate root credential keys configured directly within the mount.
Rotating to a Vault-generated key makes the key value inaccessible to the
operator and ensures only Vault can operate as a root user to manipulate dynamic
and static credentials.
```shell-session
vault write -f auth/azure/rotate-root
```
### Schedule-based root credential rotation
@include 'alerts/enterprise-only.mdx'
Use the [`rotation_schedule`](/vault/api-docs/auth/azure#rotation_schedule) field
to configure schedule-based, automatic credential rotation for root credentials in
the Azure auth engine. For example, the following command set the rotation to
occur every Saturday at midnight (00:00):
```shell-session
$ vault write auth/azure/config \
...
rotation_schedule="0 * * * SAT"
...
```
Scheduled root credential rotation can also set a
[rotation_window](/vault/api-docs/auth/azure#rotation_window) during which the
scheduled rotation is allowed to occur. Vault will stop trying to rotate the
credential once the window expires. For example, the following command tells
Vault to rotate the credential on Saturday at midnight, but only within the span
of an hour. If Vault cannot rotate the credential by 1:00, due to a failure
or otherwise, Vault will stop trying to rotate the credential until the next
scheduled rotation.
```shell-session
$ vault write auth/azure/config \
...
rotation_window="1h" \
rotation_schedule="0 * * * SAT"
...
```
You can temporarily disable root rotation by setting
[`disable_automated_rotation`](/vault/api-docs/auth/azure#disable_automated_rotation)
to `true`. Setting the `disable_automated_rotation` field prevent any rotation
of the root credential until the field is reset to `false`. If you use
`rotation_period`, setting `disable_automated_rotation` also resets the credential
TTL.
For more details on rotating root credentials in the Azure plugin, refer to the
[Root credential rotation](/vault/api-docs/auth/azure#rotate-root) API docs.
## Azure managed identities
There are two types of [managed identities](https://learn.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview#managed-identity-types)
in Azure: System-assigned and User-assigned. System-assigned identities are unique to
every virtual machine in Azure. If the resources using Azure auth are recreated
frequently, using system-assigned identities could result in many Vault entities being
created. For environments with high ephemeral workloads, user-assigned identities are
recommended.
### Limitations
The TTL of the access token returned by Azure AD for a managed identity is
24hrs and is not configurable. See ([limitations of using managed identities][id-limitations])
for more info.
[id-limitations]: https://learn.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/managed-identity-best-practice-recommendations#limitation-of-using-managed-identities-for-authorization
## Azure debug logs
The Azure auth plugin supports debug logging which includes additional information
about requests and responses from the Azure API.
To enable the Azure debug logs, set the following environment variable on the Vault
server:
```shell
AZURE_SDK_GO_LOGGING=all
```
## Plugin Workload Identity Federation (WIF)
The Azure auth method supports the plugin WIF workflow, and has a source of identity called
a plugin identity token. A plugin identity token is a JWT that is signed internally by Vault's
[plugin identity token issuer](/vault/api-docs/secret/identity/tokens#read-plugin-workload-identity-issuer-s-openid-configuration).
If there is a trust relationship configured between Vault and Azure through
[workload identity federation](https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation),
the auth method can exchange its identity token for short-lived access tokens needed to
perform its actions.
Exchanging identity tokens for access tokens lets the Azure auth method
operate without configuring explicit access to sensitive client credentials.
To configure the auth method to use plugin WIF:
1. Ensure that Vault [openid-configuration](/vault/api-docs/secret/identity/tokens#read-plugin-identity-token-issuer-s-openid-configuration)
and [public JWKS](/vault/api-docs/secret/identity/tokens#read-plugin-identity-token-issuer-s-public-jwks)
APIs are network-reachable by Azure. We recommend using an API proxy or gateway
if you need to limit Vault API exposure.
1. Configure a
[federated identity credential](https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation-create-trust?pivots=identity-wif-apps-methods-azp#configure-a-federated-identity-credential-on-an-app)
on a dedicated application registration in Azure to establish a trust relationship with Vault.
1. The issuer URL **must** point at your [Vault plugin identity token issuer](/vault/api-docs/secret/identity/tokens#read-plugin-workload-identity-issuer-s-openid-configuration) with the
`/.well-known/openid-configuration` suffix removed. For example:
`https://host:port/v1/identity/oidc/plugins`.
1. The subject identifier **must** match the unique `sub` claim issued by plugin identity tokens.
The subject identifier should have the form `plugin-identity::auth:`.
1. The audience should be under 600 characters. The default value in Azure is `api://AzureADTokenExchange`.
1. Configure the Azure auth method with the client and tenant IDs and the OIDC audience value.
```shell-session
$ vault write azure/config \
tenant_id=7cd1f227-ca67-4fc6-a1a4-9888ea7f388c \
client_id=dd794de4-4c6c-40b3-a930-d84cd32e9699 \
identity_token_audience=vault.example/v1/identity/oidc/plugins
```
Your auth method can now use plugin WIF for its configuration credentials.
By default, WIF [credentials](https://learn.microsoft.com/en-us/entra/identity-platform/access-tokens#token-lifetime)
have a time-to-live of 1 hour and automatically refresh when they expire.
Please see the [API documentation](/vault/api-docs/auth/azure#configure)
for more details on the fields associated with plugin WIF.
## Known issues and workarounds
### OIDC ID token error
Users have reported an
[issue](https://github.com/hashicorp/vault-plugin-auth-azure/issues/141#issuecomment-2757840078)
where workloads running inside AKS with Azure authentication on Vault servers
deployed to Azure VM throw following error:
**Error**
```plaintext
oidc: id token issued by a different provider, expected "https://sts.windows.net/TenantID/" got "https://login.microsoftonline.com/TenantId/v2.0"
```
The error occurs because the `vault-agent-init` container uses the `auth-type`
of `kubernetes`.
Reference:
[Vault Kubernetes auth type documentation](/vault/docs/platform/k8s/injector/annotations#vault-hashicorp-com-auth-type)
**Resolution:**
Explicitly define the Azure auth method using the
`vault.hashicorp.com/auth-type: 'azure'` annotation, and pass the mandatory
resource field `vault.hashicorp.com/auth-config-resource:
"https://management.azure.com/"` annotation.
**Annotations:**
```plaintext
...
annotations:
vault.hashicorp.com/auth-type: 'azure'
vault.hashicorp.com/auth-config-resource: "https://management.azure.com/"
...
```
**Reference:**
[Vault Kubernetes annotation documentation](/vault/docs/platform/k8s/injector/annotations#vault-hashicorp-com-auth-config)
[Vault agent auto auth documentation](/vault/docs/agent-and-proxy/autoauth/methods/azure#resource)
## API
The Azure Auth Plugin has a full HTTP API. Please see the [API
documentation](/vault/api-docs/auth/azure) for more details.
## Code example
The following example demonstrates the Azure auth method to authenticate
with Vault.
```go
package main
import (
"context"
"fmt"
vault "github.com/hashicorp/vault/api"
auth "github.com/hashicorp/vault/api/auth/azure"
)
// Fetches a key-value secret (kv-v2) after authenticating to Vault via Azure authentication.
// This example assumes you have a configured Azure AD Application.
func getSecretWithAzureAuth() (string, error) {
config := vault.DefaultConfig() // modify for more granular configuration
client, err := vault.NewClient(config)
if err != nil {
return "", fmt.Errorf("unable to initialize Vault client: %w", err)
}
azureAuth, err := auth.NewAzureAuth(
"dev-role-azure",
)
if err != nil {
return "", fmt.Errorf("unable to initialize Azure auth method: %w", err)
}
authInfo, err := client.Auth().Login(context.Background(), azureAuth)
if err != nil {
return "", fmt.Errorf("unable to login to Azure auth method: %w", err)
}
if authInfo == nil {
return "", fmt.Errorf("no auth info was returned after login")
}
// get secret from the default mount path for KV v2 in dev mode, "secret"
secret, err := client.KVv2("secret").Get(context.Background(), "creds")
if err != nil {
return "", fmt.Errorf("unable to read secret: %w", err)
}
// data map can contain more than one key-value pair,
// in this case we're just grabbing one of them
value, ok := secret.Data["password"].(string)
if !ok {
return "", fmt.Errorf("value type assertion failed: %T %#v", secret.Data["password"], secret.Data["password"])
}
return value, nil
}
```
```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Text;
using Newtonsoft.Json;
using VaultSharp;
using VaultSharp.V1.AuthMethods;
using VaultSharp.V1.AuthMethods.Azure;
using VaultSharp.V1.Commons;
namespace Examples
{
public class AzureAuthExample
{
public class InstanceMetadata
{
public string name { get; set; }
public string resourceGroupName { get; set; }
public string subscriptionId { get; set; }
}
const string MetadataEndPoint = "http://169.254.169.254/metadata/instance?api-version=2017-08-01";
const string AccessTokenEndPoint = "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/";
///
/// Fetches a key-value secret (kv-v2) after authenticating to Vault via Azure authentication.
/// This example assumes you have a configured Azure AD Application.
///
public string GetSecretWithAzureAuth()
{
string vaultAddr = Environment.GetEnvironmentVariable("VAULT_ADDR");
if(String.IsNullOrEmpty(vaultAddr))
{
throw new System.ArgumentNullException("Vault Address");
}
string roleName = Environment.GetEnvironmentVariable("VAULT_ROLE");
if(String.IsNullOrEmpty(roleName))
{
throw new System.ArgumentNullException("Vault Role Name");
}
string jwt = GetJWT();
InstanceMetadata metadata = GetMetadata();
IAuthMethodInfo authMethod = new AzureAuthMethodInfo(roleName: roleName, jwt: jwt, subscriptionId: metadata.subscriptionId, resourceGroupName: metadata.resourceGroupName, virtualMachineName: metadata.name);
var vaultClientSettings = new VaultClientSettings(vaultAddr, authMethod);
IVaultClient vaultClient = new VaultClient(vaultClientSettings);
// We can retrieve the secret from the VaultClient object
Secret kv2Secret = null;
kv2Secret = vaultClient.V1.Secrets.KeyValue.V2.ReadSecretAsync(path: "/creds").Result;
var password = kv2Secret.Data.Data["password"];
return password.ToString();
}
///
/// Query Azure Resource Manage for metadata about the Azure instance
///
private InstanceMetadata GetMetadata()
{
HttpWebRequest metadataRequest = (HttpWebRequest)WebRequest.Create(MetadataEndPoint);
metadataRequest.Headers["Metadata"] = "true";
metadataRequest.Method = "GET";
HttpWebResponse metadataResponse = (HttpWebResponse)metadataRequest.GetResponse();
StreamReader streamResponse = new StreamReader(metadataResponse.GetResponseStream());
string stringResponse = streamResponse.ReadToEnd();
var resultsDict = JsonConvert.DeserializeObject>(stringResponse);
return resultsDict["compute"];
}
///
/// Query Azure Resource Manager (ARM) for an access token
///
private string GetJWT()
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(AccessTokenEndPoint);
request.Headers["Metadata"] = "true";
request.Method = "GET";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
// Pipe response Stream to a StreamReader and extract access token
StreamReader streamResponse = new StreamReader(response.GetResponseStream());
string stringResponse = streamResponse.ReadToEnd();
var resultsDict = JsonConvert.DeserializeObject>(stringResponse);
return resultsDict["access_token"];
}
}
}
```