» Azure Secrets Engine

The Azure secrets engine dynamically generates Azure service principals and role assignments. Vault roles can be mapped to one or more Azure roles, providing a simple, flexible way to manage the permissions granted to generated service principals.

Each service principal is associated with a Vault lease. When the lease expires (either during normal revocation or through early revocation), the service principal is automatically deleted.

» Setup

Most secrets engines must be configured in advance before they can perform their functions. These steps are usually completed by an operator or configuration management tool.

  1. Enable the Azure secrets engine:

    $ vault secrets enable azure
    Success! Enabled the azure secrets engine at: azure/
    

    By default, the secrets engine will mount at the name of the engine. To enable the secrets engine at a different path, use the -path argument.

  2. Configure the secrets engine with account credentials:

    $ vault write azure/config \
    subscription_id=$AZURE_SUBSCRIPTION_ID \
    tenant_id=$AZURE_TENANT_ID \
    client_id=$AZURE_CLIENT_ID \
    client_secret=$AZURE_CLIENT_SECRET
    
    Success! Data written to: azure/config
    

    If you are running Vault inside an Azure VM with MSI enabled, client_id and client_secret may be omitted. For more information on authentication, see the authentication section below.

  3. Configure a role. Roles determine the permissions that the service principal generated by Vault will have to Azure resources.

    To configure a role called "my-role":

    $ vault write azure/roles/my-role ttl=1h azure_roles=-<<EOF
        [
            {
                "role_name": "Contributor",
                "scope":  "/subscriptions/<uuid>/resourceGroups/Website"
            }
        ]
    EOF
    

    Roles may also have their own TTL configuration that is separate from the mount's TTL. For more information on roles see the roles section below.

» Usage

After the secrets engine is configured and a user/machine has a Vault token with the proper permissions, it can generate credentials.

To generate a credential using the "my-role" role:

$ vault read azure/creds/my-role

Key                Value
---                -----
lease_id           azure/creds/sp_role/1afd0969-ad23-73e2-f974-962f7ac1c2b4
lease_duration     60m
lease_renewable    true
client_id          408bf248-dd4e-4be5-919a-7f6207a307ab
client_secret      ad06228a-2db9-4e0a-8a5d-e047c7f32594

This endpoint generates a renewable service principal. The application can login using the client_id/client_secret and will have access provided by the Azure roles set in the "my-role" configuration.

» Roles

Vault roles let you configure mapped Azure roles and role-specific TTL parameters. One or more Azure roles will be assigned to a newly created service principal. The Vault role may optionally specify role-specific ttl and/or max_ttl values. When the lease is created, the more restrictive of the mount or role TTL value will be used.

» Azure Roles

Azure roles are provided as a JSON list, with each element describing an Azure role and scope to be assigned. Azure roles may be specified using the role_name parameter ("Owner"), or role_id ("/subscriptions/.../roleDefinitions/..."). role_id is the definitive ID that's used during Vault operation; role_name is a convenience during role management operations. All roles must exist when the configuration is written or the operation will fail. The role lookup priority is:

  1. If role_id is provided, it validated and the corresponding role_name updated.
  2. If only role_name is provided, a case-insensitive search-by-name is made, succeeding only if exactly one matching role is found. The role_id field will updated with the matching role ID.

The scope must be provided for every role assignment.

Example of role configuration:

$ vault write azure/roles/my-role ttl=1h max_ttl=24h azure_roles=-<<EOF
  [
    {
        "role_name": "Contributor",
        "scope":  "/subscriptions/<uuid>/resourceGroups/Website"
    },
    {
        "role_id": "/subscriptions/<uuid>/providers/Microsoft.Authorization/roleDefinitions/<uuid>",
        "scope":  "/subscriptions/<uuid>"
    },
    {
        "role_name": "This won't matter as it will be overwritten",
        "role_id": "/subscriptions/<uuid>/providers/Microsoft.Authorization/roleDefinitions/<uuid>",
        "scope":  "/subscriptions/<uuid>/resourceGroups/Database"
    }
  ]
EOF

» Authentication

The Azure secrets backend must have sufficient permissions to read Azure role information and manage service principals. The authentication parameters can be set in the backend configuration or as environment variables. Environment variables will take precedence. The individual parameters are described in the configuration section of the API docs.

If the client ID or secret are not present and Vault is running on and Azure VM, Vault will attempt to use Managed Service Identity (MSI) to access Azure. Note that when MSI is used, tenant and subscription IDs must still be explicitly provided in the configuration or environment variables.

The following Azure roles and Azure Active Directory (AAD) permissions are required, regardless of which authentication method is used:

  • "Owner" role for the subscription scope
  • "Read and write directory data" permission in AAD
  • "Read and write all applications" permission in AAD

These permissions can be configured through the Azure Portal, CLI tool, or PowerShell.

» Additional Notes

  • If a referenced Azure role doesn't exist, a credential will not be generated. Service principals will only be generated if all role assignments are successful. This is important to note if you're using custom Azure role definitions that might be deleted at some point.

  • Azure roles are assigned only once, when the service principal is created. If the Vault role changes the list of Azure roles, these changes will not be reflected in any existing service principal, even after token renewal.

  • The time required to issue a credential is roughly proportional to the number of Azure roles that must be assigned. This operation make take some time (10s of seconds are common, and over a minute has been seen).

  • Service principal credential timeouts are not used. Vault will revoke access by deleting the service principal.

  • The Application Name for the service principal will be prefixed with vault-. This may be used to search for Vault-created credentials using other tools or the Portal.

» Help & Support

The Azure secrets engine is written as an external Vault plugin and thus exists outside the main Vault repository. It is automatically bundled with Vault releases, but the code is managed separately.

Please report issues, add feature requests, and submit contributions to the vault-plugin-secrets-azure repo on GitHub.

» API

The Azure secrets engine has a full HTTP API. Please see the Azure secrets engine API docs for more details.