0Pricing
MongoDB Academy · Lesson

Role-Based Access Control: Built-In and Custom Roles

Learners will assign built-in roles like readWrite and dbAdmin, and create custom roles with least-privilege action sets for service accounts.

Role-Based Access Control: Built-In and Custom Roles is a free MongoDB Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the MongoDB Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

What Is Role-Based Access Control?

Role-Based Access Control (RBAC) is MongoDB's authorization model. Instead of granting individual permissions directly to users, you assign roles — named collections of privileges — to users. This makes permission management scalable: update a role and every user holding that role inherits the change automatically. MongoDB ships with a rich set of built-in roles covering the most common access patterns.

Built-In Database Roles

MongoDB provides several database-level roles that apply to a specific database. The most commonly used are: read (read all collections), readWrite (read + insert/update/delete), dbAdmin (schema management, index creation), and userAdmin (create/modify users in that database). These roles are database-scoped — a user with readWrite on myApp cannot access otherApp.

// Create a user with readWrite on one database only
use myApp
db.createUser({
  user: 'appUser',
  pwd: 'SecurePass!',
  roles: [
    { role: 'readWrite', db: 'myApp' }
  ]
})

// Create a user with dbAdmin (can manage indexes but not data)
db.createUser({
  user: 'dbaUser',
  pwd: 'DbaPass!',
  roles: [
    { role: 'dbAdmin', db: 'myApp' }
  ]
})

Built-In Cluster-Wide Roles

Some built-in roles span all databases on a MongoDB instance. readAnyDatabase and readWriteAnyDatabase grant their respective permissions across every database. dbAdminAnyDatabase allows schema management everywhere. The most powerful is root, which has full access to everything — use it only for initial setup and emergency recovery, never for application accounts.

// Grant read-only access to all databases (reporting tool)
use admin
db.createUser({
  user: 'globalReporter',
  pwd: 'ReportPass!',
  roles: [
    { role: 'readAnyDatabase', db: 'admin' }
  ]
})

// The root role — avoid for applications
// roles: [{ role: 'root', db: 'admin' }]  // too powerful!

The Principle of Least Privilege

Every MongoDB user should have exactly the permissions they need — no more. An API that only reads products should have read, not readWrite. A background job that archives documents should only be able to query and delete from the archive collection — not from all collections. Applying least privilege limits the blast radius of a compromised credential.

// Tightly scoped user for a product listing API
use admin
db.createUser({
  user: 'productListingApi',
  pwd: 'ProductApiPass!',
  roles: [
    { role: 'read', db: 'catalog' }  // read-only on catalog DB only
  ]
})

Creating Custom Roles

When built-in roles are too broad, create a custom role using db.createRole(). A role definition lists specific privileges — each privilege is an action (e.g., find, insert, createIndex) on a resource (a specific database, collection, or cluster). Custom roles can also inherit from existing roles using the roles array.

// Custom role: can read orders and update order status only
use myApp
db.createRole({
  role: 'orderProcessor',
  privileges: [
    {
      resource: { db: 'myApp', collection: 'orders' },
      actions: ['find', 'update']
    }
  ],
  roles: []  // no inherited roles
})

Assigning Custom Roles to Users

Assign a custom role the same way you assign built-in roles — include it in the roles array when creating a user or grant it later with db.grantRolesToUser(). A user can hold multiple roles simultaneously, combining their permissions. MongoDB computes the union of all privileges from all assigned roles when authorizing each operation.

// Create user and assign custom role
use myApp
db.createUser({
  user: 'fulfillmentWorker',
  pwd: 'FulfillPass!',
  roles: [
    { role: 'orderProcessor', db: 'myApp' }
  ]
})

// Grant an additional role to an existing user
db.grantRolesToUser('fulfillmentWorker', [
  { role: 'read', db: 'products' }
])

Revoking Roles and Modifying Access

When an employee changes roles or a service is decommissioned, revoke unnecessary permissions promptly. db.revokeRolesFromUser() removes specific roles from a user without deleting the account. db.updateUser() lets you replace the entire roles array. Regularly audit users and their assigned roles with db.getUsers() to catch privilege creep.

