Menu
Share on

Introduction

Authorization is an essential part of user management and access control that defines the policies for what each user is allowed to do on the system. Deciding on what policies are appropriate and implementing them in your databases ensures that users can interact with the resources they require while protecting against inappropriate behavior.

In this guide, we'll go over how authorization works in MongoDB. We'll take a look at how MongoDB conceptualizes access management, what types of privileges can be granted to users, and how to attach policies to user accounts.

RELATED ON PRISMA.IO

If you are using Prisma Client with MongoDB, you can use the MongoDB connector (currently in preview) to connect and manage your data.

Prerequisites

To follow along with this guide, you'll need an account on a MongoDB server with the appropriate privileges.

To adjust the configuration of MongoDB and enable authorization on the database, you need root level access on the server.

Additionally, within MongoDB, you'll need an account that has at least the userAdmin role so that role-based authorization policies can be set. Roles that include the userAdmin role, listed from most narrowly focused to the broadest level of privileges are:

  • userAdmin
  • dbOwner
  • userAdminAnyDatabase
  • root

How does authorization work in MongoDB?

Authorization and privilege management in MongoDB is implemented using Role-Based Access Control (RBAC). In this system, different levels of access are associated with individual roles. To give a user permission to perform an action, you grant them membership to a role that has the appropriate privileges.

Roles in MongoDB can be nested. This means that roles can be granted to other roles. A role that contains another role inherits all of the child role's privileges. This makes it possible to create new roles that have the desired privileges by combining roles appropriately.

Privileges themselves are defined by a combination of an action and a resource. The action component describes the type of behavior that is permitted by the privilege, while the resource indicates the target or scope of the action.

What resources are available in MongoDB?

The target or scope of an action is known as a resource within MongoDB's access control model. Each action can only be applied to certain types of resources. When configuring privileges, you specify the exact resources for which the privilege should be scoped.

We can go over the available resources in order from the narrowest focus to the broadest.

Privileges can be most narrowly defined by scoping them to a specific collection within a specific database within the cluster. Within the same databases, different collections can specify different privileges. This allows you to implement granular policies for different types of data.

The next largest resource you can enact policies against is a database. Managing privileges on the database level allows you to provide general policy that will effect the database as a whole and all of the collections within.

You can also set policies that apply to collections of the same name across all databases. This allows you to use naming conventions to implement access control for specific collections throughout your system. A broader version of this is to apply policy to all databases and non-system collections on the system.

Finally, you can apply policy against the entire cluster. Actions targeting the cluster affect the general system instead of the data it is managing directly. Policies on the cluster level tend to be focused on administrative operations.

What actions are available in MongoDB?

There are a large number of actions available within MongoDB are related to general usage, database management, and system management. In general, actions correspond to one or more commands or methods within MongoDB.

To view the list of actions available in MongoDB as well as their function, expand the section below:

