diff --git a/website/source/assets/images/vault-ctrl-grp-1.png b/website/source/assets/images/vault-ctrl-grp-1.png
new file mode 100644
index 0000000000..d4173ed4c6
Binary files /dev/null and b/website/source/assets/images/vault-ctrl-grp-1.png differ
diff --git a/website/source/assets/images/vault-ctrl-grp-2.png b/website/source/assets/images/vault-ctrl-grp-2.png
new file mode 100644
index 0000000000..883ba16a83
Binary files /dev/null and b/website/source/assets/images/vault-ctrl-grp-2.png differ
diff --git a/website/source/assets/images/vault-ctrl-grp-3.png b/website/source/assets/images/vault-ctrl-grp-3.png
new file mode 100644
index 0000000000..2d61b698bc
Binary files /dev/null and b/website/source/assets/images/vault-ctrl-grp-3.png differ
diff --git a/website/source/assets/images/vault-ctrl-grp-4.png b/website/source/assets/images/vault-ctrl-grp-4.png
new file mode 100644
index 0000000000..0bcde5953e
Binary files /dev/null and b/website/source/assets/images/vault-ctrl-grp-4.png differ
diff --git a/website/source/assets/images/vault-ctrl-grp-5.png b/website/source/assets/images/vault-ctrl-grp-5.png
new file mode 100644
index 0000000000..052de99c3f
Binary files /dev/null and b/website/source/assets/images/vault-ctrl-grp-5.png differ
diff --git a/website/source/assets/images/vault-ctrl-grp-6.png b/website/source/assets/images/vault-ctrl-grp-6.png
new file mode 100644
index 0000000000..76c0ddccff
Binary files /dev/null and b/website/source/assets/images/vault-ctrl-grp-6.png differ
diff --git a/website/source/assets/images/vault-ctrl-grp-7.png b/website/source/assets/images/vault-ctrl-grp-7.png
new file mode 100644
index 0000000000..d85b2992ba
Binary files /dev/null and b/website/source/assets/images/vault-ctrl-grp-7.png differ
diff --git a/website/source/guides/identity/control-groups.html.md b/website/source/guides/identity/control-groups.html.md
new file mode 100644
index 0000000000..31b071a6eb
--- /dev/null
+++ b/website/source/guides/identity/control-groups.html.md
@@ -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.
+
+
+### 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"
+ ```
+
+### 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 <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**.
+
+
+### 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=
+
+ # To approve the request
+ $ vault write sys/control-group/authorize accessor=
+ ```
+
+ **Example:**
+
+ ```shell
+ # Check the current status
+ $ vault write sys/control-group/request accessor=bbb4deef-e06d-9b2a-64a9-56f815c69ee7
+ Key Value
+ --- -----
+ approved false
+ authorizations
+ 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
+ $ 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: " \
+ 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 `` with the `accessor` value you
+copied earlier.)
+
+ ```shell
+ # To check the current status using sys/control-group/request endpoint
+ $ curl --header "X-Vault-Token: " \
+ --request POST \
+ --data '{"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: " \
+ --request POST \
+ --data '{"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: " \
+ --request POST \
+ --data '{"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.
+
+
+### 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.
diff --git a/website/source/guides/identity/identity.html.md b/website/source/guides/identity/identity.html.md
index 0a30579bf6..48585efcb2 100644
--- a/website/source/guides/identity/identity.html.md
+++ b/website/source/guides/identity/identity.html.md
@@ -351,10 +351,11 @@ attached.
```shell
# Create the API request payload, payload-1.json
- $ cat payload-1.json
+ $ tee payload-1.json < with correct value
- $ tee payload-group.json <<>
Sentinel Policies
+ >
+ Control Groups
+