# Access Control Lists - Enterprise features

**URL:** <https://discuss.dgraph.io/t/access-control-lists-enterprise-features/9801>\
**Category:** Documentation\
**Created:** [August 28, 2020, 5:50pm UTC](https://discuss.dgraph.io/t/access-control-lists-enterprise-features/9801 "2020-08-28T17:50:30Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![diggy](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/diggy/32/3666_2.png) [@diggy](https://discuss.dgraph.io/u/diggy)\
**Post date:** [August 28, 2020, 5:50pm UTC](https://discuss.dgraph.io/t/access-control-lists-enterprise-features/9801/1 "2020-08-28T17:50:30Z")

</div>

Note This feature was introduced in [v1.1.0](https://github.com/dgraph-io/dgraph/releases/tag/v1.1.0). The Dgraph ACL tool is deprecated and would be removed in the next release. ACL changes can be made by using the `/admin` GraphQL endpoint on any Alpha node.

Access Control List (ACL) provides access protection to your data stored in Dgraph. When the ACL feature is turned on, a client, e.g. dgo or dgraph4j, must authenticate with a username and password before executing any transactions, and is only allowed to access the data permitted by the ACL rules.

This document has two parts: first we will talk about the admin operations needed for setting up ACL; then we will explain how to use a client to access the data protected by ACL rules.

## Turn on ACLs

The ACL Feature can be turned on by following these steps

1. Since ACL is an enterprise feature, make sure your use case is covered under a contract with Dgraph Labs Inc. You can contact us by sending an email to [[email&nbsp;protected]](https://dgraph.io/cdn-cgi/l/email-protection#7f1c10110b1e1c0b3f1b180d1e0f17511610) or post your request at [our discuss forum](http://discuss.hypermode.com) to get an enterprise license.

2. Create a plain text file, and store a randomly generated secret key in it. The secret key is used by Alpha servers to sign JSON Web Tokens (JWT). As you’ve probably guessed, it’s critical to keep the secret key as a secret. Another requirement for the secret key is that it must have at least 256-bits, i.e. 32 ASCII characters, as we are using HMAC-SHA256 as the signing algorithm.

3. Start all the alpha servers in your cluster with the option `--acl_secret_file`, and make sure they are all using the same secret key file created in Step 2.

Here is an example that starts one zero server and one alpha server with the ACL feature turned on:

```
dgraph zero --my=localhost:5080 --replicas 1 --idx 1 --bindall --expose_trace --profile_mode block --block_rate 10 --logtostderr -v=2
dgraph alpha --my=localhost:7080 --lru_mb=1024 --zero=localhost:5080 --logtostderr -v=3 --acl_secret_file ./hmac-secret

```

If you are using docker-compose, a sample cluster can be set up by:

1. `cd $GOPATH/src/github.com/dgraph-io/dgraph/compose/`
2. `make`
3. `./compose -e --acl_secret <path to your hmac secret file>`, after which a `docker-compose.yml` file will be generated.
4. `docker-compose up` to start the cluster using the `docker-compose.yml` generated above.

## Set up ACL Rules

Now that your cluster is running with the ACL feature turned on, you can set up the ACL rules. This can be done using the web UI Ratel or by using a GraphQL tool which fires the mutations. Execute the following mutations using a GraphQL tool like Insomnia, GraphQL Playground or GraphiQL.

A typical workflow is the following:

1. Reset the root password
2. Create a regular user
3. Create a group
4. Assign the user to the group
5. Assign predicate permissions to the group

### Using GraphQL Admin API

Note All these mutations require passing an `X-Dgraph-AccessToken` header, value for which can be obtained after logging in.

1) Reset the root password. The example below uses the dgraph endpoint `localhost:8080/admin`as a demo, make sure to choose the correct IP and port for your environment:

```
mutation {
  updateUser(input: {filter: {name: {eq: "groot"}}, set: {password: "newpassword"}}) {
    user {
      name
    }
  }
}

```

The default password is `password`. `groot` is part of a special group called `guardians`. Members of `guardians` group will have access to everything. You can add more users to this group if required.

2) Create a regular user

```
mutation {
  addUser(input: [{name: "alice", password: "newpassword"}]) {
    user {
      name
    }
  }
}

```

Now you should see the following output

```
{
  "data": {
    "addUser": {
      "user": [
        {
          "name": "alice"
        }
      ]
    }
  }
}

```

3) Create a group

```
mutation {
  addGroup(input: [{name: "dev"}]) {
    group {
      name
      users {
        name
      }
    }
  }
}

```

Now you should see the following output

```
{
  "data": {
    "addGroup": {
      "group": [
        {
          "name": "dev",
          "users": []
        }
      ]
    }
  }
}

```

4) Assign the user to the group To assign the user `alice` to both the group `dev` and the group `sre`, the mutation should be

