Vault
Secure workflows with Azure Active Directory with OIDC auth method
Before a client can interact with Vault, it must authenticate with an auth method to acquire a token. This token has policies attached so that the behavior of the client can be governed.

Note
To learn the basics of Vault tokens, go through the Tokens tutorial.
Auth methods perform authentication to verify the user or machine-supplied information. Some auth methods are targeted towards users while others are targeted toward machines or apps.
Challenge
Vault supports a number of auth methods for users or system to prove their identity so that a token with appropriate policies can be obtained. Delegated authorization methods based on OAuth 2.0 are convenient for users and have become increasingly common.
Solution
If you use Azure Active Directory (AD), you can use Microsoft's identity platform and its implementation of OpenID Connect to verify the identity of a Vault user. By registering a Vault application in Azure, configuring Vault's OIDC auth method, and connecting the AD group with an external group in Vault, your Vault users can log into Vault by web browser. They will be redirected to Azure to complete login and then be routed back to Vault with a newly-created token.
Note
To learn how to configure authentication for system-assigned or user-assigned managed identities in Azure, go through documentation on the Azure Auth Method.
This tutorial uses the current user's email to authenticate to Azure AD. You can optionally edit the claims and Vault configuration to use Azure AD UserPrincipalName (UPN).
Prerequisites
To perform the tasks described in this tutorial, you need to have a Vault 1.6 or later. Refer to the Vault install guide guide to install Vault. Make sure that your Vault server has been initialized and unsealed.
In this tutorial, make sure that Azure can access your Vault server to successfully redirect the authentication request.
Azure Active Directory
This tutorial uses Azure Active Directory. Make sure you have:
- Configured an Azure AD tenant. 
- Permissions to configure application registrations and read group information. 
- Signed into Azure from the CLI with the correct tenant ID. 
- An Azure AD group you can use to connect to a Vault external group. 
Policy requirements
Note
 For the purpose of this tutorial, you can use the root token to work
with Vault. However, it is recommended that root tokens are only used for just
enough initial setup or in emergencies. As a best practice, use tokens with
an appropriate set of policies based on your role in the organization.
To perform all tasks demonstrated in this tutorial, your policy must include the following permissions:
# Mount the OIDC auth method
path "sys/auth/oidc" {
  capabilities = [ "create", "read", "update", "delete", "sudo" ]
}
# Configure the OIDC auth method
path "auth/oidc/*" {
  capabilities = [ "create", "read", "update", "delete", "list" ]
}
# Write ACL policies
path "sys/policies/acl/*" {
  capabilities = [ "create", "read", "update", "delete", "list" ]
}
# List available secrets engines to retrieve accessor ID
path "sys/mounts" {
  capabilities = [ "read" ]
}
# Manage secrets engines
path "sys/mounts/*"
{
  capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}
# List, create, update, and delete key/value secrets
path "secret/*"
{
  capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}
