1--- 2layout: "guides" 3page_title: "Identity: Entities and Groups - Guides" 4sidebar_title: "Identity - Entities & Groups" 5sidebar_current: "guides-identity-identity" 6description: |- 7 This guide demonstrates the commands to create entities, entity aliases, and 8 groups. For the purpose of the demonstration, userpass auth method will be 9 used. 10--- 11 12# Identity - Entities and Groups 13 14Vault supports multiple authentication methods and also allows enabling the same 15type of authentication method on different mount paths. Each Vault client may 16have multiple accounts with various identity providers that are enabled on the 17Vault server. 18 19Vault clients can be mapped as ***entities*** and their corresponding accounts 20with authentication providers can be mapped as ***aliases***. In essence, each 21entity is made up of zero or more aliases. Identity secrets engine internally 22maintains the clients who are recognized by Vault. 23 24## Reference Material 25 26- [Identity Secrets Engine](/docs/secrets/identity/index.html) 27- [Identity Secrets Engine (API)](/api/secret/identity/index.html) 28- [External vs Internal Groups](/docs/secrets/identity/index.html#external-vs-internal-groups) 29 30~> **NOTE:** An [interactive 31tutorial](https://www.katacoda.com/hashicorp/scenarios/vault-identity) is 32also available if you do not have a Vault environment to perform the steps 33described in this guide. 34 35## Estimated Time to Complete 36 3710 minutes 38 39## Personas 40 41The steps described in this guide are typically performed by **operations** 42persona. 43 44 45## Challenge 46 47Bob has accounts in both Github and LDAP. Both Github and LDAP auth methods are 48enabled on the Vault server that he can authenticate using either one of his 49accounts. Although both accounts belong to Bob, there is no association between 50the two accounts to set some common properties. 51 52## Solution 53 54Create an _entity_ representing Bob, and associate aliases representing each of 55his accounts as the entity member. You can set additional policies and metadata 56on the entity level so that both accounts can inherit. 57 58When Bob authenticates using either one of his accounts, the entity identifier 59will be tied to the authenticated token. When such tokens are put to use, their 60entity identifiers are audit logged, marking a trail of actions performed by 61specific users. 62 63 64## Prerequisites 65 66To perform the tasks described in this guide, you need to have a Vault 67environment. Refer to the [Getting 68Started](/intro/getting-started/install.html) guide to install Vault. Make sure 69that your Vault server has been [initialized and 70unsealed](/intro/getting-started/deploy.html). 71 72 73### Policy requirements 74 75-> **NOTE:** For the purpose of this guide, you can use the **`root`** token to work 76with Vault. However, it is recommended that root tokens are used for just 77enough initial setup or in emergencies. As a best practice, use tokens with 78an appropriate set of policies based on your role in the organization. 79 80To perform all tasks demonstrated in this guide, your policy must include the 81following permissions: 82 83```shell 84# Configure auth methods 85path "sys/auth" { 86 capabilities = [ "read", "list" ] 87} 88 89# Configure auth methods 90path "sys/auth/*" { 91 capabilities = [ "create", "update", "read", "delete", "list", "sudo" ] 92} 93 94# Manage userpass auth methods 95path "auth/userpass/*" { 96 capabilities = [ "create", "read", "update", "delete" ] 97} 98 99# Manage github auth methods 100path "auth/github/*" { 101 capabilities = [ "create", "read", "update", "delete" ] 102} 103 104# Display the Policies tab in UI 105path "sys/policies" { 106 capabilities = [ "read", "list" ] 107} 108 109# Create and manage ACL policies from UI 110path "sys/policies/acl/*" { 111 capabilities = [ "create", "read", "update", "delete", "list" ] 112} 113 114# Create and manage policies 115path "sys/policy" { 116 capabilities = [ "read", "list" ] 117} 118 119# Create and manage policies 120path "sys/policy/*" { 121 capabilities = [ "create", "read", "update", "delete", "list" ] 122} 123 124# List available secret engines to retrieve accessor ID 125path "sys/mounts" { 126 capabilities = [ "read" ] 127} 128 129# Create and manage entities and groups 130path "identity/*" { 131 capabilities = [ "create", "read", "update", "delete", "list" ] 132} 133``` 134 135If you are not familiar with policies, complete the 136[policies](/guides/identity/policies.html) guide. 137 138 139## Steps 140 141In this lab, you are going to learn the API-based commands to create entities, 142entity aliases, and groups. For the purpose of the training, you are going to 143leverage the userpass auth method. The challenge exercise walks you through 144creating an external group by mapping a GitHub group to an identity group. 145 1461. [Create an Entity with Alias](#step1) 1472. [Test the Entity](#step2) 1483. [Create an Internal Group](#step3) 1494. [Create an External Group](#step4) 150 151 152 153### <a name="step1"></a>Step 1: Create an Entity with Alias 154 155You are going to create a new entity with base policy assigned. The entity 156defines two entity aliases with each has a different policy assigned. 157 158**Scenario:** A user, Bob Smith at ACME Inc. happened to have two sets of 159credentials: `bob` and `bsmith`. He can authenticate with Vault using either 160one of his accounts. To manage his accounts and link them to identity `Bob 161Smith` in QA team, you are going to create an entity for Bob. 162 163![Entity Bob Smith](/img/vault-entity-1.png) 164 165-> For the simplicity of this guide, you are going to work with the `userpass` 166auth method. However, in reality, the user `bob` might be a username exists in 167Active Directory, and `bsmith` might be Bob's username in GitHub. 168 169#### Scenario Policies 170 171**`base.hcl`** 172 173```hcl 174path "secret/training_*" { 175 capabilities = ["create", "read"] 176} 177``` 178 179**`test.hcl`** 180 181```hcl 182path "secret/test" { 183 capabilities = [ "create", "read", "update", "delete" ] 184} 185``` 186 187**`team-qa.hcl`** 188 189```hcl 190path "secret/team-qa" { 191 capabilities = [ "create", "read", "update", "delete" ] 192} 193``` 194 195~> **NOTE:** If you are running [K/V Secrets Engine v2](/api/secret/kv/kv-v2.html) 196at `secret`, set the policies path accordingly: `secret/data/training_*`, 197`secret/data/test`, and `secret/data/team-qa`. 198 199Now, you are going to create `bob` and `bsmith` users with appropriate policies 200attached. 201 202 203 204#### CLI command 205 2061. Create policies: `base`, `test`, and `team-qa`. 207 208 ```shell 209 # Create base policy 210 $ vault policy write base base.hcl 211 212 # Create test policy 213 $ vault policy write test test.hcl 214 215 # Create team-qa policy 216 $ vault policy write team-qa team-qa.hcl 217 218 # List all policies to verify that 'base', 'test' and 'team-qa' policies exist 219 $ vault policy list 220 base 221 default 222 team-qa 223 test 224 root 225 ``` 226 2271. Enable the `userpass` auth method. 228 229 ```plaintext 230 $ vault auth enable userpass 231 ``` 232 2331. Create a new user in userpass: 234 - username: bob 235 - password: training 236 - policy: test 237 238 ```plaintext 239 $ vault write auth/userpass/users/bob password="training" policies="test" 240 ``` 241 2421. Create another user in userpass: 243 - username: bsmith 244 - password: training 245 - policy: team-qa 246 247 ```plaintext 248 $ vault write auth/userpass/users/bsmith password="training" policies="team-qa" 249 ``` 250 2511. Execute the following command to discover the mount accessor for the userpass auth method: 252 253 ```plaintext 254 $ vault auth list -detailed 255 Path Type Accessor ... 256 ---- ---- -------- ... 257 token/ token auth_token_bec8530a ... 258 userpass/ userpass auth_userpass_70eba76b ... 259 ``` 260 261 In the output, locate the **Accessor** value for `userpass`. 262 263 Run the following command to store the userpass accessor value in a file named, `accessor.txt`. 264 265 ```plaintext 266 $ vault auth list -format=json | jq -r '.["userpass/"].accessor' > accessor.txt 267 ``` 268 2691. Create an entity for `bob-smith`. 270 271 ```plaintext 272 $ vault write identity/entity name="bob-smith" policies="base" \ 273 metadata=organization="ACME Inc." \ 274 metadata=team="QA" 275 276 Key Value 277 --- ----- 278 aliases <nil> 279 id 631256b1-8523-9838-5501-d0a1e2cdad9c 280 ``` 281 282 -> Make a note of the generated entity ID (**`id`**). 283 284 2851. Now, add the user `bob` to the `bob-smith` entity by creating an entity alias: 286 287 ```plaintext 288 $ vault write identity/entity-alias name="bob" \ 289 canonical_id=<entity_id> \ 290 mount_accessor=<userpass_accessor> 291 ``` 292 293 The `<userpass_accessor>` value is stored in `accessor.txt`. 294 295 **Example:** 296 297 ```plaintext 298 $ vault write identity/entity-alias name="bob" \ 299 canonical_id="631256b1-8523-9838-5501-d0a1e2cdad9c" \ 300 mount_accessor=$(cat accessor.txt) 301 302 Key Value 303 --- ----- 304 canonical_id 631256b1-8523-9838-5501-d0a1e2cdad9c 305 id 873f7b12-dec8-c182-024e-e3f065d8a9f1 306 ``` 307 3081. Repeat the step to add user `bsmith` to the `bob-smith` entity. 309 310 **Example:** 311 312 ```plaintext 313 $ vault write identity/entity-alias name="bsmith" \ 314 canonical_id="631256b1-8523-9838-5501-d0a1e2cdad9c" \ 315 mount_accessor=$(cat accessor.txt) 316 317 Key Value 318 --- ----- 319 canonical_id 631256b1-8523-9838-5501-d0a1e2cdad9c 320 id 55d46747-b99e-6a82-05f5-61bb60fd7d15 321 ``` 322 3231. Review the entity details. 324 325 ```plaintext 326 $ vault read identity/entity/id/<entity_id> 327 ``` 328 329 The output should include the entity aliases, metadata (organization, and 330 team), and base policy. 331 332 333 334 335#### API call using cURL 336 3371. Create policies: `base`, `test`, and `team-qa`. 338 339 To create a policy, use the `/sys/policy` endpoint: 340 341 ```shell 342 $ curl --header "X-Vault-Token: <TOKEN>" \ 343 --request PUT \ 344 --data <PAYLOAD> \ 345 <VAULT_ADDRESS>/v1/sys/policy/<POLICY_NAME> 346 ``` 347 348 Where `<TOKEN>` is your valid token, and `<PAYLOAD>` includes the policy name and 349 stringified policy. 350 351 **Example:** 352 353 ```shell 354 # Create the API request payload, payload-1.json 355 $ tee payload-1.json <<EOF 356 { 357 "policy": "path \"secret/training_*\" {\n capabilities = [\"create\", \"read\"]\n}" 358 } 359 EOF 360 361 # Create base policy 362 $ curl --header "X-Vault-Token: ..." \ 363 --request PUT \ 364 --data @payload-1.json \ 365 http://127.0.0.1:8200/v1/sys/policy/base 366 367 # Create the API request payload, payload-2.json 368 $ tee payload-2.json <<EOF 369 { 370 "policy": "path \"secret/test\" {\n capabilities = [ \"create\", \"read\", \"update\", \"delete\" ]\n }" 371 } 372 EOF 373 374 # Create base policy 375 $ curl --header "X-Vault-Token: ..." \ 376 --request PUT \ 377 --data @payload-2.json \ 378 http://127.0.0.1:8200/v1/sys/policy/test 379 380 # Create the API request payload, payload-1.json 381 $ tee payload-3.json <<EOF 382 { 383 "policy": "path \"secret/team-qa\" {\n capabilities = [ \"create\", \"read\", \"update\", \"delete\" ]\n }" 384 } 385 EOF 386 387 # Create base policy 388 $ curl --header "X-Vault-Token: ..." \ 389 --request PUT \ 390 --data @payload-3.json \ 391 http://127.0.0.1:8200/v1/sys/policy/team-qa 392 393 # List all policies to verify that 'base', 'test' and 'team-qa' policies exist 394 $ curl --header "X-Vault-Token: ..." \ 395 http://127.0.0.1:8200/v1/sys/policy | jq 396 ``` 397 3981. Enable the `userpass` auth method. 399 400 ```plaintext 401 $ curl --header "X-Vault-Token: ..." \ 402 --request POST \ 403 --data '{"type": "userpass"}' \ 404 http://127.0.0.1:8200/v1/sys/auth/userpass 405 ``` 406 4071. Create a new user in userpass: 408 - username: bob 409 - password: training 410 - policy: test 411 412 ```plaintext 413 $ curl --header "X-Vault-Token: ..." \ 414 --request POST \ 415 --data '{"password": "training", "policies": "test"}' \ 416 http://127.0.0.1:8200/v1/auth/userpass/users/bob 417 ``` 418 4191. Create another user in userpass: 420 - username: bsmith 421 - password: training 422 - policy: team-qa 423 424 ```plaintext 425 $ curl --header "X-Vault-Token: ..." \ 426 --request POST \ 427 --data '{"password": "training", "policies": "team-qa"}' \ 428 http://127.0.0.1:8200/v1/auth/userpass/users/bsmith 429 ``` 430 4311. Execute the following command to discover the mount accessor for the userpass 432 auth method. 433 434 ```plaintext 435 $ curl --header "X-Vault-Token: ..." \ 436 http://127.0.0.1:8200/v1/sys/auth | jq 437 { 438 ... 439 "userpass/": { 440 "accessor": "auth_userpass_9b6cd254", 441 ... 442 }, 443 ... 444 ``` 445 446 -> Make a note of the userpass accessor value (**`auth_userpass_XXXXX`**). 447 4481. Create an entity for bob-smith. 449 450 ```plaintext 451 $ tee payload.json <<EOF 452 { 453 "name": "bob-smith", 454 "metadata": { 455 "organization": "ACME Inc.", 456 "team": "QA" 457 }, 458 "policies": ["base"] 459 } 460 EOF 461 462 $ curl --header "X-Vault-Token: ..." \ 463 --request POST \ 464 --data @payload.json \ 465 http://127.0.0.1:8200/v1/identity/entity 466 { 467 "request_id": "4d4d340f-f4c9-0201-c87e-42cc140a383a", 468 "lease_id": "", 469 "renewable": false, 470 "lease_duration": 0, 471 "data": { 472 "aliases": null, 473 "id": "6ded4d31-481f-040b-11ad-c6db0cb4d211" 474 }, 475 ... 476 ``` 477 478 -> Make a note of the generated entity ID (**`id`**). 479 4801. Now, add the user `bob` to the `bob-smith` entity by creating an entity alias. 481In the request body, you need to pass the userpass name as `name`, the userpass 482accessor value as `mount_accessor`, and the entity id as `canonical_id`. 483 484 **Example:** 485 486 ```plaintext 487 $ tee payload-bob.json <<EOF 488 { 489 "name": "bob", 490 "canonical_id": "6ded4d31-481f-040b-11ad-c6db0cb4d211", 491 "mount_accessor": "auth_userpass_9b6cd254" 492 } 493 EOF 494 495 $ curl --header "X-Vault-Token: ..." \ 496 --request POST \ 497 --data @payload-bob.json \ 498 http://127.0.0.1:8200/v1/identity/entity-alias 499 ``` 500 501 5021. Repeat the step to add user `bsmith` to the `bob-smith` entity. 503 504 **Example:** 505 506 ```plaintext 507 $ tee payload-bsmith.json <<EOF 508 { 509 "name": "bsmith", 510 "canonical_id": "6ded4d31-481f-040b-11ad-c6db0cb4d211", 511 "mount_accessor": "auth_userpass_9b6cd254" 512 } 513 EOF 514 515 $ curl --header "X-Vault-Token: ..." \ 516 --request POST \ 517 --data @payload-bsmith.json \ 518 http://127.0.0.1:8200/v1/identity/entity-alias 519 ``` 520 5211. Review the entity details. (**NOTE:** Be sure to enter the entity ID matching 522 your environment.) 523 524 ```plaintext 525 $ curl --header "X-Vault-Token: ..." \ 526 http://127.0.0.1:8200/v1/identity/entity/id/<ENTITY_ID> 527 { 528 "request_id": "cc0793bf-fafe-4b2c-fd82-88855712845c", 529 "lease_id": "", 530 "renewable": false, 531 "lease_duration": 0, 532 "data": { 533 "aliases": [ 534 { 535 "canonical_id": "6ded4d31-481f-040b-11ad-c6db0cb4d211", 536 ... 537 "mount_type": "userpass", 538 "name": "bob" 539 }, 540 { 541 "canonical_id": "6ded4d31-481f-040b-11ad-c6db0cb4d211", 542 ... 543 "mount_type": "userpass", 544 "name": "bsmith" 545 } 546 ], 547 ... 548 ``` 549 550 The `bob` and `bsmith` users should appear in the entity alias list. 551 552 553#### Web UI 554 5551. Open a web browser and launch the Vault UI (e.g. http://127.0.01:8200/ui) 556and then login. 557 5581. Click the **Policies** tab, and then select **Create ACL policy**. 559 5601. Enter **`base`** in the **Name** field, and paste in the [`base.hcl` policy 561rules](#scenario-policies) in the **Policy** text editor. 562 563 ![Create Policy](/img/vault-policy-2.png) 564 5651. Click **Create Policy** to complete. 566 5671. Repeat the steps to create policies for **`test`** and **`team-qa`** as well. 568 569 ![Create Policy](/img/vault-policy-1.png) 570 5711. Click the **Access** tab, and select **Enable new method**. 572 5731. Select **Username & Password** from the **Type** drop-down menu. 574 575 ![Create Policy](/img/vault-auth-method-2.png) 576 5771. Click **Enable Method**. 578 5791. Click the Vault CLI shell icon (**`>_`**) to open a command shell. Enter the 580following command to create a new user, **`bob`**: 581 582 ```plaintext 583 $ vault write auth/userpass/users/bob password="training" policies="test" 584 ``` 585 ![Create Policy](/img/vault-auth-method-3.png) 586 5871. Enter the following command to create a new user, **`bsmith`**: 588 589 ```plaintext 590 $ vault write auth/userpass/users/bsmith password="training" policies="team-qa" 591 ``` 592 ![Create Policy](/img/vault-auth-method-4.png) 593 5941. Click the icon (**`>_`**) again to hide the shell. 595 5961. From the **Access** tab, select **Entities** and then **Create entity**. 597 5981. Populate the **Name**, **Policies** and **Metadata** fields as shown below: 599 600 ![Create Policy](/img/vault-entity-4.png) 601 6021. Click **Create**. 603 6041. Select **Add alias**. Enter **`bob`** in the **Name** field and select 605**`userpass/ (userpass)`** from the **Auth Backend** drop-down list. 606 607 ![Create Policy](/img/vault-entity-5.png) 608 6091. Click **Create**. 610 6111. Return to the **Entities** list. Select **Add alias** from the **`bob-smith`** 612entity menu. 613 614 ![Create Policy](/img/vault-entity-6.png) 615 6161. Enter **`bsmith`** in the **Name** field and select **`userpass/ (userpass)`** from the 617**Auth Backend** drop-down list, and then click **Create**. 618 619 620 621 622### <a name="step2"></a>Step 2: Test the Entity 623 624To better understand how a token inherits the capabilities from the entity's 625policy, you are going to test it by logging in as `bob`. 626 627### CLI Command 628 629First, login as `bob`. 630 631```plaintext 632$ vault login -method=userpass username=bob password=training 633 634Key Value 635--- ----- 636token ac318416-0dc1-4311-67e4-b58381c86fde 637token_accessor 79cced7b-51df-9523-920f-a1579687516b 638token_duration 768h 639token_renewable true 640token_policies ["default" "test"] 641identity_policies ["base"] 642policies ["base" "default" "test"] 643token_meta_username bob 644``` 645 646> Upon a successful authentication, a token will be returned. Notice that the 647output displays **`token_policies`** and **`identity_policies`**. The generated 648token has both `test` and `base` policies attached. 649 650The `test` policy grants CRUD operations on the `secret/test` path. 651Test to make sure that you can write secrets in the path. 652 653```plaintext 654$ vault kv put secret/test owner="bob" 655Success! Data written to: secret/test 656``` 657 658 659Although the username `bob` does not have `base` policy attached, the token 660inherits the capabilities granted in the base policy because `bob` is a member 661of the `bob-smith` entity, and the entity has base policy attached. 662 663Check to see that the bob's token inherited the capabilities. 664 665```plaintext 666$ vault token capabilities secret/training_test 667create, read 668``` 669 670> The `base` policy grants create and read capabilities on 671`secret/training_*` path; therefore, `bob` is permitted to run create and 672read operations against any path starting with `secret/training_*`. 673 674 675What about the `secret/team-qa` path? 676 677```plaintext 678$ vault token capabilities secret/team-qa 679deny 680``` 681 682The user `bob` only inherits capability from its associating entity's policy. 683The user can access the `secret/team-qa` path only if he logs in with 684`bsmith` credentials. 685 686 687~> Log back in with the token you used to configure the entity before proceed to 688[Step 3](#step3). 689 690 691#### API call using cURL 692 693First, login as `bob`. 694 695```plaintext 696$ curl --request POST \ 697 --data '{"password": "training"}' \ 698 http://127.0.0.1:8200/v1/auth/userpass/login/bob 699{ 700 ... 701 "auth": { 702 "client_token": "b3c2ac10-9f8f-4e64-9a1c-337236ba20f6", 703 "accessor": "92204429-6555-772e-cf51-52492d7f1686", 704 "policies": [ 705 "base", 706 "default", 707 "test" 708 ], 709 "token_policies": [ 710 "default", 711 "test" 712 ], 713 "identity_policies": [ 714 "base" 715 ], 716 ... 717``` 718 719> Upon a successful authentication, a token will be returned. Notice that the 720output displays **`token_policies`** and **`identity_policies`**. The generated 721token has both `test` and `base` policies attached. 722 723The `test` policy grants CRUD operations on the `secret/test` path. Test 724to make sure that you can write secrets in the path. 725 726```plaintext 727$ curl --header "X-Vault-Token: ..." \ 728 --request POST \ 729 --data '{"owner": "bob"}' \ 730 http://127.0.0.1:8200/v1/secret/test 731``` 732 733 734Although the username `bob` does not have `base` policy attached, the token 735inherits the capabilities granted in the base policy because `bob` is a member 736of the `bob-smith` entity, and the entity has base policy attached. 737 738Check to see that the bob's token inherited the capabilities. 739 740```plaintext 741$ curl --header "X-Vault-Token: ..." \ 742 --request POST \ 743 --data '{"paths": ["secret/training_test"]}' 744 http://127.0.0.1:8200/v1/sys/capabilities-self | jq 745{ 746 "secret/training_test": [ 747 "create", 748 "read" 749 ], 750 ... 751``` 752 753> The `base` policy grants create and read capabilities on 754`secret/training_*` path; therefore, `bob` is permitted to run create and 755read operations against any path starting with `secret/training_*`. 756 757 758What about the `secret/team-qa` path? 759 760```plaintext 761$ curl --header "X-Vault-Token: ..." \ 762 --request POST \ 763 --data '{"paths": ["secret/team-qa"]}' 764 http://127.0.0.1:8200/v1/sys/capabilities-self | jq 765{ 766 "secret/team-qa": [ 767 "deny" 768 ], 769 ... 770``` 771 772The user `bob` only inherits capability from its associating entity's policy. 773The user can access the `secret/team-qa` path only if he logs in with 774`bsmith` credentials. 775 776 777!> **NOTE:** Log back in with the token you used to configure the entity before proceed to 778[Step 3](#step3). 779 780 781### <a name="step3"></a>Step 3: Create an Internal Group 782 783Now, you are going to create an internal group named, **`engineers`**. Its 784member is `bob-smith` entity that you created in [Step 1](#step1). 785 786![Entity Bob Smith](/img/vault-entity-3.png) 787 788The group policy, `team-eng` defines the following: **`team-eng.hcl`** 789 790```plaintext 791path "secret/team/eng" { 792 capabilities = [ "create", "read", "update", "delete"] 793} 794``` 795 796#### CLI Command 797 7981. Create a new policy named, `team-eng`: 799 800 ```plaintext 801 $ vault policy write team-eng ./team-eng.hcl 802 ``` 803 8041. Create an internal group named, `engineers` and add `bob-smith` entity as a 805group member and attach `team-eng`. 806 807 ```plaintext 808 $ vault write identity/group name="engineers" \ 809 policies="team-eng" \ 810 member_entity_ids=<entity_id> \ 811 metadata=team="Engineering" \ 812 metadata=region="North America" 813 ```` 814 Where `<entity_id>` is the value you copied at [Step 1](#step1). 815 816 **Example:** 817 818 ```plaintext 819 $ vault write identity/group name="engineers" \ 820 policies="team-eng" \ 821 member_entity_ids="631256b1-8523-9838-5501..." \ 822 metadata=team="Engineering" \ 823 metadata=region="North America" 824 Key Value 825 --- ----- 826 id 81bdac90-284a-7b8c-6289-5fa7693bcb4a 827 name engineers 828 ``` 829 830Now, when you login as `bob` or `bsmith`, its generated token inherits the 831group-level policy, **`team-eng`**. You can perform similar tests demonstrated 832in [Step 2](#step2) to verify that. 833 834 835#### API call using cURL 836 8371. Create a new policy named, `team-eng`: 838 839 ```shell 840 # API request payload containing stringified policy 841 $ tee payload.json <<EOF 842 { 843 "policy": "path \"secret/team/eng\" {\n capabilities = [\"create\", \"read\", \"delete\", \"update\"]\n }" 844 } 845 EOF 846 847 # Create base policy 848 $ curl --header "X-Vault-Token: ..." \ 849 --request PUT \ 850 --data @payload-1.json \ 851 http://127.0.0.1:8200/v1/sys/policy/team-eng 852 ``` 853 854 8551. Create an internal group named, `engineers` and add `bob-smith` entity as a 856group member and attach `team-eng`. 857 858 ```shell 859 # API request msg payload. Be sure to replace <ENTITY_ID> with correct value 860 $ tee payload-group.json <<EOF 861 { 862 "name": "engineers", 863 "policies": ["team-eng"], 864 "member_entity_ids": ["<ENTITY_ID>"], 865 "metadata": { 866 "team": "Engineering", 867 "region": "North America" 868 } 869 } 870 EOF 871 872 # Use identity/group endpoint 873 $ curl --header "X-Vault-Token: ..." \ 874 --request PUT \ 875 --data @payload-group.json \ 876 http://127.0.0.1:8200/v1/identity/group | jq 877 { 878 "request_id": "2b6eefd6-67a6-31c7-dbc3-11c1c132e2cf", 879 "lease_id": "", 880 "renewable": false, 881 "lease_duration": 0, 882 "data": { 883 "id": "d62157aa-b5f6-b6fe-aa40-0ffc54defc41", 884 "name": "engineers" 885 }, 886 ... 887 ``` 888 889Now, when you login as `bob` or `bsmith`, its generated token inherits the 890group-level policy, **`team-eng`**. You can perform similar tests demonstrated 891in [Step 2](#step2) to verify that. 892 893 894#### Web UI 895 8961. Click the **Policies** tab, and then select **Create ACL policy**. 897 8981. Enter **`team-eng`** in the **Name** field, and paste in the [`team-eng.hcl` policy 899rules](#step3) in the **Policy** text editor, and then click **Create Policy**. 900 9011. Click the **Access** tab and select **Entities**. 902 9031. Select the **`bob-smith`** entity and copy its **ID** displayed under the 904**Details** tab. 905 9061. Now, click **Groups** from the left navigation, and select **Create group**. 907 9081. Enter the group information as shown below. 909 910 ![Group](/img/vault-entity-7.png) 911 912 ~> **NOTE:** Make sure to enter the `bob-smith` entity **ID** you copied in the 913 **Member Entity IDs** field. 914 9151. Click **Create**. 916 917Now, when you login as `bob` or `bsmith`, its generated token inherits the 918group-level policy, **`team-eng`**. You can perform similar tests demonstrated 919in [Step 3](#step3) to verify that. 920 921<br> 922 923> **Summary:** By default, Vault creates an internal group. When you create an 924internal group, you specify the ***group members*** rather than ***group 925alias***. Group _aliases_ are mapping between Vault and external identity providers 926(e.g. LDAP, GitHub, etc.). Therefore, you define group aliases only when you 927create **external** groups. For internal groups, you specify `member_entity_ids` 928and/or `member_group_ids`. 929 930 931 932### <a name="step4"></a>Step 4: Create an External Group 933 934It is common for organizations to enable auth methods such as LDAP, Okta and 935perhaps GitHub to handle the Vault user authentication, and individual user's 936group memberships are defined within those identity providers. 937 938In order to manage the group-level authorization, you can create an external 939group to link Vault with the external identity provider (auth provider) and 940attach appropriate policies to the group. 941 942#### Example Scenario 943 944Any user who belongs to **`training`** team in GitHub organization, 945**`example-inc`** are permitted to perform all operations against the 946`secret/education` path. 947 948**NOTE:** This scenario assumes that the GitHub organization, `example-inc` 949exists as well as `training` team within the organization. 950 951### CLI Command 952 953```shell 954# Write a new policy file 955# If you are running KV v2, set the path to "secret/data/education" instead 956$ tee education.hcl <<EOF 957path "secret/education" { 958 capabilities = [ "create", "read", "update", "delete", "list" ] 959} 960EOF 961 962# Create a new policy named 'education' 963$ vault policy write education education.hcl 964 965# Enable GitHub auth method 966$ vault auth enable github 967 968# Retrieve the mount accessor for the GitHub auth method and save it in accessor.txt 969$ vault auth list -format=json | jq -r '.["github/"].accessor' > accessor.txt 970 971# Configure to point to your GitHub organization (e.g. hashicorp) 972$ vault write auth/github/config organization=example-inc 973 974# Create an external group named, "education" 975# Be sure to copy the generated group ID 976$ vault write identity/group name="education" \ 977 policies="education" \ 978 type="external" \ 979 metadata=organization="Product Education" 980 981# Create a group alias where canonical_id is the group ID 982# 'name' is the actual GitHub team name (NOTE: Use slugified team name.) 983$ vault write identity/group-alias name="training" \ 984 mount_accessor=$(cat accessor.txt) \ 985 canonical_id="<group_ID>" 986``` 987 988 989 990#### API call using cURL 991 992```shell 993# API request payload containing stringfied policy 994# If you are running KV v2, set the path to "secret/data/education" instead 995$ tee payload-pol.json <<EOF 996{ 997 "policy": "path \"secret/education\" {\n capabilities = [\"create\", \"read\", \"delete\", \"update\", \"list\"]\n }" 998} 999EOF 1000 1001# Create education policy 1002$ curl --header "X-Vault-Token: ..." \ 1003 --request PUT \ 1004 --data @payload-pol.json \ 1005 http://127.0.0.1:8200/v1/sys/policy/education 1006 1007# Enable GitHub Auth Method at github 1008$ curl --header "X-Vault-Token: ..." \ 1009 --request POST \ 1010 --data '{"type": "github"}' \ 1011 http://127.0.0.1:8200/v1/sys/auth/github 1012 1013# Configure GitHub auth method by setting organization 1014$ curl --header "X-Vault-Token: ..." \ 1015 --request POST \ 1016 --data '{"organization": "example-inc"}' \ 1017 http://127.0.0.1:8200/v1/auth/github/config 1018 1019# Get the github accessor value (**`auth_github_XXXXX`**) 1020$ curl --header "X-Vault-Token: ..." \ 1021 http://127.0.0.1:8200/v1/sys/auth | jq 1022{ 1023 ... 1024 "userpass/": { 1025 "accessor": "auth_github_91010f60", 1026 ... 1027 }, 1028 ... 1029} 1030 1031# API request msg payload to create an external group 1032$ tee payload-edu.json <<EOF 1033{ 1034 "name": "education", 1035 "policies": ["education"], 1036 "type": "external", 1037 "metadata": { 1038 "organization": "Product Education" 1039 } 1040} 1041EOF 1042 1043# Create an external group named, "education" 1044# Be sure to copy the group ID (id) 1045$ curl --header "X-Vault-Token: ..." \ 1046 --request POST \ 1047 --data @payload-edu.json \ 1048 http://127.0.0.1:8200/v1/identity/group | jq 1049{ 1050 "request_id": "a8161086-13db-f982-4216-7d996eae3fd9", 1051 "lease_id": "", 1052 "renewable": false, 1053 "lease_duration": 0, 1054 "data": { 1055 "id": "ea18cb62-2478-d370-b726-a77d1700de80", 1056 "name": "education" 1057 }, 1058 ... 1059 1060# API request msg payload to create a group aliases, training 1061$ tee payload-training.json <<EOF 1062{ 1063 "canonical_id": "<GROUP_ID>", 1064 "mount_accessor": "auth_github_XXXXX", 1065 "name": "training" 1066} 1067EOF 1068 1069# Create 'training' group alias 1070$ curl --header "X-Vault-Token: ..." \ 1071 --request POST \ 1072 --data @payload-training.json \ 1073 http://127.0.0.1:8200/v1/identity/group-alias | jq 1074``` 1075 1076#### Web UI 1077 10781. Click the **Policies** tab, and then select **Create ACL policy**. 1079 10801. Enter **`education`** in the **Name** field, and enter the following policy 1081in the **Policy** text editor, and then click **Create Policy**. (**NOTE:** If 1082you are running KV v2, set the path to **`secret/data/education`** instead.) 1083 1084 ```plaintext 1085 path "secret/education" { 1086 capabilities = [ "create", "read", "update", "delete", "list" ] 1087 } 1088 ``` 1089 10901. Click the **Access** tab and select **Auth Methods**. 1091 10921. Select **Enable new method**. 1093 10941. Select **GitHub** from the **Type** drop-down menu, and then enter 1095**`example-inc`** in the **Organization** field. 1096 10971. Click **Enable Method**. 1098 10991. Click the **Access** tab and select **Groups**. 1100 11011. Select **Create group**. Enter the group information as shown below. 1102 1103 ![Create Policy](/img/vault-entity-9.png) 1104 11051. Click **Create**. 1106 11071. Select **Add alias** and enter **`training`** in the **Name** field. Select 1108**github/ (github)** from the **Auth Backend** drop-down list. 1109 1110 ![Create Policy](/img/vault-entity-10.png) 1111 11121. Click **Create**. 1113 1114<br> 1115 1116> **Summary:** At this point, any GitHub user who belongs to `training` 1117team within the `example-inc` organization can authenticate with Vault. The 1118generated token for the user has `education` policy attached. 1119 1120 1121## Next steps 1122 1123Now that you have learned about managing user identity using entities and 1124groups, read the [AppRole Pull 1125Authentication](/guides/identity/authentication.html) guide to learn how apps or 1126machines can authenticate with Vault. 1127