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