> For the complete documentation index, see [llms.txt](https://v2.dataos.info/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://v2.dataos.info/references/v1/resources/nilus/roles-and-permissions/mongodb-minimum-permissions.md).

# MongoDB

This page documents the minimum MongoDB grants a platform or database administrator must provision for Nilus to run batch, CDC, and metadata pipelines against a MongoDB depot. It is validated against Nilus 2.0.

## Pipeline modes supported

| Pipeline type    | URI prefix            | Description                                                     |
| ---------------- | --------------------- | --------------------------------------------------------------- |
| `type: batch`    | `mongodb://`          | Full or incremental reads and writes                            |
| `type: cdc`      | `debezium+mongodb://` | Change stream capture (requires replica set or sharded cluster) |
| `type: metadata` | `metadata+mongodb://` | Hera metadata ingestion                                         |

Nilus supports two write strategies for MongoDB destinations: `replace` and `merge`. It does not support `append`.

## Read data: MongoDB as source (`type: batch`)

Nilus uses this path when the depot is referenced in `source.address` of a pipeline config. Nilus reads documents from the target collection using the MongoDB driver.

### Minimum grants

```javascript
db.getSiblingDB("admin").createUser({
  user: "nilus_reader",
  pwd: "<password>",
  roles: [
    { role: "read", db: "<database_name>" }
  ]
})
```

The built-in `read` role covers `find`, `listCollections`, `listIndexes`, `dbStats`, and `collStats` on the target database.

To restrict access to a specific collection, grant a custom role with only `find` on that collection instead of the database-level `read` role.

## Write data: MongoDB as destination (`type: batch`, `type: cdc`)

Nilus uses this path when the depot is referenced in `sink.address` of a pipeline config.

### Minimum grants

```javascript
db.getSiblingDB("admin").createUser({
  user: "nilus_writer",
  pwd: "<password>",
  roles: [
    { role: "readWrite", db: "<database_name>" }
  ]
})
```

### Grants by write strategy

| Strategy  | Operations used                   | Role required |
| --------- | --------------------------------- | ------------- |
| `replace` | `delete_many({})` + `insert_many` | `readWrite`   |
| `merge`   | `upsert` (insert + update)        | `readWrite`   |

The built-in `readWrite` role covers all required operations for both strategies. Writes need no custom role.

## CDC source: MongoDB (`type: cdc`)

Nilus captures document-level changes through MongoDB change streams, not direct oplog reads. The Debezium MongoDB connector manages the change stream cursor and offset tracking.

### Infrastructure prerequisite

MongoDB must run as a replica set or sharded cluster. Standalone servers do not support change streams and are not supported.

Set the `replicaSet` parameter in `depot spec.params`.

### Connector behavior: `allChangesForCluster: true`

The Nilus Debezium MongoDB connector always opens a deployment-wide change stream using `{ $changeStream: { allChangesForCluster: true } }`, executed as a collectionless `aggregate` against `$db: admin`. This applies even when only a single collection (for example, `nilusdb.orders`) is targeted: Debezium filters client-side after opening the cluster-wide cursor.

A database-scoped `read` role alone is not sufficient. The CDC user must have `changeStream` and `find` privileges at the all-databases level, not just on the captured database. This was confirmed empirically: with only `read` on the source database, the connector fails with `error 13 (Unauthorized)` on the `admin` aggregate. The pipeline succeeded only after cluster-wide privileges were granted.

{% hint style="warning" %}
The connector always opens a cluster-wide change stream (`allChangesForCluster: true`), even when the pipeline targets a single collection. Grant the CDC user cluster-wide `changeStream` and `find` privileges (`readAnyDatabase` and `clusterMonitor` on `admin`), not just read access to the captured database. A database-scoped `read` role alone fails with `error 13 (Unauthorized)`.
{% endhint %}

### Minimum grants

```javascript
db.getSiblingDB("admin").createUser({
  user: "cdc_user",
  pwd: "<password>",
  roles: [
    { role: "read", db: "<captured_database>" },
    { role: "clusterMonitor", db: "admin" }
  ]
})
```

For a sharded cluster, add read access to the `config` database:

```javascript
// Additional role for sharded cluster topology
{ role: "read", db: "config" }
```

`clusterMonitor` is required to run the `hello` command and read replica set and cluster metadata. Without it, the Debezium connector cannot resolve the cluster topology at startup.

Because Nilus uses `allChangesForCluster: true`, `clusterMonitor` alone is not sufficient. The CDC user also needs cluster-wide `changeStream` and `find` privileges. The mandatory minimum, regardless of how many databases are captured, is:

```javascript
{ role: "readAnyDatabase", db: "admin" },
{ role: "clusterMonitor", db: "admin" }
```

## Hera metadata ingestion: MongoDB source connector (`type: metadata`)

Nilus uses this path when the depot is referenced in `source.address` of a `type: metadata` pipeline. Nilus drives the Hera MongoDB source connector.

### Workflows that run for MongoDB

Nilus conditionally gates metadata workflow steps based on the source type. For MongoDB, only the following steps run:

| Workflow step                            | Runs? | Mode                               |
| ---------------------------------------- | ----- | ---------------------------------- |
| Metadata (collections, schemas, columns) | Yes   | Always                             |
| Profiler (row counts, sample data)       | Yes   | `deep` mode only                   |
| Classification                           | Yes   | `deep` mode only                   |
| Lineage                                  | No    | Skipped: not supported for MongoDB |
| Usage                                    | No    | Skipped: not supported for MongoDB |

Lineage and usage are permanently excluded for MongoDB at the orchestration level (`nilus-domain.yaml`), regardless of permissions.

### Minimum grants

```javascript
db.getSiblingDB("admin").createUser({
  user: "hera_user",
  pwd: "<password>",
  roles: [
    { role: "read", db: "<database_name>" }
  ]
})
```

The `read` role covers both required operations:

* `find` on collections
* `listCollections` on the database

No system table access or additional grants are needed for any MongoDB metadata workflow.

## Permission matrix

| Use case                                  | Role                               | Scope                                  |
| ----------------------------------------- | ---------------------------------- | -------------------------------------- |
| Read (source, batch)                      | `read`                             | Target database                        |
| Write, `replace`                          | `readWrite`                        | Target database                        |
| Write, `merge`                            | `readWrite`                        | Target database                        |
| CDC source                                | `read` + `clusterMonitor`          | Captured database + `admin`            |
| CDC source (sharded)                      | `read` + `clusterMonitor` + `read` | Captured database + `admin` + `config` |
| Hera metadata / profiler / classification | `read`                             | Target database                        |

## Notes

* Replica set is required for CDC. Standalone MongoDB servers do not support change streams. Set the `replicaSet` parameter in the depot spec `params`.
* `authSource` must match the user's admin database. If the user is created in the `admin` database, set `params.authSource = "admin"`. A mismatched `authSource` causes authentication failures.
* `append` is not a supported write strategy. Only `replace` and `merge` are supported for MongoDB destinations.
* MongoDB has no lineage or usage workflow. Nilus excludes these workflows at the orchestration level, and no additional grants enable them.
* `readWrite` covers all write operations. Both `replace` (delete and insert) and `merge` (upsert) are covered by the built-in `readWrite` role.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://v2.dataos.info/references/v1/resources/nilus/roles-and-permissions/mongodb-minimum-permissions.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
