Authenticating Applications with HashiCorp Vault AppRole
Tip: HashiCorp Learn now has a consistently updated tutorial on how to generate tokens for machines or apps by enabling the AppRole auth method. Visit this page for the most up-to-date steps and code samples. Be sure to read our introduction to the Vault Agent which is very helpful for fetching initial secrets and a number of other tasks.
HashiCorp Vault is an open source tool for managing secrets. Application identity management with Vault enables applications and machines to automatically create, change, and rotate secrets needed for communications, services, scripts, etc. Additionally, Vault enables administrators to manage applications and machines by providing access control over different secrets. In a previous post we looked at Why We Need Dynamic Secrets. This post explores how machines and applications can use the AppRole auth method to authenticate with Vault and access secrets.
» Auth Methods
Auth methods in Vault are the components that perform authentication and assigning policies to a user, application, or machine. Vault has many auth methods to support different use cases and sources of identity. Organizations using Active Directory to manage users can use the LDAP auth method, some might use Github auth method to manage users, while VMs running in AWS can use AWS auth method.
While auth methods such as LDAP, and Github allow users to login to Vault, there needs to be a similar workflow to allow applications to do the same. AppRole auth method was specifically designed to be used by machines or applications to login to Vault. Let’s take a detailed look on how AppRole auth method works.
» AppRole
The AppRole auth method allows multiple “roles” to be defined corresponding to different applications, each with different levels of access. To authenticate with Vault the application is assigned a static Role ID and a dynamically generated Secret ID which are both required to login and fetch a Vault token. The AppRole auth method was specifically designed to be used by machines and applications but uses similar authentication method that a human might use. You can look at Role ID as a “username” and the Secret ID as a “password” allowing machines to authenticate to Vault. Once authenticated, they are assigned a set of policies which grant access to retrieve secrets from Vault.
» Role ID
As discussed earlier, Role ID can be seen as the “username” for a particular application. This means that multiple instances of the same application can share the same Role ID. For example, a front-end service can have multiple instances running and they all share the same Role ID since they are a single logical service. Role IDs can be created by an operator or a build system and is provided to the application using various methods like configuration management. This can then be used along with a Secret ID to login to Vault.
» Secret ID
Secret ID is always intended to be a secret and can be seen as the “password” that is required to login to Vault. This can be dynamically generated by a trusted entity such as build system or using configuration management. Each Secret ID is meant to be unique for one instance of an application. Unique credentials allow us to better audit access and have fine grained revocation of access. Each Secret ID can have a usage limit, TTL, and expiration to better limit access.
Let’s now take a look at an end to end example to help understand AppRole auth method better.
The above example explores an end to end process of generating a Vault token for an application running on a server or using a container.
In this example, an operator creates a policy to allow an application to fetch its secrets from Vault. Below is an example of a policy that is created for a front-end service named “hello-world”.
$ cat hello-world.hcl
path "secret/hello-world" {
capabilities = ["read", "list"]
}
$ vault policy write hello-world hello-world.hcl
Next, an operator can create a role in Vault and associate the policy with that role.
$ vault write auth/approle/role/hello-world secret_id_ttl=120m token_ttl=60m token_max_tll=120m policies="hello-world"
The hello-world
role is now ready to be used by any instance of the hello-world application. The Role ID for the hello-world
role can be fetched using the Vault API by a human or a machine. Below is an example of how Role ID can be fetched using the Vault CLI.
$ vault read auth/approle/role/hello-world/role-id
Key Value
--- -----
role_id 83b621b3-0aca-1e63-fc05-b7a44318dd85
In this example, a developer triggers a build for the hello-world application by pushing a new version of application to the source code repository. The CI/CD build system can now fetch the Role ID for the hello-world role using the Vault API. This Role ID can be written as part of the metadata for the application.
In this example, Role ID is written to the machine image of the server that is responsible for running the hello-world application. This can be done during the creation of machine image using Packer. The CI/CD system can pass the Role ID as an argument to Packer and it can use a variety of provisioners to write it to the machine image. Once the build for the machine image is complete, this machine image can be used to spin up new instances of the hello-world application. The machine image will contain all application dependencies, application code along with Role ID written file.
Next, the machine image can be sent to the orchestrator used to spin up instances of the application. This can be configuration management system. In this example, Terraform will be used to spin up servers for the hello-world application. The orchestrator will generate a Secret ID for the application and deliver it to the server that is running the application using methods such as SSH. Below is an example of generating a Secret ID using the Vault CLI for the hello-world role.
$ vault write -f auth/approle/role/hello-world/secret-id
Key Value
--- -----
secret_id 238651ce-7962-c9bf-67a4-1ec0573d1058
secret_id_accessor d5fd9984-d901-cf65-473e-edbb43618d95
Note that the orchestrator(Terraform) can only generate Secret IDs for the hello-world application and does not have access to the secrets for the application. This is essential helps to compartmentalize access in the application delivery pipeline.
The hello-world application can authenticate with Vault using the Role ID, and Secret ID provided by a file written during the build process. Below is an example of using the Role ID, and Secret ID to login to Vault using the Vault CLI.
$ vault write auth/approle/login role_id=${ROLE_ID} secret_id=${SECRET_ID}
Key Value
--- -----
token 87e9d662-2f9d-5cc5-a7eb-b3e5ed76d887
token_accessor 3e9a58e5-4ea5-fe1c-d3fc-180017b63e98
token_duration 1h
token_renewable true
token_policies [default hello-world]
token_meta_role_name hello-world
The -field=token
command line argument can be used to filter the output to only return the Vault token. This is helpful when setting the VAULT_TOKEN environment variable.
Once the authentication successful, Vault will provide a token to the application that can used to request secrets. Tools like envconsul, and consul-template can also be used to populate secret data for the application. Below is an example of fetching secret data using consul-template.
{{ with secret "secret/hello-world" }}
{{ if .Data.password }}
password = "{{ .Data.password }}"
{{ end }}
{{ end }}
Secrets fetched from Vault can be written to a configuration file by consul-template. The application can then be started by consul-template and it can read the configuration file to use the secrets.
» Conclusion
The AppRole auth method provides a workflow for application or machines to authenticate with Vault. It can help provide a multi-part authenticating solution by using the combination of Role ID (sensitive), and Secret ID (secret). AppRole allows applications to be assigned a unique role and securely authenticate with Vault while fitting into existing configuration management or CI/CD workflows. To learn more checkout AppRole auth method.
Sign up for the latest HashiCorp news
More blog posts like this one
Vault integrations with MongoDB, Private Machines, and walt.id strengthen customer security
Three new HashiCorp Vault ecosystem integrations extend security use cases for customers.
HashiCorp at re:Invent 2024: Security Lifecycle Management with AWS
A recap of HashiCorp security news and developments on AWS from the past year, for your security management playbook.
HCP Vault Dedicated adds secrets sync, cross-region DR, EST PKI, and more
The newest HCP Vault Dedicated 1.18 upgrade includes a range of new features that include expanding DR region coverage, syncing secrets across providers, and adding PKI EST among other key features.