---
# System prepended metadata

title: OPA-MongoDB Data filtering

---

# OPA-MongoDB Data filtering

This is cli tool to integrate OPA with mongo database.

Available commands & flags:
```
$ ./opa-mongo --help
This CLI lets you to integrate OPA with mongo DB. You can store larger contexts 
that needs OPA evaluation in mongo database and defines the unknowns in rego policies
accordingly for evaluation and the unknowns are fetched from mongo with this cli

Note: Before you run this CLI make sure you have working mongo database that is accessible through this cli.

Usage:
  opa_mongo [command]

Available Commands:
  help        Help about any command
  run         Run OPA with Mongo DB as server
  test        This command inserts static employee data for development & testing purposes.

Flags:
  -c, --config.file string   configuration file.
  -h, --help                 help for opa_mongo

Use "opa-mongo [command] --help" for more information about a command.
```

You can deploy opa-mongo server in two ways:

1. Docker
2. Kubernetes

### Deploying as container:

Prerequisites:

* Docker

#### Step 1:

Running Mongo DB as container:

```
docker run -d -e MONGO_INITDB_ROOT_USERNAME=admin -e MONGO_INITDB_ROOT_PASSWORD=password -p 27017:27017 mongo
```

#### Step 2:

Configure the mongo db details in the config file as shown below in a file named ```config.yaml```:

```
cfg:
  address: <node-ip>:27017
  database: opa-mongo
  username: admin
  password: password
``` 

#### Step 3: 

Add example rego policy into the file named ```example.rego```:

```
package details.authz

allow {
  input.method == "GET"
  employee := data.employees[_]
  employee.name == input.user
  employee.name == input.path[1]
}

allow {
  input.method == "GET"
  employee := data.employees[_]
  employee.manager == input.user
  employee.name == input.path[1]
}

allow {
  input.method == "GET"
  input.path = ["employees"]
  employee := data.employees[_]
  input.user == "danerys"
  employee.salary > 0
  employee.salary < 300000
}
```

#### Step 4:

Below cmd lets you to start opa server with mongo db and on opa server startup, we insert sample data.

```
$ docker run -d -p 9095:9095 -v /config.yaml:/opa/config.yaml /
    -v /example.rego:/opa/example.rego vineeth97/opa-mongo:latest
```



### Deploying in Kubernetes:

Pre-requisites:

1. kubectl
2. kind - https://kind.sigs.k8s.io/

#### Step 1:

Create a Kubernetes cluster 

```
kind create cluster
```

#### Step 2:

Running opa-mongo server with mongo database

```
kubectl create -f https://github.com/open-policy-agent/contrib/blob/master/data_filter_mongodb/k8s/opa-mongo.yaml
```

By now you have running opa-mongo server with mongo database. Now let's query the data from opa-mongo server.

### View the data that exists in mongo database:

You can view all the data that exist in the mongo database by accessing the below URL. This endpoint is exposed for viewing the data that exists in the database.

```
http://localhost:9095/records
```

This opa-mongo server is designed to retreive employee details. The employee details can be seen either by the employee or by respective manager. 

Below are records that are inserted on opa server startup:

```
[
  {
    "Name": "john",
    "Designation": "lead engineer",
    "Salary": 270000,
    "Email": "john@opa.com",
    "Mobile": "1233743438738",
    "Manager": "danerys"
  },
  {
    "Name": "arya",
    "Designation": "software engineer",
    "Salary": 90000,
    "Email": "arya@opa.com",
    "Mobile": "1233746238738",
    "Manager": "john"
  },
  {
    "Name": "tyrian",
    "Designation": "senior software engineer",
    "Salary": 250000,
    "Email": "tyrian@opa.com",
    "Mobile": "123336238738",
    "Manager": "danerys"
  },
  {
    "Name": "jamie",
    "Designation": "lead engineer",
    "Salary": 70000,
    "Email": "jamie@opa.com",
    "Mobile": "1233746238738",
    "Manager": "danerys"
  },
  {
    "Name": "jeffrey",
    "Designation": "software engineer",
    "Salary": 60000,
    "Email": "jeffrey@opa.com",
    "Mobile": "1233746238738",
    "Manager": "jamie"
  },
  {
    "Name": "sansa",
    "Designation": "senior software engineer",
    "Salary": 80000,
    "Email": "sansa@opa.com",
    "Mobile": "1233746238738",
    "Manager": "john"
  },
  {
    "Name": "ramsay",
    "Designation": "software engineer",
    "Salary": 70000,
    "Email": "ramsay@opa.com",
    "Mobile": "1233746238738",
    "Manager": "john"
  },
  {
    "Name": "cersei",
    "Designation": "senior software engineer",
    "Salary": 170000,
    "Email": "cersei@opa.com",
    "Mobile": "1233746238738",
    "Manager": "jamie"
  },
  {
    "Name": "theon",
    "Designation": "software engineer",
    "Salary": 75000,
    "Email": "theon@opa.com",
    "Mobile": "1233746238738",
    "Manager": "john"
  },
  {
    "Name": "rob",
    "Designation": "software engineer",
    "Salary": 75000,
    "Email": "rob@opa.com",
    "Mobile": "1343238738",
    "Manager": "john "
  },
  {
    "Name": "danerys",
    "Designation": "director of engineering",
    "Salary": 350000,
    "Email": "danerys@opa.com",
    "Mobile": "12332423738",
    "Manager": "nil"
  }
]
```

### Querying opa-mongo server:

Below is the request you can make to opa server:

This requests for employee john details as we notice request param and path in request body says john, and the request body expects the requested user name. Based on the rego policy the requested user should be either the employee or the respective manager to retrieve the employee details.

```
URL: http://localhost:9095/employees/john
```
Request body:
```
{
    "input": {
        "method": "GET",
        "path": ["employees", "john"],
        "user": "danerys"
    }
}
```

Response:
```
{
    "result": {
        "Defined": true,
        "Data": [
            {
                "Name": "john",
                "Designation": "lead engineer",
                "Salary": 270000,
                "Email": "john@opa.com",
                "Mobile": "1233743438738",
                "Manager": "danerys"
            }
        ]
    }
}
```

In opa-mongo server logs you can observe the received query, equivalent opa-query and the equivalent mongo-query based on the rego policy:

```
2020/08/07 18:15:45 received requestmap[method:GET path:[employees john] user:danery]
2020/08/07 18:15:45 opa-query: ["danery" = data.employees[_].name; "john" = data.employees[_].name "danery" = data.employees[_].manager; "john" = data.employees[_].name]
2020/08/07 18:15:45 mongo query: map[$or:[map[$and:[map[name:map[$eq:danery]] map[name:map[$eq:john]]]] map[$and:[map[manager:map[$eq:danery]] map[name:map[$eq:john]]]]]]
```

Now you have successfully retrevied john details by requesting the opa-mongo server by enforcing the policies from the mongo database.