// Revoke a specific role from a user
use myApp
db.revokeRolesFromUser('fulfillmentWorker', [
  { role: 'read', db: 'products' }
])

// Replace all roles for a user
db.updateUser('fulfillmentWorker', {
  roles: [{ role: 'read', db: 'myApp' }]  // demote to read-only
})

Collection-Level Privilege Granularity

Custom roles can be scoped to a specific collection rather than an entire database. This allows fine-grained access control where, for example, a service can only read the products collection but has no access to users or orders in the same database. Collection-level scoping is achieved by specifying a collection name in the resource document.

// Role scoped to a single collection
use myApp
db.createRole({
  role: 'catalogReader',
  privileges: [
    {
      resource: { db: 'myApp', collection: 'products' },
      actions: ['find']
    }
  ],
  roles: []
})

Cluster Administration Roles

Several built-in roles govern cluster-level operations rather than data access. clusterMonitor grants read access to monitoring commands (useful for metrics exporters). clusterAdmin allows managing shards, replica sets, and global operations — very powerful, restrict carefully. backup and restore roles grant the specific permissions needed for mongodump and mongorestore without full admin rights.

// Backup user — can dump data but not administer users
use admin
db.createUser({
  user: 'backupAgent',
  pwd: 'BackupPass!',
  roles: [
    { role: 'backup', db: 'admin' }
  ]
})

// Monitoring exporter user
db.createUser({
  user: 'prometheusExporter',
  pwd: 'MonitorPass!',
  roles: [
    { role: 'clusterMonitor', db: 'admin' },
    { role: 'read', db: 'local' }
  ]
})

Viewing Role Details and Inherited Privileges

Use db.getRole(roleName, { showPrivileges: true }) to see exactly which actions and resources a role grants, including inherited privileges from parent roles. This is essential for auditing — you can confirm that a custom role provides exactly the right permissions without accidentally granting broader access through inherited roles.

// Inspect a custom role's full privileges
use myApp
db.getRole('orderProcessor', { showPrivileges: true })

// List all custom roles in the current database
db.getRoles({ showBuiltinRoles: false })

// List all users and their roles
db.getUsers()

RBAC in MongoDB Atlas

MongoDB Atlas implements RBAC through its Database Access panel. You can create database users with built-in or custom roles via the Atlas UI, Atlas CLI, or Atlas API. Atlas also supports temporary users that expire automatically after a set time — ideal for short-lived developer access or incident response. Additionally, Atlas can integrate with AWS IAM and LDAP for enterprise identity management.

Quick Check

Test your understanding of MongoDB & NoSQL Databases concepts from this lesson.

Lesson Recap

In this lesson you learned: built-in roles like read, readWrite, and dbAdmin cover common access patterns at database scope, custom roles let you define collection-level privileges with only the exact actions required, and principle of least privilege — each user and service account should hold only the permissions it genuinely needs. Next up we cover encryption at rest and TLS in transit.

Frequently asked questions

Is the “Role-Based Access Control: Built-In and Custom Roles” lesson free?

Yes — the full text of “Role-Based Access Control: Built-In and Custom Roles” is free to read here on the web, and the MongoDB Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the MongoDB Academy course, upgrade to CoddyKit PRO.

What will I learn in “Role-Based Access Control: Built-In and Custom Roles”?

Learners will assign built-in roles like readWrite and dbAdmin, and create custom roles with least-privilege action sets for service accounts. You practise MongoDB Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start MongoDB Academy?

No prior experience is required. MongoDB Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Role-Based Access Control: Built-In and Custom Roles” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this MongoDB Academy lesson?

Yes. Every MongoDB Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Authentication Mechanisms: SCRAM and x.509
  2. Role-Based Access Control: Built-In and Custom Roles
  3. Encryption at Rest and TLS in Transit
  4. Client-Side Field Level Encryption
← Back to MongoDB Academy