open-vault/website/source/guides/identity/control-groups.html.md
Jeff Escalante a3dfde5cec New Docs Website (#5535)
* conversion stage 1

* correct image paths

* add sidebar title to frontmatter

* docs/concepts and docs/internals

* configuration docs and multi-level nav corrections

* commands docs, index file corrections, small item nav correction

* secrets converted

* auth

* add enterprise and agent docs

* add extra dividers

* secret section, wip

* correct sidebar nav title in front matter for apu section, start working on api items

* auth and backend, a couple directory structure fixes

* remove old docs

* intro side nav converted

* reset sidebar styles, add hashi-global-styles

* basic styling for nav sidebar

* folder collapse functionality

* patch up border length on last list item

* wip restructure for content component

* taking middleman hacking to the extreme, but its working

* small css fix

* add new mega nav

* fix a small mistake from the rebase

* fix a content resolution issue with middleman

* title a couple missing docs pages

* update deps, remove temporary markup

* community page

* footer to layout, community page css adjustments

* wip downloads page

* deps updated, downloads page ready

* fix community page

* homepage progress

* add components, adjust spacing

* docs and api landing pages

* a bunch of fixes, add docs and api landing pages

* update deps, add deploy scripts

* add readme note

* update deploy command

* overview page, index title

* Update doc fields

Note this still requires the link fields to be populated -- this is solely related to copy on the description fields

* Update api_basic_categories.yml

Updated API category descriptions. Like the document descriptions you'll still need to update the link headers to the proper target pages.

* Add bottom hero, adjust CSS, responsive friendly

* Add mega nav title

* homepage adjustments, asset boosts

* small fixes

* docs page styling fixes

* meganav title

* some category link corrections

* Update API categories page

updated to reflect the second level headings for api categories

* Update docs_detailed_categories.yml

Updated to represent the existing docs structure

* Update docs_detailed_categories.yml

* docs page data fix, extra operator page remove

* api data fix

* fix makefile

* update deps, add product subnav to docs and api landing pages

* Rearrange non-hands-on guides to _docs_

Since there is no place for these on learn.hashicorp, we'll put them
under _docs_.

* WIP Redirects for guides to docs

* content and component updates

* font weight hotfix, redirects

* fix guides and intro sidenavs

* fix some redirects

* small style tweaks

* Redirects to learn and internally to docs

* Remove redirect to `/vault`

* Remove `.html` from destination on redirects

* fix incorrect index redirect

* final touchups

* address feedback from michell for makefile and product downloads
2018-10-19 08:40:11 -07:00

19 KiB

layout page_title sidebar_title sidebar_current description
guides Control Groups - Guides Control Groups guides-identity-control-groups Vault Enterprise has a support for Control Group Authorization which adds additional authorization factors to be required before satisfying a request.

Control Groups

~> Enterprise Only: Control Groups is a part of Vault Enterprise Premium.

Control Groups add additional authorization factors to be required before processing requests to increase the governance, accountability, and security of your secrets. When a control group is required for a request, the requesting client receives the wrapping token in return. Only when all authorizations are satisfied, the wrapping token can be used to unwrap the requested secrets.

Reference Material

Estimated Time to Complete

10 minutes

Personas

The end-to-end scenario described in this guide involves three personas:

  • admin with privileged permissions to create policies and identities
  • processor with permission to approve secret access
  • controller with limited permission to access secrets

Challenge

In order to operate in EU, a company must abide by the General Data Protection Regulation (GDPR) as of May 2018. The regulation enforces two or more controllers jointly determine the purposes and means of processing (Chapter 4: Controller and Processor).

Consider the following scenarios:

  • Anytime an authorized user requests to read data at "EU_GDPR_data/orders/*", at least two people from the Security group must approve to ensure that the user has a valid business reason for requesting the data.

  • Anytime a database configuration is updated, it requires that one person from the DBA and one person from Security group must approve it.

Solution

Use Control Groups in your policies to implement dual controller authorization required.

Prerequisites

To perform the tasks described in this guide, you need to have a Vault Enterprise environment.

This guide assumes that you have some hands-on experience with ACL policies as well as Identities. If you are not familiar, go through the following guides first:

Policy requirements

Since this guide demonstrates the creation of policies, log in with a highly privileged token such as root.
Otherwise, required permissions to perform the steps in this guide are:

# Create and manage ACL policies via CLI
path "sys/policy/*"
{
  capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}

# Create and manage ACL policies via Web UI
path "sys/policies/acl/*"
{
  capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}

# To enable secret engines
path "sys/mounts/*" {
  capabilities = [ "create", "read", "update", "delete" ]
}

# Setting up test data
path "EU_GDPR_data/*"
{
  capabilities = ["create", "read", "update", "delete", "list"]
}

# Manage userpass auth method
path "auth/userpass/*"
{
  capabilities = ["create", "read", "update", "delete", "list"]
}

# List, create, update, and delete auth methods
path "sys/auth/*"
{
  capabilities = ["create", "read", "update", "delete"]
}

# Create and manage entities and groups
path "identity/*" {
  capabilities = [ "create", "read", "update", "delete", "list" ]
}

Steps

The scenario in this guide is that a user, Bob Smith has read-only permission on the "EU_GDPR_data/orders/*" path; however, someone in the acct_manager group must approve it before he can actually read the data.

As a member of the acct_manager group, Ellen Wright can authorize Bob's request.

Scenario

You are going to perform the following:

  1. Implement a control group
  2. Deploy the policies
  3. Setup entities and a group
  4. Verification
  5. ACL Policies vs. Sentinel Policies

-> Step 1, 2 and 3 are the tasks need to be performed by administrators or operators who have the privileges to create policies and configure entities and groups.

Step 1: Implement a control group

(Persona: admin)

  1. Author a policy named, read-gdpr-order.hcl.

    Bob needs "read" permit on "EU_GDPR_data/orders/*":

    path "EU_GDPR_data/orders/*" {
    	capabilities = [ "read" ]
    }
    

    Now, add control group to this policy:

    path "EU_GDPR_data/orders/*" {
    	capabilities = [ "read" ]
    
    	control_group = {
    		factor "authorizer" {
    			identity {
    				group_names = [ "acct_manager" ]
    				approvals = 1
    			}
    		}
    	}
    }
    

    For the purpose of this guide, the number of approvals is set to 1 to keep it simple and easy to test. Any member of the identity group, acct_manager can approve the read request. Although this example has only one factor (authorizer), you can add as many factor blocks as you need.

  2. Now, write another policy for the acct_manager group named acct_manager.hcl.

    # To approve the request
    path "sys/control-group/authorize" {
        capabilities = ["create", "update"]
    }
    
    # To check control group request status
    path "sys/control-group/request" {
        capabilities = ["create", "update"]
    }
    

    NOTE: The important thing here is that the authorizer (acct_manager) must have create and update permission on the sys/control-group/authorize endpoint so that they can approve the request.

  3. Enable key/value secrets engine at EU_GDPR_data and write some mock data:

    # Enable kv-v1 at EU_GDPR_data
    $ vault secrets enable -path=EU_GDPR_data -version=1 kv
    
    # Write some mock data
    $ vault kv put EU_GDPR_data/orders/acct1 order_number="12345678" product_id="987654321"
    

Step 2: Deploy the policies

(Persona: admin)

Deploy the read-gdpr-order and acct_manager policies that you wrote.

CLI command

# Create read-gdpr-order policy
$ vault policy write read-gdpr-order read-gdpr-order.hcl

# Create acct_manager policy
$ vault policy write acct_manager acct_manager.hcl

API call using cURL

# Construct API request payload to create read-gdpr-read policy
$ tee payload-1.json <<EOF
{
  "policy": "path \"EU_GDPR_data/orders/*\" {capabilities = [ \"read\" ]control_group = {factor \"authorizer\" ..."
}
EOF

# Create read-gdpr-order policy
$ curl --header "X-Vault-Token: ..." \
       --request PUT \
       --data @payload-1.json \
       http://127.0.0.1:8200/v1/sys/policies/acl/read-gdpr-order

# Construct API request payload to create acct_manager policy
$ tee payload-2.json <<EOF
{
 "policy": "path \"sys/control-group/authorize\" {capabilities = [\"create\", \"update\"]} ..."
}
EOF

# Create acct_manager policy
$ curl --header "X-Vault-Token: ..." \
      --request PUT \
      --data @payload-2.json \
      http://127.0.0.1:8200/v1/sys/policies/acl/acct_manager

Web UI

Open a web browser and launch the Vault UI (e.g. http://127.0.0.1:8200/ui) and then login.

  1. Click the Policies tab, and then select Create ACL policy.

  2. Toggle Upload file, and click Choose a file to select your read-gdpr-order.hcl file you authored at Step 1.

    Create Policy

    This loads the policy and sets the Name to be read-gdpr-order.

  3. Click Create Policy to complete.

  4. Repeat the steps to create a policy for acct_manager.

Step 3: Setup entities and a group

(Persona: admin)

-> This step only demonstrates CLI commands and Web UI to create entities and groups. Refer to the Identity - Entities and Groups guide if you need the full details.

Now you have policies, let's create a user, bob and an acct_manager group with ellen as a group member.

NOTE: For the purpose of this guide, use userpass auth method to create user bob and ellen so that the scenario can be easily tested.

CLI command

The following command uses jq tool to parse JSON output.

# Enable userpass
$ vault auth enable userpass

# Create a user, bob
$ vault write auth/userpass/users/bob password="training"

# Create a user, ellen
$ vault write auth/userpass/users/ellen password="training"

# Retrieve the userpass mount accessor and save it in a file named, accessor.txt
$ vault auth list -format=json | jq -r '.["userpass/"].accessor' > accessor.txt  

# Create Bob Smith entity and save the identity ID in the entity_id_bob.txt
$ vault write -format=json identity/entity name="Bob Smith" policies="read-gdpr-order" \
        metadata=team="Processor" \
        | jq -r ".data.id" > entity_id_bob.txt

# Add an entity alias for the Bob Smith entity
$ vault write identity/entity-alias name="bob" \
       canonical_id=$(cat entity_id_bob.txt) \
       mount_accessor=$(cat accessor.txt)

# Create Ellen Wright entity and save the identity ID in the entity_id_ellen.txt
$ vault write -format=json identity/entity name="Ellen Wright" policies="default" \
        metadata=team="Acct Controller" \
        | jq -r ".data.id" > entity_id_ellen.txt

# Add an entity alias for the Ellen Wright entity
$ vault write identity/entity-alias name="ellen" \
       canonical_id=$(cat entity_id_ellen.txt) \
       mount_accessor=$(cat accessor.txt)

# Finally, create acct_manager group and add Ellen Wright entity as a member
$ vault write identity/group name="acct_manager" \
      policies="acct_manager" \
      member_entity_ids=$(cat entity_id_ellen.txt)  

Web UI

  1. Click the Access tab, and select Enable new method.

  2. Select Username & Password from the Type drop-down menu.

  3. Click Enable Method.

  4. Click the Vault CLI shell icon (>_) to open a command shell. Enter the following command to create a new user, bob:

    $ vault write auth/userpass/users/bob password="training"
    

    Create Policy

  5. Enter the following command to create a new user, ellen:

    $ vault write auth/userpass/users/ellen password="training"
    
  6. Click the icon (>_) again to hide the shell.

  7. From the Access tab, select Entities and then Create entity.

  8. Populate the Name, Policies and Metadata fields as shown below.

    Create Entity

  9. Click Create.

  10. Select Add alias. Enter bob in the Name field and select userpass/ (userpass) from the Auth Backend drop-down list.

  11. Return to the Entities tab and then Create entity.

  12. Populate the Name, Policies and Metadata fields as shown below.

    Create Entity

  13. Click Create.

  14. Select Add alias. Enter ellen in the Name field and select userpass/ (userpass) from the Auth Backend drop-down list.

  15. Click Create.

  16. Select the Ellen Wright entity and copy its ID displayed under the Details tab.

  17. Click Groups from the left navigation, and select Create group.

  18. Enter acct_manager in the Name, and again enter acct_manager in the Policies fields.

  19. Enter the Ellen Wright entity ID in the Member Entity IDs field, and then click Create.

Step 4: Verification

(Persona: bob and ellen)

Now, let's see how the control group works.

CLI Command

  1. Log in as bob.

    $ vault login -method=userpass username="bob" password="training"
    
  2. Request to read "EU_GDPR_data/orders/acct1":

    $ vault kv get EU_GDPR_data/orders/acct1
    
    Key                              Value
    ---                              -----
    wrapping_token:                  1f1411bc-2f18-551a-5e58-0fe44432e9a5
    wrapping_accessor:               bbb4deef-e06d-9b2a-64a9-56f815c69ee7
    wrapping_token_ttl:              24h
    wrapping_token_creation_time:    2018-08-08 09:36:32 -0700 PDT
    wrapping_token_creation_path:    EU_GDPR_data/orders/acct1
    

    The response includes wrapping_token and wrapping_accessor. Copy this wrapping_accessor value.

  3. Now, a member of acct_manager must approve this request. Log in as ellen who is a member of acct_manager group.

    $ vault login -method=userpass username="ellen" password="training"
    
  4. As a user, ellen, you can check and authorize bob's request using the following commands.

    # To check the current status
    $ vault write sys/control-group/request accessor=<wrapping_accessor>
    
    # To approve the request
    $ vault write sys/control-group/authorize accessor=<wrapping_accessor>
    

    Example:

    # Check the current status
    $ vault write sys/control-group/request accessor=bbb4deef-e06d-9b2a-64a9-56f815c69ee7
    Key               Value
    ---               -----
    approved          false
    authorizations    <nil>
    request_entity    map[name:Bob Smith id:38700386-723d-3d65-43b7-4fb44d7e6c30]
    request_path      EU_GDPR_data/orders/acct1
    
    # Approve the request
    $ vault write sys/control-group/authorize accessor=bbb4deef-e06d-9b2a-64a9-56f815c69ee7
    Key         Value
    ---         -----
    approved    true
    

    Now, the approved status is true.

  5. Since the control group requires one approval from a member of acct_manager group, the condition has been met. Log back in as bob and unwrap the secret.

    Example:

    # Log back in as bob - you can use the bob's token: vault login <bob_token>
    $ vault login -method=userpass username="bob" password="training"
    
    # Unwrap the secrets by passing the wrapping_token
    $ vault unwrap 1f1411bc-2f18-551a-5e58-0fe44432e9a5
    Key                 Value
    ---                 -----
    refresh_interval    768h
    order_number        12345678
    product_id          987654321
    

API call using cURL

  1. Log in as bob.

    $ curl --request POST \
           --data '{"password": "training"}' \
           http://127.0.0.1:8200/v1/auth/userpass/login/bob | jq
    

    Copy the generated client_token value.

  2. Request to EU_GDPR_data/orders/acct1:

    $ curl --header "X-Vault-Token: <bob_client_token>" \
           http://127.0.0.1:8200/v1/EU_GDPR_data/orders/acct1 | jq
    {
       ...
       "wrap_info": {
         "token": "20a2f2b3-8bea-4e16-980b-82724dcdc38b",
         "accessor": "9910cb38-600c-29d8-1c39-764a1c89a481",
         "ttl": 86400,
         "creation_time": "2018-08-08T10:13:06-07:00",
         "creation_path": "EU_GDPR_data/orders/acct1"
       },
       ...
    }
    

    The response includes wrap_info instead of the actual data. Copy the accessor value.

  3. Now, a member of acct_manager must approve this request. Log in as ellen who is a member of acct_manager group.

    $ curl --request POST \
           --data '{"password": "training"}' \
           http://127.0.0.1:8200/v1/auth/userpass/login/ellen | jq
    

    Copy the generated client_token value.

  4. As a user, ellen, you can check the current status and then authorize bob's request. (NOTE: Be sure to replace <accessor> with the accessor value you copied earlier.)

    # To check the current status using sys/control-group/request endpoint
    $ curl --header "X-Vault-Token: <ellen_client_token>" \
           --request POST \
           --data '{"accessor": "<accessor>"}' \
           http://127.0.0.1:8200/v1/sys/control-group/request | jq
    {
       ...
       "data": {
         "approved": false,
         "authorizations": null,
         "request_entity": {
           "id": "38700386-723d-3d65-43b7-4fb44d7e6c30",
           "name": "Bob Smith"
         },
         "request_path": "EU_GDPR_data/orders/acct1"
       },
       ...
    }
    
    # Now, authorize the request using sys/control-group/authorize endpoint
    $ curl --header "X-Vault-Token: <ellen_client_token>" \
             --request POST \
             --data '{"accessor": "<accessor>"}' \
             http://127.0.0.1:8200/v1/sys/control-group/authorize | jq
    {
       ...
       "data": {
         "approved": true
       },
       ...
    }
    

    Now, the approved status is true.

  5. The bob user should be able to unwrap the secrets.

    $ curl --header "X-Vault-Token: <bob_client_token>" \
           --request POST \
           --data '{"token": "<wrapping_token>"}' \
           http://127.0.0.1:8200/v1/sys/wrapping/unwrap | jq
    {
       ...
       "data": {
         "order_number": "12345678",
         "product_id": "987654321"
       },
       ...
    }
    

Web UI

The user, ellen can approve the data access request via UI.

  1. Open the Vault sign in page in a web browser (e.g. http://127.0.0.1:8200/ui/vault/auth?with=userpass). In the Userpass tab, enter ellen in the Username field, and training in the Password field.

  2. Click Sign in.

  3. Select the Access tab, and then Control Groups.

  4. Enter the wrapping_accessor value in the Accessor field and click Lookup. Control Groups

  5. Awaiting authorization message displays. Control
Groups

  6. Click Authorize. The message changes to "Thanks! You have given authorization."

Bob needs to request data access via CLI or API. Once the access request was approved, use the CLI or API to unwrap the secrets.

Step 5: ACL Policy vs. Sentinel Policy

Although the read-gdpr-order.hcl was written as ACL policy, you can implement Control Groups in either ACL or Sentinel policies.

Using Sentinel, the same policy may look something like:

import "controlgroup"

control_group = func() {
  numAuthzs = 0
  for controlgroup.authorizations as authz {
      if "acct_manager" in authz.groups.by_name {
         numAuthzs = numAuthzs + 1
      }
  }
  if numAuthzs >= 1 {
      return true
  }
  return false
}

main = rule {
   control_group()
}

Deploy this policy as an Endpoint Governing Policy attached to "EU_GDPR_data/orders/*" path.

-> Refer to the Sentinel Properties documentation for the list of available properties associated with control groups.

Next steps

To protect your secrets, it may become necessary to write finer-grained policies to introspect different aspects of incoming requests. If you have not already done so, read Sentinel documentation to learn more about what you can accomplish writing policies as a code.