[Guide] Control Groups (#5072)
* Control Group guide * Fixed user policy list * Fixed a typo * Replaced the wrong screenshot * Added missing period
BIN
website/source/assets/images/vault-ctrl-grp-1.png
Normal file
After Width: | Height: | Size: 94 KiB |
BIN
website/source/assets/images/vault-ctrl-grp-2.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
website/source/assets/images/vault-ctrl-grp-3.png
Normal file
After Width: | Height: | Size: 70 KiB |
BIN
website/source/assets/images/vault-ctrl-grp-4.png
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
website/source/assets/images/vault-ctrl-grp-5.png
Normal file
After Width: | Height: | Size: 74 KiB |
BIN
website/source/assets/images/vault-ctrl-grp-6.png
Normal file
After Width: | Height: | Size: 39 KiB |
BIN
website/source/assets/images/vault-ctrl-grp-7.png
Normal file
After Width: | Height: | Size: 36 KiB |
665
website/source/guides/identity/control-groups.html.md
Normal file
@ -0,0 +1,665 @@
|
||||
---
|
||||
layout: "guides"
|
||||
page_title: "Control Groups - Guides"
|
||||
sidebar_current: "guides-identity-control-groups"
|
||||
description: |-
|
||||
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](/docs/concepts/response-wrapping.html) in
|
||||
return. Only when all authorizations are satisfied, the wrapping token can be
|
||||
used to unwrap the requested secrets.
|
||||
|
||||
|
||||
## Reference Material
|
||||
|
||||
- [Vault Enterprise Control Group Support](/docs/enterprise/control-groups/index.html)
|
||||
- [Policies](http://localhost:4567/docs/concepts/policies.html)
|
||||
- [Identity Groups](/docs/secrets/identity/index.html)
|
||||
- [Control Group API](/api/system/control-group.html)
|
||||
- [Sentinel Policies](/docs/enterprise/sentinel/index.html)
|
||||
|
||||
## 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)](https://www.eugdpr.org/) as of May 2018. The regulation
|
||||
enforces two or more controllers jointly determine the purposes and means of
|
||||
processing ([Chapter 4: Controller and
|
||||
Processor](https://gdpr-info.eu/chapter-4/)).
|
||||
|
||||
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](/docs/concepts/policies.html) as well as
|
||||
[Identities](/docs/secrets/identity/index.html). If you are not familiar,
|
||||
go through the following guides first:
|
||||
|
||||
- [Policies](/guides/identity/policies.html)
|
||||
- [Identity - Entities & Groups](/guides/identity/identity.html)
|
||||
|
||||
### 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:
|
||||
|
||||
```shell
|
||||
# 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.
|
||||
|
||||

|
||||
|
||||
You are going to perform the following:
|
||||
|
||||
1. [Implement a control group](#step1)
|
||||
1. [Deploy the policies](#step2)
|
||||
1. [Setup entities and a group](#step3)
|
||||
1. [Verification](#step4)
|
||||
1. [ACL Policies vs. Sentinel Policies](#step5)
|
||||
|
||||
|
||||
-> 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.
|
||||
|
||||
|
||||
### <a name="step1"></a>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/*`":
|
||||
|
||||
```hcl
|
||||
path "EU_GDPR_data/orders/*" {
|
||||
capabilities = [ "read" ]
|
||||
}
|
||||
```
|
||||
|
||||
Now, add control group to this policy:
|
||||
|
||||
```hcl
|
||||
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.
|
||||
|
||||
1. Now, write another policy for the **`acct_manager`** group named
|
||||
**`acct_manager.hcl`**.
|
||||
|
||||
```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.
|
||||
|
||||
|
||||
1. Enable key/value secrets engine at **`EU_GDPR_data`** and write some mock data:
|
||||
|
||||
```shell
|
||||
# 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"
|
||||
```
|
||||
|
||||
### <a name="step2"></a>Step 2: Deploy the policies
|
||||
(**Persona:** admin)
|
||||
|
||||
Deploy the `read-gdpr-order` and `acct_manager` policies that you wrote.
|
||||
|
||||
#### CLI command
|
||||
|
||||
```shell
|
||||
# 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
|
||||
|
||||
```shell
|
||||
# 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**.
|
||||
|
||||
1. Toggle **Upload file**, and click **Choose a file** to select your **`read-gdpr-order.hcl`** file you authored at [Step 1](#step1).
|
||||
|
||||

|
||||
|
||||
This loads the policy and sets the **Name** to be `read-gdpr-order`.
|
||||
|
||||
1. Click **Create Policy** to complete.
|
||||
|
||||
1. Repeat the steps to create a policy for **`acct_manager`**.
|
||||
|
||||
|
||||
|
||||
### <a name="step3"></a>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](/guides/identity/identity.html) 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`](https://stedolan.github.io/jq/download/) tool
|
||||
to parse JSON output.
|
||||
|
||||
```shell
|
||||
# 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**.
|
||||
|
||||
1. Select **Username & Password** from the **Type** drop-down menu.
|
||||
|
||||
1. Click **Enable Method**.
|
||||
|
||||
1. Click the Vault CLI shell icon (**`>_`**) to open a command shell. Enter the
|
||||
following command to create a new user, **`bob`**:
|
||||
|
||||
```plaintext
|
||||
$ vault write auth/userpass/users/bob password="training"
|
||||
```
|
||||

|
||||
|
||||
1. Enter the following command to create a new user, **`ellen`**:
|
||||
|
||||
```plaintext
|
||||
$ vault write auth/userpass/users/ellen password="training"
|
||||
```
|
||||
|
||||
1. Click the icon (**`>_`**) again to hide the shell.
|
||||
|
||||
1. From the **Access** tab, select **Entities** and then **Create entity**.
|
||||
|
||||
1. Populate the **Name**, **Policies** and **Metadata** fields as shown below.
|
||||
|
||||

|
||||
|
||||
1. Click **Create**.
|
||||
|
||||
1. Select **Add alias**. Enter **`bob`** in the **Name** field and select
|
||||
**`userpass/ (userpass)`** from the **Auth Backend** drop-down list.
|
||||
|
||||
1. Return to the **Entities** tab and then **Create entity**.
|
||||
|
||||
1. Populate the **Name**, **Policies** and **Metadata** fields as shown below.
|
||||
|
||||

|
||||
|
||||
1. Click **Create**.
|
||||
|
||||
1. Select **Add alias**. Enter **`ellen`** in the **Name** field and select
|
||||
**`userpass/ (userpass)`** from the **Auth Backend** drop-down list.
|
||||
|
||||
1. Click **Create**.
|
||||
|
||||
1. Select the **`Ellen Wright`** entity and copy its **ID** displayed under the
|
||||
**Details** tab.
|
||||
|
||||
1. Click **Groups** from the left navigation, and select **Create group**.
|
||||
|
||||
1. Enter **`acct_manager`** in the **Name**, and again enter **`acct_manager`**
|
||||
in the **Policies** fields.
|
||||
|
||||
1. Enter the `Ellen Wright` entity ID in the **Member Entity IDs** field, and
|
||||
then click **Create**.
|
||||
|
||||
|
||||
### <a name="step4"></a>Step 4: Verification
|
||||
(**Persona:** bob and ellen)
|
||||
|
||||
Now, let's see how the control group works.
|
||||
|
||||
#### CLI Command
|
||||
|
||||
1. Log in as **`bob`**.
|
||||
|
||||
```plaintext
|
||||
$ vault login -method=userpass username="bob" password="training"
|
||||
```
|
||||
|
||||
1. Request to read "`EU_GDPR_data/orders/acct1`":
|
||||
|
||||
```plaintext
|
||||
$ 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.
|
||||
|
||||
1. Now, a member of `acct_manager` must approve this request. Log in as
|
||||
**`ellen`** who is a member of `acct_manager` group.
|
||||
|
||||
```plaintext
|
||||
$ vault login -method=userpass username="ellen" password="training"
|
||||
```
|
||||
|
||||
1. As a user, `ellen`, you can check and authorize bob's request using the
|
||||
following commands.
|
||||
|
||||
```shell
|
||||
# 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:**
|
||||
|
||||
```shell
|
||||
# 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`.
|
||||
|
||||
1. 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:**
|
||||
|
||||
```shell
|
||||
# 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`**.
|
||||
|
||||
```plaintext
|
||||
$ curl --request POST \
|
||||
--data '{"password": "training"}' \
|
||||
http://127.0.0.1:8200/v1/auth/userpass/login/bob | jq
|
||||
```
|
||||
|
||||
Copy the generated **`client_token`** value.
|
||||
|
||||
1. Request to `EU_GDPR_data/orders/acct1`:
|
||||
|
||||
```plaintext
|
||||
$ 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.
|
||||
|
||||
1. Now, a member of `acct_manager` must approve this request. Log in as
|
||||
**`ellen`** who is a member of `acct_manager` group.
|
||||
|
||||
```plaintext
|
||||
$ curl --request POST \
|
||||
--data '{"password": "training"}' \
|
||||
http://127.0.0.1:8200/v1/auth/userpass/login/ellen | jq
|
||||
```
|
||||
|
||||
Copy the generated **`client_token`** value.
|
||||
|
||||
1. 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.)
|
||||
|
||||
```shell
|
||||
# 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`.
|
||||
|
||||
1. The `bob` user should be able to unwrap the secrets.
|
||||
|
||||
```plaintext
|
||||
$ 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.
|
||||
|
||||
1. Click **Sign in**.
|
||||
|
||||
1. Select the **Access** tab, and then **Control Groups**.
|
||||
|
||||
1. Enter the **`wrapping_accessor`** value in the **Accessor** field and click
|
||||
**Lookup**. 
|
||||
|
||||
1. _Awaiting authorization_ message displays. 
|
||||
|
||||
1. 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.
|
||||
|
||||
|
||||
### <a name="step5"></a>Step 5: ACL Policy vs. Sentinel Policy
|
||||
|
||||
Although the [**`read-gdpr-order.hcl`**](#step1) 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:
|
||||
|
||||
```hcl
|
||||
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](/docs/enterprise/sentinel/properties.html#control-group-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](https://docs.hashicorp.com/sentinel/)
|
||||
documentation to learn more about what you can accomplish writing policies as a
|
||||
code.
|
@ -351,10 +351,11 @@ attached.
|
||||
|
||||
```shell
|
||||
# Create the API request payload, payload-1.json
|
||||
$ cat payload-1.json
|
||||
$ tee payload-1.json <<EOF
|
||||
{
|
||||
"policy": "path \"secret/training_*\" {\n capabilities = [\"create\", \"read\"]\n}"
|
||||
}
|
||||
EOF
|
||||
|
||||
# Create base policy
|
||||
$ curl --header "X-Vault-Token: ..." \
|
||||
@ -363,10 +364,11 @@ attached.
|
||||
http://127.0.0.1:8200/v1/sys/policy/base
|
||||
|
||||
# Create the API request payload, payload-2.json
|
||||
$ cat payload-2.json
|
||||
$ tee payload-2.json <<EOF
|
||||
{
|
||||
"policy": "path \"secret/test\" {\n capabilities = [ \"create\", \"read\", \"update\", \"delete\" ]\n }"
|
||||
}
|
||||
EOF
|
||||
|
||||
# Create base policy
|
||||
$ curl --header "X-Vault-Token: ..." \
|
||||
@ -375,10 +377,11 @@ attached.
|
||||
http://127.0.0.1:8200/v1/sys/policy/test
|
||||
|
||||
# Create the API request payload, payload-1.json
|
||||
$ cat payload-3.json
|
||||
$ tee payload-3.json <<EOF
|
||||
{
|
||||
"policy": "path \"secret/team-qa\" {\n capabilities = [ \"create\", \"read\", \"update\", \"delete\" ]\n }"
|
||||
}
|
||||
EOF
|
||||
|
||||
# Create base policy
|
||||
$ curl --header "X-Vault-Token: ..." \
|
||||
@ -486,6 +489,7 @@ In the request body, you need to pass the userpass accessor value as
|
||||
"canonical_id": "6ded4d31-481f-040b-11ad-c6db0cb4d211",
|
||||
"mount_accessor": "auth_userpass_9b6cd254"
|
||||
}
|
||||
EOF
|
||||
|
||||
$ curl --header "X-Vault-Token: ..." \
|
||||
--request POST \
|
||||
@ -505,6 +509,7 @@ In the request body, you need to pass the userpass accessor value as
|
||||
"canonical_id": "6ded4d31-481f-040b-11ad-c6db0cb4d211",
|
||||
"mount_accessor": "auth_userpass_9b6cd254"
|
||||
}
|
||||
EOF
|
||||
|
||||
$ curl --header "X-Vault-Token: ..." \
|
||||
--request POST \
|
||||
@ -832,10 +837,11 @@ in [Step 2](#step2) to verify that.
|
||||
|
||||
```shell
|
||||
# API request payload containing stringified policy
|
||||
$ cat payload.json
|
||||
$ tee payload.json <<EOF
|
||||
{
|
||||
"policy": "path \"secret/team/eng\" {\n capabilities = [\"create\", \"read\", \"delete\", \"update\"]\n }"
|
||||
}
|
||||
EOF
|
||||
|
||||
# Create base policy
|
||||
$ curl --header "X-Vault-Token: ..." \
|
||||
@ -850,7 +856,7 @@ group member and attach `team-eng`.
|
||||
|
||||
```shell
|
||||
# API request msg payload. Be sure to replace <ENTITY_ID> with correct value
|
||||
$ tee payload-group.json <<<EOF
|
||||
$ tee payload-group.json <<EOF
|
||||
{
|
||||
"name": "engineers",
|
||||
"policies": ["team-eng"],
|
||||
@ -985,10 +991,11 @@ $ vault write identity/group-alias name="training" \
|
||||
```shell
|
||||
# API request payload containing stringfied policy
|
||||
# If you are running KV v2, set the path to "secret/data/education" instead
|
||||
$ cat payload-pol.json
|
||||
$ tee payload-pol.json <<EOF
|
||||
{
|
||||
"policy": "path \"secret/education\" {\n capabilities = [\"create\", \"read\", \"delete\", \"update\", \"list\"]\n }"
|
||||
}
|
||||
EOF
|
||||
|
||||
# Create education policy
|
||||
$ curl --header "X-Vault-Token: ..." \
|
||||
@ -1021,7 +1028,7 @@ $ curl --header "X-Vault-Token: ..." \
|
||||
}
|
||||
|
||||
# API request msg payload to create an external group
|
||||
$ tee payload-edu.json <<<EOF
|
||||
$ tee payload-edu.json <<EOF
|
||||
{
|
||||
"name": "education",
|
||||
"policies": ["education"],
|
||||
|
@ -45,3 +45,7 @@ identity.
|
||||
- [Sentinel Policies](/guides/identity/sentinel.html) guide
|
||||
walks through the creation and usage of _Role Governing Policies_ (RGPs) and
|
||||
_Endpoint Governing Policies_ (EGPs) in Vault.
|
||||
|
||||
- [Control Groups](/guides/identity/control-groups.html) can be used to enforce
|
||||
additional authorization factors before the request can be completed. This
|
||||
guide walks through the implementation of a Control Group.
|
||||
|
@ -75,6 +75,9 @@
|
||||
<li<%= sidebar_current("guides-identity-sentinel") %>>
|
||||
<a href="/guides/identity/sentinel.html">Sentinel Policies</a>
|
||||
</li>
|
||||
<li<%= sidebar_current("guides-identity-control-groups") %>>
|
||||
<a href="/guides/identity/control-groups.html">Control Groups</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|