```
mutation {
  updateUser(input: {filter: {name: {eq: "alice"}}, set: {groups: [{name: "dev"}, {name: "sre"}]}}) {
    user {
      name
      groups {
        name
    }
    }
  }
}

```

5) Assign predicate permissions to the group

```
mutation {
  updateGroup(input: {filter: {name: {eq: "dev"}}, set: {rules: [{predicate: "friend", permission: 7}]}}) {
    group {
      name
      rules {
        permission
        predicate
      }
    }
  }
}

```

Here we assigned a permission rule for the friend predicate to the group. In case you have [reverse edges](https://dgraph.io/docs/query-language/schema/#reverse-edges), they have to be given the permission to the group as well

```
mutation {
  updateGroup(input: {filter: {name: {eq: "dev"}}, set: {rules: [{predicate: "~friend", permission: 7}]}}) {
    group {
      name
      rules {
        permission
        predicate
      }
    }
  }
}

```

You can also resolve this by using the `dgraph acl` tool

```
dgraph acl -a <ALPHA_ADDRESS:PORT> -w <GROOT_USER> -x <GROOT_PASSWORD> mod --group dev --pred ~friend --perm 7

```

The command above grants the `dev` group the `READ`+`WRITE`+`MODIFY` permission on the `friend` predicate. Permissions are represented by a number following the UNIX file permission convention. That is, 4 (binary 100) represents `READ`, 2 (binary 010) represents `WRITE`, and 1 (binary 001) represents `MODIFY` (the permission to change a predicate’s schema). Similarly, permisson numbers can be bitwise OR-ed to represent multiple permissions. For example, 7 (binary 111) represents all of `READ`, `WRITE` and `MODIFY`. In order for the example in the next section to work, we also need to grant full permissions on another predicate `name` to the group `dev`. If there are no rules for a predicate, the default behavior is to block all (`READ`, `WRITE` and `MODIFY`) operations.

```
mutation {
  updateGroup(input: {filter: {name: {eq: "dev"}}, set: {rules: [{predicate: "name", permission: 7}]}}) {
    group {
      name
      rules {
        permission
        predicate
      }
    }
  }
}

```

## Retrieve Users and Groups Information

Note All these queries require passing an `X-Dgraph-AccessToken` header, value for which can be obtained after logging in.

The following examples show how to retrieve information about users and groups.

1) Check information about a user

```
query {
  getUser(name: "alice") {
    name
    groups {
      name
    }
  }
}

```

and the output should show the groups that the user has been added to, e.g.

```
{
  "data": {
    "getUser": {
      "name": "alice",
      "groups": [
        {
          "name": "dev"
        }
      ]
    }
  }
}

```

2) Check information about a group

```
{
  getGroup(name: "dev") {
    name
    users {
      name
    }
    rules {
      permission
      predicate
    }
  }
}

```

and the output should include the users in the group, as well as the permissions, the group’s ACL rules, e.g.

```
{
  "data": {
    "getGroup": {
      "name": "dev",
      "users": [
        {
          "name": "alice"
        }
      ],
      "rules": [
        {
          "permission": 7,
          "predicate": "friend"
        },
        {
          "permission": 7,
          "predicate": "name"
        }
      ]
    }
  }
}

```

