2018-03-22 22:28:42 +00:00
---
2020-01-18 00:18:09 +00:00
layout: docs
page_title: Azure - Auth Methods
2018-03-22 22:28:42 +00:00
description: |-
The azure auth method plugin allows automated authentication of Azure Active
Directory.
---
2023-07-18 21:07:55 +00:00
# Azure auth method
2018-03-22 22:28:42 +00:00
The `azure` auth method allows authentication against Vault using
2020-01-18 00:18:09 +00:00
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)
2018-03-22 22:28:42 +00:00
signed by Azure Active Directory for the configured tenant.
2020-05-08 23:20:08 +00:00
This method supports authentication for system-assigned and user-assigned
2022-12-16 15:40:59 +00:00
managed identities. See [Managed identities for Azure resources](https://learn.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview)
2022-10-20 19:36:29 +00:00
for more information about these resources.
2018-03-22 22:28:42 +00:00
2022-10-20 19:36:29 +00:00
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.
2022-02-11 22:09:35 +00:00
2018-03-22 22:28:42 +00:00
## Prerequisites:
2022-10-20 19:36:29 +00:00
The Azure auth method requires client credentials to access Azure APIs. The following
are required to configure the auth method:
2018-03-22 22:28:42 +00:00
2022-10-20 19:36:29 +00:00
- 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).
2018-03-22 22:28:42 +00:00
2022-10-20 19:36:29 +00:00
If Vault is hosted on Azure, Vault can use MSI to access Azure instead of a shared secret.
2022-12-16 15:40:59 +00:00
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.
2018-07-19 14:36:09 +00:00
2022-10-20 19:36:29 +00:00
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.
2018-07-19 14:24:55 +00:00
2023-07-18 21:07:55 +00:00
### Role assignments
2023-02-09 01:14:28 +00:00
2022-10-20 19:36:29 +00:00
~> **Note:** The role assignments are only required when the
2023-01-26 00:12:15 +00:00
[`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.
2020-11-09 19:49:03 +00:00
2022-10-20 19:36:29 +00:00
| Azure Environment | Login Parameter | Azure API Permission |
| ----------- | --------------- | -------------------- |
2023-01-26 00:12:15 +00:00
| 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 |
2018-03-22 22:28:42 +00:00
2022-10-20 19:36:29 +00:00
[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
2022-12-16 15:40:59 +00:00
[managed-identities]: https://learn.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/managed-identities-status
2018-03-22 22:28:42 +00:00
2023-07-18 21:07:55 +00:00
### API permissions
2023-02-09 01:14:28 +00:00
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 |
2018-03-22 22:28:42 +00:00
## 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.
2020-05-21 17:18:17 +00:00
```shell-session
2018-03-22 22:28:42 +00:00
$ vault write auth/azure/login \
role="dev-role" \
jwt="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
subscription_id="12345-..." \
resource_group_name="test-group" \
vm_name="test-vm"
```
2022-12-16 15:40:59 +00:00
The `role` and `jwt` parameters are required. When using
`bound_service_principal_ids` and `bound_group_ids` in the token roles, all the
information is required in the JWT (except for `vm_name`, `vmss_name`, `resource_id`). When
using other `bound_*` parameters, calls to Azure APIs will be made and
`subscription_id`, `resource_group_name`, and `vm_name`/`vmss_name` are all required
and can be obtained through instance metadata.
2018-03-22 22:28:42 +00:00
2019-01-30 20:13:39 +00:00
For example:
2020-05-21 17:18:17 +00:00
```shell-session
2019-01-30 20:13:39 +00:00
$ vault write auth/azure/login role="dev-role" \
2022-01-13 18:41:40 +00:00
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')" \
2019-01-30 20:13:39 +00:00
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')
```
2018-03-22 22:28:42 +00:00
### 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`.
2020-05-21 17:18:17 +00:00
```shell-session
2018-03-22 22:28:42 +00:00
$ curl \
--request POST \
--data '{"role": "dev-role", "jwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}' \
2018-04-27 15:47:06 +00:00
https://127.0.0.1:8200/v1/auth/azure/login
2018-03-22 22:28:42 +00:00
```
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",
2020-01-18 00:18:09 +00:00
"policies": ["default", "dev", "prod"],
2018-03-22 22:28:42 +00:00
"lease_duration": 2764800,
"renewable": true
}
}
```
## Configuration
Auth methods must be configured in advance before machines can authenticate.
2020-01-18 00:18:09 +00:00
These steps are usually completed by an operator or configuration management
2018-03-22 22:28:42 +00:00
tool.
### Via the CLI
1. Enable Azure authentication in Vault:
2022-12-16 15:40:59 +00:00
```shell-session
2020-01-18 00:18:09 +00:00
$ vault auth enable azure
```
2018-03-22 22:28:42 +00:00
1. Configure the Azure auth method:
2022-12-16 15:40:59 +00:00
```shell-session
2020-01-18 00:18:09 +00:00
$ vault write auth/azure/config \
tenant_id=7cd1f227-ca67-4fc6-a1a4-9888ea7f388c \
2022-01-13 18:41:40 +00:00
resource=https://management.azure.com/ \
2020-01-18 00:18:09 +00:00
client_id=dd794de4-4c6c-40b3-a930-d84cd32e9699 \
client_secret=IT3B2XfZvWnfB98s1cie8EMe7zWg483Xy8zY004=
```
2018-03-22 22:28:42 +00:00
2020-01-18 00:18:09 +00:00
For the complete list of configuration options, please see the API
documentation.
2018-03-22 22:28:42 +00:00
1. Create a role:
2022-12-16 15:40:59 +00:00
```shell-session
2020-01-18 00:18:09 +00:00
$ vault write auth/azure/role/dev-role \
policies="prod,dev" \
bound_subscription_ids=6a1d5988-5917-4221-b224-904cd7e24a25 \
bound_resource_groups=vault
```
2018-03-22 22:28:42 +00:00
2020-01-18 00:18:09 +00:00
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.
2018-03-22 22:28:42 +00:00
2023-01-26 00:12:15 +00:00
For the complete list of role options, please see the [API documentation](/vault/api-docs/auth/azure).
2018-03-22 22:28:42 +00:00
### Via the API
1. Enable Azure authentication in Vault:
2022-12-16 15:40:59 +00:00
```shell-session
2020-01-18 00:18:09 +00:00
$ curl \
--header "X-Vault-Token: ..." \
--request POST \
--data '{"type": "azure"}' \
https://127.0.0.1:8200/v1/sys/auth/azure
```
2018-03-22 22:28:42 +00:00
1. Configure the Azure auth method:
2022-12-16 15:40:59 +00:00
```shell-session
2020-01-18 00:18:09 +00:00
$ curl \
--header "X-Vault-Token: ..." \
--request POST \
--data '{"tenant_id": "...", "resource": "..."}' \
https://127.0.0.1:8200/v1/auth/azure/config
```
2018-03-22 22:28:42 +00:00
1. Create a role:
2022-12-16 15:40:59 +00:00
```shell-session
2020-01-18 00:18:09 +00:00
$ curl \
--header "X-Vault-Token: ..." \
--request POST \
--data '{"policies": ["dev", "prod"], ...}' \
https://127.0.0.1:8200/v1/auth/azure/role/dev-role
```
2018-03-22 22:28:42 +00:00
2023-07-18 21:07:55 +00:00
## Azure managed identities
2018-03-22 22:28:42 +00:00
2022-10-20 19:36:29 +00:00
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
2022-12-16 15:40:59 +00:00
every virtual machine in Azure. If the resources using Azure auth are recreated
2022-10-20 19:36:29 +00:00
frequently, using system-assigned identities could result in many Vault entities being
created. For environments with high ephemeral workloads, user-assigned identities are
recommended.
2018-03-22 22:28:42 +00:00
2022-12-16 15:40:59 +00:00
### 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
2023-07-18 21:07:55 +00:00
## Azure debug logs
2021-12-13 19:16:45 +00:00
2022-01-07 16:33:53 +00:00
The Azure auth plugin supports debug logging which includes additional information
2021-12-13 19:16:45 +00:00
about requests and responses from the Azure API.
To enable the Azure debug logs, set the following environment variable on the Vault
server:
```shell
2022-01-07 16:33:53 +00:00
AZURE_GO_SDK_LOG_LEVEL=DEBUG
2021-12-13 19:16:45 +00:00
```
2018-03-22 22:28:42 +00:00
## API
2023-01-26 00:12:15 +00:00
The Azure Auth Plugin has a full HTTP API. Please see the [API documentation](/vault/api-docs/auth/azure) for more details.
2021-11-03 17:10:28 +00:00
2023-07-18 21:07:55 +00:00
## Code example
2021-11-03 17:10:28 +00:00
2022-04-26 21:12:52 +00:00
The following example demonstrates the Azure auth method to authenticate
2021-11-03 17:10:28 +00:00
with Vault.
2022-04-26 21:12:52 +00:00
<CodeTabs>
2021-11-03 17:10:28 +00:00
2022-04-26 21:12:52 +00:00
<CodeBlockConfig>
2021-11-03 17:10:28 +00:00
```go
package main
import (
2021-11-17 19:52:38 +00:00
"context"
2021-11-03 17:10:28 +00:00
"fmt"
vault "github.com/hashicorp/vault/api"
2022-07-12 19:06:44 +00:00
auth "github.com/hashicorp/vault/api/auth/azure"
2021-11-03 17:10:28 +00:00
)
// 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) {
2021-11-17 19:52:38 +00:00
config := vault.DefaultConfig() // modify for more granular configuration
2021-11-03 17:10:28 +00:00
2021-11-17 19:52:38 +00:00
client, err := vault.NewClient(config)
if err != nil {
return "", fmt.Errorf("unable to initialize Vault client: %w", err)
}
2021-11-03 17:10:28 +00:00
2021-11-17 19:52:38 +00:00
azureAuth, err := auth.NewAzureAuth(
"dev-role-azure",
)
if err != nil {
return "", fmt.Errorf("unable to initialize Azure auth method: %w", err)
}
2021-11-03 17:10:28 +00:00
2022-06-09 00:37:02 +00:00
authInfo, err := client.Auth().Login(context.Background(), azureAuth)
2021-11-17 19:52:38 +00:00
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")
}
2021-11-03 17:10:28 +00:00
2022-06-09 00:37:02 +00:00
// get secret from the default mount path for KV v2 in dev mode, "secret"
secret, err := client.KVv2("secret").Get(context.Background(), "creds")
2021-11-17 19:52:38 +00:00
if err != nil {
return "", fmt.Errorf("unable to read secret: %w", err)
}
2021-11-03 17:10:28 +00:00
2021-11-17 19:52:38 +00:00
// data map can contain more than one key-value pair,
// in this case we're just grabbing one of them
2022-06-09 00:37:02 +00:00
value, ok := secret.Data["password"].(string)
2021-11-17 19:52:38 +00:00
if !ok {
2022-06-09 00:37:02 +00:00
return "", fmt.Errorf("value type assertion failed: %T %#v", secret.Data["password"], secret.Data["password"])
2021-11-17 19:52:38 +00:00
}
2021-11-03 17:10:28 +00:00
2021-11-17 19:52:38 +00:00
return value, nil
2021-11-03 17:10:28 +00:00
}
2021-12-22 17:33:12 +00:00
2021-11-03 17:10:28 +00:00
```
</CodeBlockConfig>
2022-04-26 21:12:52 +00:00
<CodeBlockConfig>
2021-11-03 17:10:28 +00:00
```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
{
2022-01-07 16:33:53 +00:00
public class AzureAuthExample
2021-11-03 17:10:28 +00:00
{
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/";
2022-01-07 16:33:53 +00:00
/// <summary>
2021-11-03 17:10:28 +00:00
/// Fetches a key-value secret (kv-v2) after authenticating to Vault via Azure authentication.
/// This example assumes you have a configured Azure AD Application.
/// </summary>
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");
2022-01-07 16:33:53 +00:00
}
2021-11-03 17:10:28 +00:00
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);
2022-01-07 16:33:53 +00:00
2021-11-03 17:10:28 +00:00
// We can retrieve the secret from the VaultClient object
Secret<SecretData> kv2Secret = null;
kv2Secret = vaultClient.V1.Secrets.KeyValue.V2.ReadSecretAsync(path: "/creds").Result;
2022-01-07 16:33:53 +00:00
2021-11-03 17:10:28 +00:00
var password = kv2Secret.Data.Data["password"];
2022-01-07 16:33:53 +00:00
2021-11-03 17:10:28 +00:00
return password.ToString();
}
2022-01-07 16:33:53 +00:00
2021-11-03 17:10:28 +00:00
/// <summary>
/// Query Azure Resource Manage for metadata about the Azure instance
/// </summary>
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<Dictionary<string, InstanceMetadata>>(stringResponse);
2022-01-07 16:33:53 +00:00
2021-11-03 17:10:28 +00:00
return resultsDict["compute"];
}
/// <summary>
/// Query Azure Resource Manager (ARM) for an access token
/// </summary>
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
2022-01-07 16:33:53 +00:00
StreamReader streamResponse = new StreamReader(response.GetResponseStream());
2021-11-03 17:10:28 +00:00
string stringResponse = streamResponse.ReadToEnd();
var resultsDict = JsonConvert.DeserializeObject<Dictionary<string, string>>(stringResponse);
return resultsDict["access_token"];
}
}
}
```
</CodeBlockConfig>
</CodeTabs>