ActionScopeDescription
finddatabase or collectionAllows read operations on a database
insertdatabase or collectionAllows write operations on a database
removedatabase or collectionAllows delete operations on a database
updatedatabase or collectionAllows replacement operations on a database
bypassDocumentValidationdatabase or collectionLets the user to ignore data validation policies for documents.
useUUIDclusterLets the user use UUID values to find for documents
changeCustomDatadatabaseThe user can modify custom data associated with any user in the database
changeOwnCustomDatadatabaseAllows the user to change the custom data associated with their own user
changeOwnPassworddatabaseLets a user change their own account password
changePassworddatabaseLets a user change the password for any user in the database
createCollectiondatabase or collectionAllows the user to create collections in the database
createIndexdatabase or collectionLets the user create indexes for the database
createRoledatabaseAllows the user to create custom roles in the database
createUserdatabaseLets the user define new user accounts
dropCollectiondatabase or collectionAllows the user to delete collections
dropRoledatabaseLets the user delete roles
dropUserdatabaseLets the user delete users
enableProfilerdatabaseAllows the user to enable performance profiling
grantRoledatabaseLets the user grant roles associated with the database to any user on the system
killCursorscollectionLets a user kill their own cursors in versions of MongoDB prior to 4.2
killAnyCursorcollectionLets a user kill other users' cursors
revokeRoledatabaseAllows the user to remove roles from any user in the system
setAuthenticationRestrictiondatabaseAllows the user to set authentication requirements for users and roles
unlockclusterLets the user reduce the number of write locks on the cluster
viewRoledatabaseAllows viewing details about roles in the database
viewUserdatabaseAllows viewing details about users in the database
authSchemaUpgradeclusterAllows user to upgrade the authentication mechanisms between MongoDB versions
cleanupOrphanedclusterLets the user clean up orphaned documents in MongoDB versions prior to 4.4
cpuProfilerclusterAllows the user to enable CPU profiling
inprogclusterLets the user view information on other users' in progress or queued operations
invalidateUserCacheclusterLets the user manually flush user details from the cache
killopclusterAllows the user to kill other users' operations
planCacheReaddatabase or collectionLets the user view information about cached query plans
planCacheWritedatabase or collectionAllows the user to delete cached query plans
storageDetailsdatabase or collectionDeprecated
changeStreamcollection, database, or clusterAllows the user to access real time change data from non-system collections
appendOpLogNoteclusterLets the user add notes to the oplog
replSetConfigureclusterAllows configuring replica sets
replSetGetConfigclusterLets the user view the current replica set configuration
replSetGetStatusclusterLets the user find the current status of the replica set
replSetHeartbeatclusterDeprecated
replSetStateChangeclusterAllows the user to manage the state of cluster replica sets
resyncclusterDeprecated
addShardclusterLets the user add a shard replica to a sharded cluster
clearJumboFlagdatabase or collectionLets the user clean up oversized chunks in a shard
enableShardingcluster, database, or collectionAllows user to enable sharding on clusters and database or manage sharding on a cluster level
refineCollectionShardKeydatabase or collectionLets the user add additional fields to an existing shard key
flushRouterConfigclusterLets the user mark a cached routing table as obsolete
getShardVersiondatabaseInternal command
listShardsclusterLets user see a list of configured shards for the cluster
moveChunkdatabase or collectionAllows a user to move a chunk to a new shard
removeShardclusterLets the user drain chunks from a shard and then remove the shard from the cluster
shardingStateclusterAllows the user to view whether the MongoDB server is part of a sharded cluster
splitChunkdatabase or collectionAllows the user to merge or split chunks in a shard
splitVectordatabase or collectionInternal command
applicationMessageclusterLets the user add custom messages to the audit log
closeAllDatabasesclusterDeprecated
collModdatabase or collectionLets the user modify the options associated with a collection
compactdatabase or collectionAllows the user to defragment data and indexes in a collection
connPoolSyncclusterInternal command
convertToCappeddatabase or collectionLets the user convert a collection into a capped collection with a set maximum size
dropConnectionsclusterLets the user remove outgoing connections from MongoDB to a specified host
dropDatabasedatabaseLets the user delete the current database
dropIndexdatabase or collectionLets the user delete an index
forceUUIDclusterLets users define collections using globally unique UUIDs
fsyncclusterAllows the user to flush all pending writes to storage and lock the cluster for writes
getDefaultRWConcernclusterLets the user view the default read and write consistency and isolation settings
getParameterclusterLets the user query for the value of a parameter
hostInfoclusterAllows the user to see information about the server running the MongoDB instance
logRotateclusterLets the user trigger log rotation
reIndexdatabase or collectionLets the user rebuild the indexes for a collection
renameCollectionSameDBdatabaseLets the user rename a collection in the current database
setDefaultRWConcernclusterLets the user specify the default read and write consistency and isolation settings
setParameterclusterAllows the user to define the value for parameters
shutdownclusterLets the user shutdown the MongoDB instance
touchclusterDeprecated
impersonateclusterLets the user kill sessions associated with other users and roles
listSessionsclusterLets the user list all sessions by all users
killAnySessionclusterLets the user kill all sessions for a specific user or a pattern
checkFreeMonitoringStatusclusterAllows the user to see the status of cloud monitoring functionality
setFreeMonitoringclusterLets the user enable or disable cloud monitoring functionality
collStatsdatabase or collectionAllows the user to view statistics about collections
connPoolStatsclusterLets the user see the status of outgoing connections from MongoDB instances
dbHashdatabase or collectionLets the user query for hashed values of collections in a database
dbStatsdatabaseAllows the user to view storage statistics
getCmdLineOptsclusterLets the user see the command line options used to start the MongoDB instance
getLogclusterLets the user see the most recent MongoDB events
listDatabasesclusterLets the user see the list of all databases
listCollectionsdatabaseAllows the user to see a list of collections and views in a database
listIndexesdatabase or collectionLets the user see what indexes are associated with a specific collection
netstatclusterInternal command
serverStatusclusterLets the user view information about the database's current state
validatedatabase or collectionAllows the user to check a collections data and indexes for correctness
topclusterLets the user see usage statistics for collections

