1---
2layout: "guides"
3page_title: "AppRole Pull Authentication - Guides"
4sidebar_title: "AppRole Pull Authentication"
5sidebar_current: "guides-identity-authentication"
6description: |-
7  Authentication is a process in Vault by which user or machine-supplied
8  information is verified to create a token with pre-configured policy.
9---
10
11# Authentication
12
13Before a client can interact with Vault, it must authenticate against an [**auth
14method**](/docs/auth/index.html) to acquire a token. This token has policies attached so
15that the behavior of the client can be governed.
16
17Since tokens are the core method for authentication within Vault, there is a
18**token** auth method (often referred to as **_token store_**). This is a special
19auth method responsible for creating and storing tokens.
20
21### Auth Methods
22
23Auth methods perform authentication to verify the user or machine-supplied
24information. Some of the supported auth methods are targeted towards users
25while others are targeted toward machines or apps. For example,
26[**LDAP**](/docs/auth/ldap.html) auth method enables user authentication using
27an existing LDAP server while [**AppRole**](/docs/auth/approle.html) auth
28method is recommended for machines or apps.
29
30The [Getting Started](/intro/getting-started/authentication.html) guide walks you
31through how to enable the GitHub auth method for user authentication.
32
33This introductory guide focuses on generating tokens for machines or apps by
34enabling the [**AppRole**](/docs/auth/approle.html) auth method.
35
36
37## Reference Material
38
39- [AppRole Auth Method](/docs/auth/approle.html)
40- [AppRole Auth Method (API)](/api/auth/approle/index.html)
41- [Authenticating Applications with HashiCorp Vault AppRole](https://www.hashicorp.com/blog/authenticating-applications-with-vault-approle)
42
43
44
45## Estimated Time to Complete
46
4710 minutes
48
49## Personas
50
51The end-to-end scenario described in this guide involves two personas:
52
53- **`admin`** with privileged permissions to configure an auth method
54- **`app`** is the consumer of secrets stored in Vault
55
56
57## Challenge
58
59Think of a scenario where a DevOps team wants to configure Jenkins to read
60secrets from Vault so that it can inject the secrets to an app's environment
61variables (e.g. `MYSQL_DB_HOST`) at deployment time.
62
63Instead of hardcoding secrets in each build script as plain text, Jenkins
64retrieves secrets from Vault.
65
66As a user, you can authenticate with Vault using your LDAP credentials, and
67Vault generates a token. This token has policies granting you permission to perform
68the appropriate operations.
69
70How can a Jenkins server programmatically request a token so that it can read
71secrets from Vault?
72
73
74## Solution
75
76Enable **AppRole** auth method so that the Jenkins server can obtain a Vault
77token with appropriate policies attached. Since each AppRole has attached
78policies, you can write fine-grained policies limiting which app can access
79which path.
80
81
82## Prerequisites
83
84To perform the tasks described in this guide, you need to have a Vault
85environment.  Refer to the [Getting
86Started](/intro/getting-started/install.html) guide to install Vault. Make sure
87that your Vault server has been [initialized and
88unsealed](/intro/getting-started/deploy.html).
89
90### Policy requirements
91
92-> **NOTE:** For the purpose of this guide, you can use the **`root`** token to work
93with Vault. However, it is recommended that root tokens are only used for just
94enough initial setup or in emergencies. As a best practice, use tokens with
95an appropriate set of policies based on your role in the organization.
96
97To perform all tasks demonstrated in this guide, your policy must include the
98following permissions:
99
100```shell
101# Mount the AppRole auth method
102path "sys/auth/approle" {
103  capabilities = [ "create", "read", "update", "delete", "sudo" ]
104}
105
106# Configure the AppRole auth method
107path "sys/auth/approle/*" {
108  capabilities = [ "create", "read", "update", "delete" ]
109}
110
111# Create and manage roles
112path "auth/approle/*" {
113  capabilities = [ "create", "read", "update", "delete", "list" ]
114}
115
116# Write ACL policies
117path "sys/policy/*" {
118  capabilities = [ "create", "read", "update", "delete", "list" ]
119}
120
121# Write test data
122# Set the path to "secret/data/mysql/*" if you are running `kv-v2`
123path "secret/mysql/*" {
124  capabilities = [ "create", "read", "update", "delete", "list" ]
125}
126```
127
128If you are not familiar with policies, complete the
129[policies](/guides/identity/policies.html) guide.
130
131
132## Steps
133
134[AppRole](/docs/auth/approle.html) is an authentication mechanism within Vault
135to allow machines or apps to acquire a token to interact with Vault. It uses
136**Role ID** and **Secret ID** for login.
137
138The basic workflow is:
139![AppRole auth method workflow](/img/vault-approle-workflow.png)
140
141> For the purpose of introducing the basics of AppRole, this guide walks you
142> through a very simple scenario involving only two personas (admin and app).
143> Please refer to the [Advanced Features](#advanced-features) section for
144> further discussions after completing the following steps.
145
146In this guide, you are going to perform the following steps:
147
1481. [Enable AppRole auth method](#step1)
1491. [Create a role with policy attached](#step2)
1501. [Get Role ID and Secret ID](#step3)
1511. [Login with Role ID & Secret ID](#step4)
1521. [Read secrets using the AppRole token](#step5)
153
154Step 1 through 3 need to be performed by an `admin` user.  Step 4 and 5 describe
155the commands that an `app` runs to get a token and read secrets from Vault.
156
157
158### <a name="step1"></a>Step 1: Enable AppRole auth method
159(**Persona:** admin)
160
161Like many other auth methods, AppRole must be enabled before it can be used.
162
163#### CLI command
164
165Enable `approle` auth method by executing the following command:
166
167```shell
168$ vault auth enable approle
169```
170
171#### API call using cURL
172
173Enable `approle` auth method by mounting its endpoint at `/sys/auth/approle`:
174
175```shell
176$ curl --header "X-Vault-Token: <TOKEN>" \
177       --request POST \
178       --data <PARAMETERS> \
179       <VAULT_ADDRESS>/v1/sys/auth/approle
180```
181
182Where `<TOKEN>` is your valid token, and `<PARAMETERS>` holds [configuration
183parameters](/api/system/auth.html#enable-auth-method) of the method.
184
185
186**Example:**
187
188```shell
189$ curl --header "X-Vault-Token: ..." \
190       --request POST \
191       --data '{"type": "approle"}' \
192       http://127.0.0.1:8200/v1/sys/auth/approle
193```
194
195The above example passes the **type** (`approle`) in the request payload
196at the `sys/auth/approle` endpoint.
197
198### <a name="step2"></a>Step 2: Create a role with policy attached
199(**Persona:** admin)
200
201When you enabled the AppRole auth method, it gets mounted at the
202**`/auth/approle`** path. In this example, you are going to create a role for
203the **`app`** persona (`jenkins` in our scenario).
204
205The scenario in this guide requires the `app` to have the
206following policy (`jenkins-pol.hcl`):
207
208```shell
209# Login with AppRole
210path "auth/approle/login" {
211  capabilities = [ "create", "read" ]
212}
213
214# Read test data
215# Set the path to "secret/data/mysql/*" if you are running `kv-v2`
216path "secret/mysql/*" {
217  capabilities = [ "read" ]
218}
219
220```
221
222#### CLI command
223
224Before creating a role, create a `jenkins` policy:
225
226```shell
227$ vault policy write jenkins jenkins-pol.hcl
228```
229
230The command to create a new AppRole:
231
232```shell
233$ vault write auth/approle/role/<ROLE_NAME> [parameters]
234```
235
236> There are a number of
237> [parameters](/api/auth/approle/index.html#create-new-approle) that you can set
238> on a role. If you want to limit the use of the generated secret ID, set
239> `secret_id_num_uses` or `secret_id_ttl` parameter values. Similarly, you can
240> specify `token_num_uses` and `token_ttl`. You may never want the app token to
241> expire.  In such a case, specify the `period` so that the token generated by
242> this AppRole is a periodic token.  To learn more about periodic token, refer to
243> the [Tokens and Leases](/guides/identity/lease.html#step4) guide.
244
245**Example:**
246
247The following example creates a role named `jenkins` with `jenkins` policy
248attached. (NOTE: This example creates a role operates in [**pull**
249mode](/docs/auth/approle.html).)
250
251```shell
252$ vault write auth/approle/role/jenkins policies="jenkins"
253
254# Read the jenkins role
255$ vault read auth/approle/role/jenkins
256
257  Key               	Value
258  ---               	-----
259  bind_secret_id    	true
260  bound_cidr_list
261  period            	0
262  policies          	[jenkins]
263  secret_id_num_uses	0
264  secret_id_ttl     	0
265  token_max_ttl     	0
266  token_num_uses    	0
267  token_ttl         	0
268```
269
270**NOTE:** To attach multiple policies, pass the policy names as a comma
271separated string.
272
273```shell
274$ vault write auth/approle/role/jenkins policies="jenkins,anotherpolicy"
275````
276
277#### API call using cURL
278
279Before creating a role, create `jenkins` policy:
280
281```shell
282$ curl --header "X-Vault-Token: ..." --request PUT --data @payload.json \
283     http://127.0.0.1:8200/v1/sys/policy/jenkins
284
285$ cat payload.json
286{
287  "policy": "path \"auth/approle/login\" {  capabilities = [ \"create\", \"read\" ] } ... }"
288}
289```
290
291Now, you are ready to create a role.
292
293**Example:**
294
295The following example creates a role named `jenkins` with a `jenkins` policy
296attached. (NOTE: This example creates a role which operates in [**pull**
297mode](/docs/auth/approle.html).)
298
299```shell
300$ curl --header "X-Vault-Token: ..." --request POST \
301       --data '{"policies":"jenkins"}' \
302       http://127.0.0.1:8200/v1/auth/approle/role/jenkins
303```
304
305> There are a number of
306> [parameters](/api/auth/approle/index.html#create-new-approle) that you can set
307> on a role. If you want to limit the use of the generated secret ID, set
308> `secret_id_num_uses` or `secret_id_ttl` parameter values. Similarly, you can
309> specify `token_num_uses` and `token_ttl`. You may never want the app token to
310> expire.  In such a case, specify the `period` so that the token generated by
311> this AppRole is a periodic token.  To learn more about periodic tokens, refer to
312> the [Tokens and Leases](/guides/identity/lease.html#step4) guide.
313
314
315**NOTE:** To attach multiple policies, pass the policy names as a comma
316separated string.
317
318```shell
319$ curl --header "X-Vault-Token:..."
320       --request POST \
321       --data '{"policies":"jenkins,anotherpolicy"}' \
322       http://127.0.0.1:8200/v1/auth/approle/role/jenkins
323````
324
325To read the jenkins role you just created:
326
327```shell
328$ curl --header "X-Vault-Token: ..." --request GET \
329        http://127.0.0.1:8200/v1/auth/approle/role/jenkins | jq
330{
331  "request_id": "b18054ad-1ab5-8d83-eeed-193d97026ee7",
332  "lease_id": "",
333  "renewable": false,
334  "lease_duration": 0,
335  "data": {
336    "bind_secret_id": true,
337    "bound_cidr_list": "",
338    "period": 0,
339    "policies": [
340      "jenkins"
341    ],
342    "secret_id_num_uses": 0,
343    "secret_id_ttl": 0,
344    "token_max_ttl": 0,
345    "token_num_uses": 0,
346    "token_ttl": 0
347  },
348  "wrap_info": null,
349  "warnings": null,
350  "auth": null
351}
352```
353
354
355### <a name="step3"></a>Step 3: Get Role ID and Secret ID
356(**Persona:** admin)
357
358**Role ID** and **Secret ID** are like a username and password that a machine or
359app uses to authenticate.
360
361Since the example created a `jenkins` role which operates in pull mode, Vault
362will generate the Secret ID. You can set properties such as usage-limit, TTLs,
363and expirations on the secret IDs to control its lifecycle.
364
365#### CLI command
366
367Now, you need to fetch the Role ID and Secret ID of a role.
368
369To read the Role ID:
370
371```shell
372$ vault read auth/approle/role/<ROLE_NAME>/role-id
373```
374
375To generate a new Secret ID:
376
377```shell
378$ vault write -f auth/approle/role/<ROLE_NAME>/secret-id
379```
380
381NOTE: The `-f` flag forces the `write` operation to continue without any data
382values specified. Alternatively, you can set
383[parameters](/api/auth/approle/index.html#generate-new-secret-id)  such as
384`cidr_list`.
385
386**Example:**
387
388```shell
389$ vault read auth/approle/role/jenkins/role-id
390  Key    	Value
391  ---    	-----
392  role_id	675a50e7-cfe0-be76-e35f-49ec009731ea
393
394$ vault write -f auth/approle/role/jenkins/secret-id
395  Key               	Value
396  ---               	-----
397  secret_id         	ed0a642f-2acf-c2da-232f-1b21300d5f29
398  secret_id_accessor	a240a31f-270a-4765-64bd-94ba1f65703c
399```
400
401If you specified `secret_id_ttl`, `secret_id_num_uses`, or `bound_cidr_list` on
402the role in [Step 2](#step2), the generated secret ID carries out the conditions.
403
404
405#### API call using cURL
406
407To read the Role ID:
408
409```shell
410$ curl --header "X-Vault-Token:..." \
411       --request GET \
412       <VAULT_ADDRESS>/v1/auth/approle/role/<ROLE_NAME>/role-id
413```
414
415To generate a new Secret ID:
416
417```shell
418$ curl --header "X-Vault-Token:..." \
419       --request POST \
420       --data <PARAMETERS>
421       <VAULT_ADDRESS>/v1/auth/approle/role/<ROLE_NAME>/secret-id
422```
423
424You can pass
425[parameters](/api/auth/approle/index.html#generate-new-secret-id) in the request
426payload, or invoke the API with an empty payload.
427
428**Example:**
429
430```shell
431$ curl --header "X-Vault-Token:..." --request GET \
432       http://127.0.0.1:8200/v1/auth/approle/role/jenkins/role-id | jq
433
434$ curl --header "X-Vault-Token:..." --request POST \
435       http://127.0.0.1:8200/v1/auth/approle/role/jenkins/secret-id | jq
436```
437
438If you specified `secret_id_ttl`, `secret_id_num_uses`, or `bound_cidr_list` on
439the role in [Step 2](#step2), the generated secret ID carries out the conditions.
440
441
442
443### <a name="step4"></a>Step 4: Login with Role ID & Secret ID
444(**Persona:** app)
445
446The client (in this case, Jenkins) uses the role ID and secret ID passed by the
447admin to authenticate with Vault. If Jenkins did not receive the role ID and/or
448secret ID, the admin needs to investigate.
449
450-> Refer to the [Advanced Features](#advanced-features) section for further
451discussion on distributing the role ID and secret ID to the client app
452securely.
453
454#### CLI command
455
456To login, use the `auth/approle/login` endpoint by passing the role ID and secret ID.
457
458**Example:**
459
460```shell
461$ vault write auth/approle/login role_id="675a50e7-cfe0-be76-e35f-49ec009731ea" \
462  secret_id="ed0a642f-2acf-c2da-232f-1b21300d5f29"
463
464  Key                 	Value
465  ---                 	-----
466  token               	eeaf890e-4b0f-a687-4190-c75b1d6d70bc
467  token_accessor      	fcee5d4e-7281-8bb0-2901-e743c52e0502
468  token_duration      	768h0m0s
469  token_renewable     	true
470  token_policies      	[jenkins]
471  token_meta_role_name	"jenkins"
472```
473
474Now you have a **client token** with `default` and `jenkins` policies attached.
475
476
477#### API call using cURL
478
479To login, use the `auth/approle/login` endpoint by passing the role ID and secret ID
480in the request payload.
481
482**Example:**
483
484```plaintext
485$ cat payload.json
486  {
487    "role_id": "675a50e7-cfe0-be76-e35f-49ec009731ea",
488    "secret_id": "ed0a642f-2acf-c2da-232f-1b21300d5f29"
489  }
490
491$ curl --request POST --data @payload.json http://127.0.0.1:8200/v1/auth/approle/login | jq
492{
493  "request_id": "fccae32b-1e6a-9a9c-7666-f5cb07805c1e",
494  "lease_id": "",
495  "renewable": false,
496  "lease_duration": 0,
497  "data": null,
498  "wrap_info": null,
499  "warnings": null,
500  "auth": {
501    "client_token": "eeaf890e-4b0f-a687-4190-c75b1d6d70bc",
502    "accessor": "fcee5d4e-7281-8bb0-2901-e743c52e0502",
503    "policies": [
504      "default",
505      "jenkins"
506    ],
507    "metadata": {
508      "role_name": "jenkins"
509    },
510    "lease_duration": 2764800,
511    "renewable": true,
512    "entity_id": "54e0b765-6daf-0ff5-70b9-32c0d491f473"
513  }
514}
515```
516
517Now you have a **client token** with `default` and `jenkins` policies attached.
518
519
520### <a name="step5"></a>Step 5: Read secrets using the AppRole token
521(**Persona:** app)
522
523Once receiving a token from Vault, the client can make future requests using
524this token.
525
526#### CLI command
527
528**Example:**
529
530You can pass the `client_token` returned in [Step 4](#step4) as a part of the
531CLI command.
532
533```shell
534$ VAULT_TOKEN=3e7dd0ac-8b3e-8f88-bb37-a2890455ca6e vault kv get secret/mysql/webapp
535No value found at secret/mysql/webapp
536```
537
538Alternatively, you can first authenticate with Vault using the `client_token`.
539
540```shell
541$ vault login eeaf890e-4b0f-a687-4190-c75b1d6d70bc
542Successfully authenticated! You are now logged in.
543token: eeaf890e-4b0f-a687-4190-c75b1d6d70bc
544token_duration: 2762013
545token_policies: [default jenkins]
546
547$ vault kv get secret/mysql/webapp
548No value found at secret/mysql/webapp
549```
550
551Since there is no value at `secret/mysql/webapp`, it returns a "no value
552found" message.
553
554**Optional:** Using the `admin` user's token, you can store some secrets in the
555`secret/mysql/webapp` path.
556
557```shell
558$ vault kv put secret/mysql/webapp @mysqldb.txt
559
560$ cat mysqldb.txt
561{
562  "url": "foo.example.com:35533",
563  "db_name": "users",
564  "username": "admin",
565  "password": "pa$$w0rd"
566}
567```
568
569Now, try to read secrets from `secret/mysql/webapp` using the `client_token` again.
570This time, it should return the values you just created.
571
572
573#### API call using cURL
574
575You can now pass the `client_token` returned in [Step 4](#step4) in the
576**`X-Vault-Token`** or **`Authorization`** header.
577
578**Example:**
579
580```plaintext
581$ curl --header "X-Vault-Token: eeaf890e-4b0f-a687-4190-c75b1d6d70bc" \
582       --request GET \
583       http://127.0.0.1:8200/v1/secret/data/mysql/webapp | jq
584{
585  "errors": []
586}
587```
588
589Since there is no value at `secret/mysql/webapp`, it returns an empty array.
590
591**Optional:** Using the **`admin`** user's token, create some secrets in the
592`secret/mysql/webapp` path.
593
594```shell
595$ curl --header "X-Vault-Token: ..." --request POST --data @mysqldb.txt \
596
597$ cat mysqldb.text
598{
599  "url": "foo.example.com:35533",
600  "db_name": "users",
601  "username": "admin",
602  "password": "p@ssw0rd"
603}
604```
605
606Now, try to read secrets from `secret/mysql/webapp` using the `client_token` again.
607This time, it should return the values you just created.
608
609
610
611## Advanced Features
612
613The Role ID is equivalent to a username, and Secret ID is the corresponding
614password. The app needs both to log in with Vault. Naturally, the next question
615becomes how to deliver those values to the expected client.
616
617A common solution involves **three personas** instead of two: `admin`, `app`, and
618`trusted entity`. The `trusted entity` delivers the Role ID and Secret ID to the
619client by separate means.
620
621For example, Terraform as a trusted entity can deliver the Role ID onto the
622virtual machine.  When the app runs on the virtual machine, the Role ID already
623exists on the virtual machine.
624
625![AppRole auth method workflow](/img/vault-approle-workflow2.png)
626
627The secret ID can be delivered using [**response
628wrapping**](/docs/concepts/response-wrapping.html) to transmit the _reference_
629to the secret ID rather than the actual value.
630
631In [Step 3](#step3), you executed the following command to retrieve the Secret
632ID:
633
634```shell
635$ vault write -f auth/approle/role/jenkins/secret-id
636```
637
638Instead, use response wrapping by passing the **`-wrap-ttl`** parameter:
639
640```shell
641$ vault write -wrap-ttl=60s -f auth/approle/role/jenkins/secret-id
642
643Key                          	Value
644---                          	-----
645wrapping_token:              	9bbe23b7-5f8c-2aec-83dc-e97e94a2e632
646wrapping_accessor:           	cb5bdc8f-0cdb-35ff-0e68-9de57a79c3bf
647wrapping_token_ttl:          	1m0s
648wrapping_token_creation_time:	2018-01-08 21:29:38.826611 -0800 PST
649wrapping_token_creation_path:	auth/approle/role/jenkins/secret-id
650```
651
652Send this `wrapping_token` to the client so that the response can be unwrapped and
653obtain the Secret ID.
654
655```shell
656$ VAULT_TOKEN=9bbe23b7-5f8c-2aec-83dc-e97e94a2e632 vault unwrap
657
658Key               	Value
659---               	-----
660secret_id         	575f23e4-01ad-25f7-2661-9c9bdbb1cf81
661secret_id_accessor	7d8a40b7-a6fd-a634-579b-b7d673ff86fb
662```
663
664NOTE: To retrieve the Secret ID alone, you can use `jq` as follows:
665
666```shell
667$ VAULT_TOKEN=2577044d-cf86-a065-e28f-e2a14ea6eaf7 vault unwrap -format=json | jq -r ".data.secret_id"
668
669b07d7a47-1d0d-741d-20b4-ae0de7c6d964
670```
671
672
673## Next steps
674
675Read the [_AppRole with Terraform and
676Chef_](/guides/identity/approle-trusted-entities.html) guide to better
677understand the role of trusted entities using Terraform and Chef as an example.
678
679To learn more about response wrapping, go to the [Cubbyhole Response
680Wrapping](/guides/secret-mgmt/cubbyhole.html) guide.
681