3) Query for users

```
query {
  queryUser(filter: {name: {eq: "alice"}}) {
    name
    groups {
      name
    }
  }
}

```

and the output should show the groups that the user has been added to, e.g.

```
{
  "data": {
    "queryUser": [
      {
        "name": "alice",
        "groups": [
          {
            "name": "dev"
          }
        ]
      }
    ]
  }
}

```

4) Query for groups

```
query {
  queryGroup(filter: {name: {eq: "dev"}}) {
    name
    users {
      name
    }
    rules {
      permission
      predicate
    }
  }
}

```

and the output should include the users in the group, as well as the permissions the group’s ACL rules, e.g.

```
{
  "data": {
    "queryGroup": [
      {
        "name": "dev",
        "users": [
          {
            "name": "alice"
          }
        ],
        "rules": [
          {
            "permission": 7,
            "predicate": "friend"
          },
          {
            "permission": 7,
            "predicate": "name"
          }
        ]
      }
    ]
  }
}

```

5) Run ACL commands as another guardian (member of `guardians` group).

You can also run ACL commands with other users. Say we have a user `alice` which is member of `guardians` group and its password is `simple_alice`.

## Access Data Using a Client

Now that the ACL data are set, to access the data protected by ACL rules, we need to first log in through a user. This is tyically done via the client’s `.login(USER_ID, USER_PASSWORD)` method.

A sample code using the dgo client can be found [here](https://github.com/dgraph-io/dgraph/blob/master/tlstest/acl/acl_over_tls_test.go). An example using dgraph4j can be found [here](https://github.com/dgraph-io/dgraph4j/blob/master/src/test/java/io/dgraph/AclTest.java).

## Access Data Using the GraphQL API

Dgraph’s HTTP API also supports authenticated operations to access ACL-protected data.

To login, send a POST request to `/admin` with the GraphQL mutation. For example, to log in as the root user groot:

```
mutation {
  login(userId: "groot", password: "password") {
    response {
      accessJWT
      refreshJWT
    }
  }
}

```

Response:

```
{
  "data": {
    "accessJWT": "<accessJWT>",
    "refreshJWT": "<refreshJWT>"
  }
}

```

The response includes the access and refresh JWTs which are used for the authentication itself and refreshing the authentication token, respectively. Save the JWTs from the response for later HTTP requests.

You can run authenticated requests by passing the accessJWT to a request via the `X-Dgraph-AccessToken` header. Add the header `X-Dgraph-AccessToken` with the `accessJWT` value which you got in the login response in the GraphQL tool which you’re using to make the request. For example:

```
mutation {
  addUser(input: [{name: "alice", password: "newpassword"}]) {
    user {
      name
    }
  }
}

```

The refresh token can be used in the `/admin` POST GraphQL mutation to receive new access and refresh JWTs, which is useful to renew the authenticated session once the ACL access TTL expires (controlled by Dgraph Alpha’s flag `--acl_access_ttl` which is set to 6h0m0s by default).

```
mutation {
  login(userId: "groot", password: "newpassword", refreshToken: "<refreshJWT>") {
    response {
      accessJWT
      refreshJWT
    }
  }
}

```

## Reset Groot Password

If you’ve forgotten the password to your groot user, then you may reset the groot password (or the password for any user) by following these steps.

1. Stop Dgraph Alpha.
2. Turn off ACLs by removing the `--acl_hmac_secret` config flag in the Alpha config. This leaves the Alpha open with no ACL rules, so be sure to restrict access, including stopping request traffic to this Alpha.
3. Start Dgraph Alpha.
4. Connect to Dgraph Alpha using Ratel and run the following upsert mutation to update the groot password to `newpassword` (choose your own secure password):

5. Restart Dgraph Alpha with ACLs turned on by setting the `--acl_hmac_secret` config flag.

6. Login as groot with your new password.

* * *
This is a companion discussion topic for the original entry at [https://dgraph.io/docs/enterprise-features/access-control-lists/](https://dgraph.io/docs/enterprise-features/access-control-lists/)