What roles are available in MongoDB by default?

MongoDB includes a number of useful roles that combine similar privileges together. These roles allow you to grant and revoke privileges to database resources in a concise way.

To view the list of actions available in MongoDB as well as their function, expand the section below:

  • read: Provides read access to non-system collections
    • Actions:
      • changeStream
      • collStats
      • dbHash
      • dbStats
      • find
      • killCursors
      • listIndexes
      • listCollections
  • readWrite: Provides read and write access to non-system collections
    • Actions:
      • collStats
      • convertToCapped
      • createCollection
      • dbHash
      • dbStats
      • dropCollection
      • createIndex
      • dropIndex
      • find
      • insert
      • killCursors
      • listIndexes
      • listCollections
      • remove
      • renameCollectionSameDB
      • update
  • dbAdmin: Provides access to administrative tasks at the database level, excluding role and user management
    • Actions within the system.profile collection:
      • changeStream
      • collStats
      • convertToCapped
      • createCollection
      • dbHash
      • dbStats
      • dropCollection
      • find
      • killCursors
      • listCollections
      • listIndexes
      • planCacheRead
    • Actions in non-system collections:
      • bypassDocumentValidation
      • collMod
      • collStats
      • compact
      • convertToCapped
      • createCollection
      • createIndex
      • dbStats
      • dropCollection
      • dropDatabase
      • dropIndex
      • enableProfiler
      • listCollections
      • listIndexes
      • planCacheIndexFilter
      • planCacheRead
      • planCacheWrite
      • reIndex
      • renameCollectionSameDB
      • storageDetails
      • validate
  • userAdmin: Provides access to create and modify users and roles
    • Actions:
      • changeCustomData
      • changePassword
      • createRole
      • createUser
      • dropRole
      • dropUser
      • grantRole
      • revokeRole
      • setAuthenticationRestriction
      • viewRole
      • viewUser
  • dbOwner: Provides administrative access to the database including role and user management
    • Roles this role inherits:
      • readWrite
      • dbAdmin
      • userAdmin
  • clusterMonitor: Provides read access to the cluster
    • Actions for the whole cluster:
      • checkFreeMonitoringStatus
      • connPoolStats
      • getCmdLineOpts
      • getDefaultRWConcern
      • getLog
      • getParameter
      • getShardMap
      • hostInfo
      • inprog
      • listDatabases
      • listSessions
      • listShards
      • netstat
      • replSetGetConfig
      • replSetGetStatus
      • serverStatus
      • setFreeMonitoring
      • shardingState
      • top
    • Actions for all databases within the cluster:
      • collStats
      • dbStats
      • getShardVersion
      • indexStats
      • useUUID
    • Actions for all system.profile collections:
      • find
    • Actions on the non-system collections in the config database:
      • collStats
      • dbHash
      • dbStats
      • find
      • getShardVersion
      • indexStats
      • killCursors
      • listCollections
      • listIndexes
      • planCacheRead
    • Actions on the system.js collection in the config database:
      • collStats
      • dbHash
      • dbStats
      • find
      • killCursors
      • listCollections
      • listIndexes
      • planCacheRead
    • Actions on all collections in the local database:
      • collStats
      • dbHash
      • dbStats
      • find
      • getShardVersion
      • indexStats
      • killCursors
      • listCollections
      • listIndexes
      • planCacheRead
    • Actions on the system.js collection in the local database:
      • collStats
      • dbHash
      • dbStats
      • find
      • killCursors
      • listCollections
      • listIndexes
      • planCacheRead
    • Actions on the system.replset and system.profile collections in the local database:
      • find
  • clusterManager: Provides monitoring and management access on the cluster through the config and local databases
    • Actions on the entire cluster:
      • addShard
      • appendOplogNote
      • applicationMessage
      • cleanupOrphaned
      • flushRouterConfig
      • getDefaultRWConcern
      • listSessions
      • listShards
      • removeShard
      • replSetConfigure
      • replSetGetConfig
      • replSetGetStatus
      • replSetStateChange
      • resync
      • setDefaultRWConcern
      • setFeatureCompatibilityVersion
      • setFreeMonitoring
    • Actions on all databases within the cluster:
      • clearJumboFlag
      • enableSharding
      • refineCollectionShardKey
      • moveChunk
      • splitChunk
      • splitVector
    • Actions on non-system collections in the config database:
      • collStats
      • dbHash
      • dbStats
      • enableSharding
      • find
      • insert
      • killCursors
      • listCollections
      • listIndexes
      • moveChunk
      • planCacheRead
      • remove
      • splitChunk
      • splitVector
      • update
    • Actions on the system.js collection in the config database:
      • collStats
      • dbHash
      • dbStats
      • find
      • killCursors
      • listCollections
      • listIndexes
      • planCacheRead
    • Actions on all non-system collections in the local database:
      • enableSharding
      • insert
      • moveChunk
      • remove
      • splitChunk
      • splitVector
      • update
    • Actions for the system.replset collection in the local database:
      • collStats
      • dbHash
      • dbStats
      • find
      • killCursors
      • listCollections
      • listIndexes
      • planCacheRead
  • hostManager: Provides the ability to monitor and manage servers.
    • Actions on the entire cluster:
      • applicationMessage
      • closeAllDatabases
      • connPoolSync
      • flushRouterConfig
      • fsync
      • invalidateUserCache
      • killAnyCursor
      • KillAnySession
      • killop
      • logRotate
      • resync
      • setParameter
      • shutdown
      • touch
      • unlock
  • clusterAdmin: Provides all cluster management access
    • Roles this role inherits:
      • clusterManager
      • clusterMonitor
      • hostManager
    • Additional actions:
      • dropDatabase
  • backup: Provides privileges needed to back up data
    • Actions on all resources:
      • listDatabases
      • listCollections
      • listIndexes
    • Actions on the entire cluster:
      • appendOplogNote
      • getParameter
      • listDatabases
      • serverStatus
    • Actions on non-system collections, the system.js and system.profile collections, the admin.system.users and admin.system.roles collections, and the config.settings collection:
      • find
    • Actions on the config.settings collection:
      • insert
      • update
  • restore: Provides the privileges to restore data to the cluster
    • Actions on the entire cluster:
      • getParameter
    • Actions on non-system collections:
      • bypassDocumentValidation
      • changeCustomData
      • changePassword
      • collMod
      • convertToCapped
      • createCollection
      • createIndex
      • createRole
      • createUser
      • dropCollection
      • dropRole
      • dropUser
      • grantRole
      • insert
      • revokeRole
      • viewRole
      • viewUser
    • Actions on the system.js collection:
      • bypassDocumentValidation
      • collMod
      • createCollection
      • createIndex
      • dropCollection
      • insert
    • Actions on any resource
      • listCollections
    • Actions on non-system collections in the config and local databases:
      • bypassDocumentValidation
      • collMod
      • createCollection
      • createIndex
      • dropCollection
      • insert
    • Actions on the admin.system.version collection:
      • bypassDocumentValidation
      • collMod
      • createCollection
      • createIndex
      • dropCollection
      • find
      • insert
    • Actions on the admin.system.roles collection:
      • createIndex
    • Actions on the admin.system.users collection:
      • bypassDocumentValidation
      • collMod
      • createCollection
      • createIndex
      • dropCollection
      • find
      • insert
      • remove
      • update
  • readAnyDatabase: Provides same privileges as read to all databases except local and config
    • Additional actions on the entire cluster:
      • listDatabases
  • readWriteAnyDatabase: Provides the same privileges as readWrite to all databases except local and config
    • Additional actions on the entire cluster:
      • listDatabases
  • userAdminAnyDatabase: Provides the same privileges as userAdmin on all databases except local and config.
    • Additional actions on the entire cluster:
      • authSchemaUpgrade
      • invalidateUserCache
      • listDatabases
    • Additional actions on the system.users and system.roles clusters in the admin database:
      • collStats
      • dbHash
      • dbStats
      • find
      • killCursors
      • planCacheRead
  • dbAdminAnyDatabase: Provides the same privileges as dbAdmin for all databases except local and config.
    • Additional actions on the entire cluster:
      • listDatabases
  • root: Provides complete access to the entire system.
    • Roles this role inherits:
      • readWriteAnyDatabase
      • dbAdminAnyDatabase
      • userAdminAnyDatabase
      • clusterAdmin
      • restore
      • backup
    • Additional actions on system collections:
      • validate