If you are not familiar with policies, complete the policies tutorial.
Lab setup
- In another terminal, start a Vault dev server with - rootas the root token.- $ vault server -dev -dev-root-token-id root
- The Vault dev server defaults to running at - 127.0.0.1:8200. The server is initialized and unsealed.- Insecure operation - Do not run a Vault dev server in production. This approach starts a Vault server with an in-memory database and runs in an insecure way. 
- Export an environment variable for the - vaultCLI to address the Vault server.- $ export VAULT_ADDR=http://127.0.0.1:8200
- Export an environment variable for the - vaultCLI to address the Vault server through the OIDC interface.- $ export VAULT_OIDC_ADDR=http://127.0.0.1:8250
- Export an environment variable for the - vaultCLI to authenticate with the Vault server.- $ export VAULT_TOKEN=root- Note - For these tasks, you can use Vault's root token. However, it is recommended that root tokens are only used for enough initial setup or in emergencies. As a best practice, use an authentication method or token that meets the policy requirements. 
The Vault server is ready.
Register Vault as a web app
An app registration allows Azure AD to identify Vault and the user.
- Set the - AD_AZURE_DISPLAY_NAMEenvironment variable to a unique display name for Vault's app registration.- $ export AD_AZURE_DISPLAY_NAME=vault-$(xxd -l 4 -p < /dev/random)- Note - The example above uses - xxdand- /dev/randomto generate a short unique string to use for the app name.
- Register a web app for Vault with two redirect URIs (also called - reply-urls). One URI is for Vault CLI access and the second is for UI access. Save the application ID to the- AD_VAULT_APP_IDenvironment variable.- $ export AD_VAULT_APP_ID=$(az ad app create \ --display-name ${AD_AZURE_DISPLAY_NAME} \ --web-redirect-uris "http://localhost:8250/oidc/callback" \ "${VAULT_ADDR}/ui/vault/auth/oidc/oidc/callback" | \ jq -r '.appId')
- Retrieve the application ID of the Microsoft Graph API, which allows you to access Azure service resources. This ID will be used to attach API permissions to the app registration. - $ export AD_MICROSOFT_GRAPH_API_ID=$(az ad sp list \ --filter "displayName eq 'Microsoft Graph'" \ --query '[].appId' -o tsv)
- Using the Microsoft Graph API ID, retrieve the ID of the permission for - GroupMember.Read.All.- $ export AD_PERMISSION_GROUP_MEMBER_READ_ALL_ID=$(az ad sp show \ --id ${AD_MICROSOFT_GRAPH_API_ID} \ --query "oauth2PermissionScopes[?value=='GroupMember.Read.All'].id" -o tsv)
- Add the - GroupMember.Read.Allpermission to the application. This allows the application to read an Active Directory group and its users.- $ az ad app permission add \ --id ${AD_VAULT_APP_ID} \ --api ${AD_MICROSOFT_GRAPH_API_ID} \ --api-permissions ${AD_PERMISSION_GROUP_MEMBER_READ_ALL_ID}=Scope- NOTE: If you would want to use UPN instead of email, you may need to add permissions such as - User.Readand- profile.
- Create a service principal to attach to the application. The service principal allows you to grant administrative consent from the Azure CLI. - $ az ad sp create --id ${AD_VAULT_APP_ID}
- Grant administrative consent for the application to access the Microsoft Graph API. - $ az ad app permission grant --id ${AD_VAULT_APP_ID} \ --api ${AD_MICROSOFT_GRAPH_API_ID} \ --scope ${AD_PERMISSION_GROUP_MEMBER_READ_ALL_ID}
- Retrieve the Azure tenant ID for the application and set it to the - AD_TENANT_IDenvironment variable.- $ export AD_TENANT_ID=$(az ad sp show --id ${AD_VAULT_APP_ID} \ --query 'appOwnerOrganizationId' -o tsv)
- Reset the client secret for the application and set the password to the - AD_CLIENT_SECRETenvironment variable. You will need the secret to configure the OIDC auth method in Vault.- $ export AD_CLIENT_SECRET=$(az ad app credential reset \ --id ${AD_VAULT_APP_ID} | jq -r '.password')
Update application group claims and ID tokens
To use AD groups to authenticate to Vault, you need to update the Vault application in Azure with a claim for group membership information.
- Create a file named - manifest.jsonwith the specification for an ID token for an AD group.- $ cat > manifest.json << EOF { "idToken": [ { "name": "groups", "additionalProperties": [] }, { "name": "email", "additionalProperties": [] } ] } EOF
- Update the application with the claims manifest in - manifest.jsonand set- groupMembershipClaimsto- SecurityGroup. You can expand the group type to additional groups.- $ az ad app update --id ${AD_VAULT_APP_ID} \ --set groupMembershipClaims=SecurityGroup \ --optional-claims @manifest.json
Create Vault policies for an example group
Every client token has policies attached to it to control its secret access. You must create the policies before defining them in the OIDC configuration.
- Create an example Vault policy that allows an application development team to read and write secrets mounted at - secrets/.- $ cat > kv-reader-policy.hcl << EOF path "secret/*" { capabilities = ["read", "list"] } EOF
- Write the policy named - kv-readerto Vault.- $ vault policy write kv-reader kv-reader-policy.hcl
- Enable the key-value secrets engine at - secret/.- $ vault secrets enable -path=secret -version=2 kv
- Create a sample entry in the KV secrets engine. - $ vault kv put secret/azure hello=world
Configure Vault with the OIDC auth method
OIDC must be enabled and configured before it can be used. In this section, you
will configure OIDC for a role named app-dev, which application development
teams can use to log in and access secrets.
- Set the - VAULT_LOGIN_ROLEenvironment variable to- app-dev. In your own configuration, you can change this role name.- $ export VAULT_LOGIN_ROLE=app-dev
- Enable the OIDC auth method on the Vault server. - $ vault auth enable oidc
- Configure the OIDC auth method with the application ID, client secret, and tenant ID of your Vault application in Azure AD. - $ vault write auth/oidc/config \ oidc_client_id="${AD_VAULT_APP_ID}" \ oidc_client_secret="${AD_CLIENT_SECRET}" \ default_role="${VAULT_LOGIN_ROLE}" \ oidc_discovery_url="https://login.microsoftonline.com/${AD_TENANT_ID}/v2.0"- Tip - Further information for configuring the OIDC auth method for use with Azure AD is available in the Azure Active Directory (AAD) section of the OIDC Provider Configuration documentation. 
- Add a role to Vault called - app-devthat uses the Vault policy to read secrets (- kv-reader). It authenticates to Azure by a user's email. In addition, it passes the- group_claimof- groupsthat were configured as part of the claims manifest. The- oidc_scopesshould be set to the- https://graph.microsoft.com/.default, which is the Microsoft Graph API.- $ vault write auth/oidc/role/${VAULT_LOGIN_ROLE} \ user_claim="email" \ allowed_redirect_uris="http://localhost:8250/oidc/callback" \ allowed_redirect_uris="${VAULT_ADDR}/ui/vault/auth/oidc/oidc/callback" \ policies="kv-reader" \ oidc_scopes="https://graph.microsoft.com/.default"- Note - If you want to use UPN instead of user email, change the - user_claimfield to- upn.
- Record the current Vault token. - $ echo $VAULT_TOKEN VAULT_TOKEN=hvs.REDACTED- You will use this to re-authenticate with Vault to add additional OIDC configuration for external groups. 
- Unset the - VAULT_TOKENenvironment variable. When you authenticate with Azure you will receive a new token based on the OIDC configuration.- $ unset VAULT_TOKEN
- Try to log into the server with the OIDC auth method. If it is successful, the command launches a browser to Azure for you to log in and return a Vault token. - $ vault login -method=oidc role="app-dev" Complete the login via your OIDC provider. Launching browser to: https://login.microsoftonline.com/... Success! You are now authenticated. The token information displayed below is already stored in the token helper. You do NOT need to run "vault login" again. Future Vault requests will automatically use this token. Key Value --- ----- token hvs.REDACTED token_accessor u58XsOYz2I5T1GmqwsaaOpsP.WEwzy token_duration 1h token_renewable true token_policies ["default" "kv-reader"] identity_policies [] policies ["default" "kv-reader"] token_meta_role app-dev- You successful authenticated to Vault using Azure credentials. The - kv-readerpolicy was applied because this was configured as the default policy for the- app-devrole.
- As part of the - app-devrole, you should be able to access- secret/.- $ vault kv list secret Keys ---- azure- The secret created earlier is listed. 
Set up Vault external group and AD group
With OIDC setup correctly, you will now create an Active Directory group for the security team to write secrets. Connect this Azure AD group to a Vault policy, which will allow any users in the Azure AD group to log into Vault by email and write secrets.
- Export the token that was unset prior to testing the OIDC configuration. - $ export VAULT_TOKEN=<actual-token-value>
- Create a policy file named - secops.hcl.- $ tee secops.hcl <<EOF # Manage k/v secrets path "/secret/*" { capabilities = ["create", "read", "update", "delete", "list"] } EOF
- Create a policy named - secopswith the policy defined in- secops.hcl.- $ vault policy write secops secops.hcl
- Create an Azure AD group. - $ az ad group create \ --display-name hashicorp-secops-$AD_AZURE_DISPLAY_NAME \ --mail-nickname hashicorp-secops-$AD_AZURE_DISPLAY_NAME
- Add the user authenticated with the Azure CLI to the new AD group. - $ az ad group member add --group hashicorp-secops-$AD_AZURE_DISPLAY_NAME \ --member-id $(az ad signed-in-user show | jq -r .id)
- Create a role named - secops.- $ vault write auth/oidc/role/secops \ user_claim="email" \ allowed_redirect_uris="http://localhost:8250/oidc/callback" \ allowed_redirect_uris="${VAULT_ADDR}/ui/vault/auth/oidc/oidc/callback" \ groups_claim="groups" \ policies="kv-reader" \ oidc_scopes="https://graph.microsoft.com/.default"
- Create an external group named - secopsin the Vault identity secrets engine that references the- secopspolicy and set the group ID in the- VAULT_GROUP_IDenvironment variable.- $ export VAULT_GROUP_ID=$(vault write \ -field=id -format=table \ identity/group \ name="secops" \ type="external" \ policies="secops")
- Retrieve Vault's OIDC accessor ID and set it to the - VAULT_OIDC_ACCESSOR_IDenvironment variable.- $ export VAULT_OIDC_ACCESSOR_ID=$(vault auth list -format=json | \ jq -r '."oidc/".accessor')
- Retrieve the - objectIdActive Directory group you previously create and save it as an environment variable.- $ AZ_GROUP_ID=$(az ad group show --group hashicorp-secops-$AD_AZURE_DISPLAY_NAME | jq .id -r)
- Create a group alias using the ID of the AD security group. - $ vault write identity/group-alias name="$AZ_GROUP_ID" \ mount_accessor="$VAULT_OIDC_ACCESSOR_ID" \ canonical_id="$VAULT_GROUP_ID"
- Unset the - VAULT_TOKENenvironment variable. When you authenticate with Azure you will receive a new token based on the OIDC configuration.- $ unset VAULT_TOKEN
- Try to log into the server with the OIDC auth method as a member of the AD group you configured with Vault. If it is successful, the command launches a browser to Azure for you to log in and return a Vault token. - $ vault login -method=oidc role="secops" Complete the login via your OIDC provider. Launching browser to: https://login.microsoftonline.com/...snip... Waiting for OIDC authentication to complete... Success! You are now authenticated. The token information displayed below is already stored in the token helper. You do NOT need to run "vault login" again. Future Vault requests will automatically use this token. Key Value --- ----- token hvs.REDACTED token_accessor 6OACh6sPly1ogpRV5RY5zmos.CGhuZ token_duration 1h token_renewable true token_policies ["default" "kv-reader"] identity_policies ["secops"] policies ["default" "kv-reader" "secops"] token_meta_role secops- The - secopspolicy is assigned through the AD group membership.
- As part of the - secopsrole that is connected to the AD group, you should be able to write secrets to the- secret/path.- $ vault kv put secret/groups oidc=ftw === Secret Path === secret/data/groups ======= Metadata ======= Key Value --- ----- created_time 2023-01-09T15:22:21.854306825Z custom_metadata <nil> deletion_time n/a destroyed false version 1- You are now able to write secrets based on the - secopspolicy assigned to the user.
Cleanup
To avoid unnecessary charges and having unused security resources in your Azure account, remove the following:
- Delete the Vault Azure app. - $ az ad app delete --id $AD_VAULT_APP_ID
- Delete the Azure AD group - $ az ad group delete --group hashicorp-secops-$AD_AZURE_DISPLAY_NAME
- Create an array of the local environment variables. - $ learnVariables=( \ AD_AZURE_DISPLAY_NAME \ AD_VAULT_APP_ID \ AD_MICROSOFT_GRAPH_API_ID \ AD_PERMISSION_GROUP_MEMBER_READ_ALL_ID \ AD_TENANT_ID \ AD_CLIENT_SECRET \ VAULT_LOGIN_ROLE \ VAULT_GROUP_ID \ VAULT_OIDC_ACCESSOR_ID \ )
- Unset the environment variables. - for v in ${learnVariables[@]}; do unset $v done
Summary
In this tutorial, you configured Vault's OIDC auth method to authenticate a user by using a group in Azure Active Directory. This allowed the user to read and list secrets from Vault.


