MongoDBAuthorization & RBAC

Authorization & Role-Based Access Control

Authentication answers "who are you?" — authorization answers "what are you allowed to do?" MongoDB implements authorization through Role-Based Access Control (RBAC): every user has one or more roles, and every role is a bundle of specific privileges.

Built-in Roles

Role

Grants

read

Read data on a specific database

readWrite

Read and write data on a specific database

dbAdmin

Schema/index management, stats — no data read/write

userAdmin

Create and manage users and roles on a database — no data access

dbOwner

Combination of readWrite + dbAdmin + userAdmin on a database

readAnyDatabase

Read access across every database in the cluster

readWriteAnyDatabase

Read/write access across every database in the cluster

clusterAdmin

Cluster-wide administrative actions (replication, sharding config)

clusterMonitor

Read-only access to monitoring/diagnostic data cluster-wide

backup / restore

Privileges needed to run backup/restore tooling

root

Superuser — combines the most powerful built-in roles; avoid for application users

Granting and Revoking Roles

JS
use shop
db.grantRolesToUser("appUser", [{ role: "readWrite", db: "shop" }])
db.revokeRolesFromUser("appUser", [{ role: "dbAdmin", db: "shop" }])

// Inspect a user's current roles and privileges
db.getUser("appUser")
Custom Roles — Resource + Actions

When built-in roles are too broad, define a custom role as a set of privileges — each privilege pairs a resource (database + collection) with a list of allowed actions.

Custom role: write orders, read-only everywhere else

JS
db.createRole({
  role: "orderServiceRole",
  privileges: [
    {
      resource: { db: "shop", collection: "orders" },
      actions: ["find", "insert", "update"]
    },
    {
      resource: { db: "shop", collection: "products" },
      actions: ["find"]
    }
  ],
  roles: []   // can also compose from existing roles instead of raw privileges
})

db.grantRolesToUser("orderService", [{ role: "orderServiceRole", db: "shop" }])
Least-Privilege Examples

A concrete pattern: give every distinct workload its own user with only the privileges that workload needs.

Application user — readWrite on its own database only

JS
db.createUser({
  user: "appUser",
  pwd: passwordPrompt(),
  roles: [{ role: "readWrite", db: "shop" }]
})

Analytics user — read-only, across a couple of databases

JS
db.createUser({
  user: "analyticsUser",
  pwd: passwordPrompt(),
  roles: [
    { role: "read", db: "shop" },
    { role: "read", db: "billing" }
  ]
})

Backup user — the built-in backup role only, nothing else

JS
db.createUser({
  user: "backupAgent",
  pwd: passwordPrompt(),
  roles: [{ role: "backup", db: "admin" }]
})
Tip
A backup user with only the backup role can run mongodump across the deployment, but cannot read individual document contents through normal queries or modify any data — exactly the access a backup job needs and nothing more.
Viewing Effective Privileges

JS
db.getUser("appUser", { showPrivileges: true })
db.getRole("orderServiceRole", { showPrivileges: true })
Common Actions Reference

Action

Covers

find

Read documents

insert

Insert documents

update

Modify existing documents

remove

Delete documents

createIndex / dropIndex

Manage indexes

createCollection / dropCollection

Manage collections

changeStream

Open change streams on the resource

listCollections / listIndexes

Introspect schema/index metadata

Warning
Avoid granting root or dbOwner to application service accounts. If a service is compromised, its blast radius should be limited to what that specific service actually needs to touch — least privilege is the single biggest lever you have against a credential leak turning into a full data breach.
Summary
  • RBAC bundles specific privileges (resource + action) into roles, which are then assigned to users.

  • Built-in roles cover most common needs (read, readWrite, dbAdmin, cluster roles) — reach for custom roles when you need finer-grained control.

  • Design one user per workload (application, analytics, backup) scoped to exactly what that workload needs.

  • Regularly audit db.getUser(..., { showPrivileges: true }) output for accounts holding more access than they use.