How to enable authorization in MongoDB

Before MongoDB can use authorization to manage user privileges, you must enable the functionality on your server or cluster. To do so, you must log in to your server with root or other administrative privileges.

Note: Before enabling authorization, double check to make sure that you have access to at least one role with the privileges necessary to manage roles.

Modify the MongoDB server's configuration by opening the /etc/mongod.conf file in a text editor as an administrator. This command will open the file using the text editor defined in the EDITOR environment variable and fall back to vi, which is available on almost all systems:

sudo ${EDITOR:-vi} /etc/mongod.conf

The MongoDB configuration file uses the YAML serialization format to define the configuratio. Uncomment or add a security: section key to the file. Beneath this key, indent a line using spaces (tabs are not permitted in YAML) and set authorization to enabled:

. . .
security:
authorization: enabled
. . .

Save and close the file when you are finished.

To enable the new settings, restart your MongoDB server process. If your MongoDB server is running on a Linux host, the operation will look like this:

sudo systemctl restart mongod.service

Once the process restarts, MongoDB's authorization framework should be enabled within the database.

Viewing privileges and roles

Before you begin assigning roles to users, it is a good idea to get familiar with how to view information about privileges and roles within the system.

To view all of the roles available on the system, including all built-in roles and their associated privileges, use the db.getRoles() method with the showPrivileges and showBuiltinRoles options set to true:

db.getRoles({
rolesInfo: 1,
showPrivileges: true,
showBuiltinRoles: true
})

The returned list will include a whole list of nested information about each of the roles and the privileges they have on various resources throughout the system.

To get information about a specific role, use the db.getRole() method instead. You must be on the database where the user is defined before executing the command:

use admin
db.getRole(
"root",
{
showPrivileges: true,
showBuiltinRoles: true
}
)

To check which roles have been granted to each user, change to the database you are interested in and use the db.getUsers() method:

use admin
db.getUsers()

To check on the roles associated with a specific user, use db.getUser() instead:

use admin
db.getUser("root")

Assigning and revoking roles from users

To grant additional privileges to a user, you must grant them access to an existing role.

The db.grantRolesToUser() method allows you to specify additional roles that you want to add to a user. Its first argument is the user you wish to grant additional privileges to and the second argument is an array of additional roles you wish to add:

db.grantRolesToUser(
"sally",
[
"read",
"backup"
]
)

If the roles are defined in the current database, you can use the shorthand above that specifies the role by name without mentioning a database.

To grant roles associated with a different database or to be more explicit, specify roles as a document defining the role and db instead:

db.grantRolesToUser(
"sally",
[
{ role: "read", db: "sales"},
{ role: "readWrite", db: "callLogs"}
]
)

To revoke roles from a user, you can use the companion method called db.revokeRolesFromUser(). The argument syntax works exactly the same, but this time, the command removes the roles from the specified account.

To remove roles defined in the current database you can use the role names without mentioning the database:

db.revokeRolesFromUser(
"sally",
[
"read",
"backup"
]
)

To specify roles that are associated with other databases, use the long form by specifying the role and db in a document:

db.revokeRolesFromUser(
"sally",
[
{ role: "read", db: "sales"},
{ role: "readWrite", db: "callLogs"}
]
)

Creating and managing custom roles

There are times when the system's built-in roles do not adequately match up with the types of permissions you need to assign. In these cases, you can create your own custom roles.

Creating new roles

The db.createRole() method allows you to define a new role that you can assign privileges and other roles to. You can then grant your new role to users to give them the specific privileges you defined.

The basic syntax of the db.createRole() method involves passing a document that defines the role's characteristics. The document can have the following fields:

  • role: The name you want to give the role
  • privileges: An array containing the set of loose privileges you want to assign to the role. Each privilege is defined in a nested document that defines a resource document (specifying which resources this privilege applies to) as well as an array of actions that are being granted
  • roles: An array of additional roles that this role should inherit from. The new role will acquire all of the privileges granted to any of the roles listed here.
  • authenticationRestrictions: An array that specifies any restrictions on authentication for the role. This allows you to deny a role's privileges if the user has not authenticated in a way the role approves of.

The first three fields are required for every new role created.

As an example, let's create a role called salesMonitor that provides read-only access to the sales database:

db.createRole({
role: "salesMonitor",
privileges: [],
roles: [
{
role: "read",
db: "sales"
}
],
})

We could express a similar (but more limited) role using the privileges field instead of the read role by typing:

db.createRole({
role: "salesMonitor",
privileges: [
{
resource: { db: "sales", collection: "" },
actions: [ "find" ]
}
],
roles: []
})

Viewing information about custom roles

As before, you can get information about your roles with the db.getRole method:

db.getRole(
"salesMonitor",
{
showPrivileges: true
}
)

Granting additional privileges to custom roles

To grant additional privileges to an existing user-defined role, you can use the db.grantPrivilegesToRole() method. It takes an array of privileges that are defined by documents containing a resource document and actions array, just as we saw above with db.createRole().

For instance, to add the listCollections privilege to the salesMonitor role, you could type:

db.grantPrivilegesToRole(
"salesMonitor",
[
{
resource: { db: "sales", collection: "" },
actions: [ "listCollections" ]
}
]
)

Revoking privileges from custom roles

If you change your mind, you can use the db.revokePrivilegesFromRole() method to remove the listCollections action using the same format:

db.revokePrivilegesFromRole(
"salesMonitor",
[
{
resource: { db: "sales", collection: "" },
actions: [ "listCollections" ]
}
]
)

Granting roles to custom roles

To add the privileges defined by a role to another role, you can use the db.grantRolesToRole() method. The method takes the role you want to modify and an array of roles you want to add to it as arguments.

To specify that you want to use the read role for the salesMonitor role after all, you can do so by typing:

db.grantRolesToRole(
"salesMonitor",
[
"read"
]
)

Revoking roles from custom roles

If you change your mind again, you can revoke the role access using the db.revokeRolesFromRole() method, which uses the same argument syntax:

db.revokeRolesFromRole(
"salesMonitor",
[
"read"
]
)

Replacing the values of a custom role

To redefine the characteristics of a user-defined role, you can use the db.updateRole() command. It works by replacing the fields it specifies instead of appending or truncating them. For this reason, it's a good idea to be careful when issuing the command so that you do not accidentally overwrite important information.

The syntax for the db.updateRole() command involves passing the role name as the first argument and a document specifying the field or fields you wish to replace as the second argument. The fields that can be replaced include the privileges array, the roles array, and the authenticationRestrictions array. At least one of these must be included in the document.

For example, once we've finally decided we want the salesMonitor role to use the read role on the sales database, we may want to redefine the role's privilege and role arrays to clean up any extra privileges that have been left behind by our experimentation. You can do this by updating the role with the new information you want to set:

db.updateRole(
"salesMonitor",
{
privileges: [],
roles: [
{
role: "read",
db: "sales"
}
]
}
)

Deleting user-defined roles

You can delete unnecessary roles with the db.dropRole() method.

To delete a role, just pass its name to the method:

db.dropRole()

The role will be removed from the system and any privileges granted to users by that role will no longer be accessible.

Conclusion

In this article, we covered a lot of ground about how MongoDB implements access control and privilege management. We took a look at the conceptual underpinnings of the system, saw the roles, actions, and resources available for administrators to manage, and then learned about how to use the roles system to configure authorization across the system.

These skills are necessary to provide users with access to the resources they need to complete their required tasks while limiting exposure to unrelated parts of the system. Learning how to define and leverage roles increases your ability to offer fine grained access control on the MongoDB systems you manage.

RELATED ON PRISMA.IO

If you are using Prisma Client with MongoDB, you can use the MongoDB connector (currently in preview) to connect and manage your data.