MongoDB Authorization Model - User-defined Roles Part 1
Introduction
In MongoDB, roles are essential to the authorization model. A role can be thought of as a privilege given to a user that allows them to perform certain tasks using certain resources. While MongoDB provides a variety of built-in roles, these predefined roles don’t always describe the exact set of privileges you want to grant a user. In these cases, administrators can define new roles that fit their specific requirements. In this article, we’ll take a closer look at user-defined roles and understand how they fit into the MongoDB authorization model.
Prerequisites
There are only a couple prerequisites that need to be in place before we dive deeper into the world of built-in and user-defined roles:
You need to ensure that MongoDB is properly installed on your machine or server.
You’ll also need to have at least a basic understanding of MongoDB Built-in roles.
NOTE: The MongoDB version used in this article is v4.0.10
What is a Role?
As we discussed in the introduction, a role can be defined as a privilege that defines which actions a user can perform with which resources. Let’s look at each of the terms we used in that definition:
Actions — This term refers to all operations and commands that a user can perform in MongoDB.
Resources — These can include the database, the collection, the set of collections or the cluster.
Privilege — This term can be thought of as the permission to perform an action on a resource. By grouping multiple privileges, a role is created.
What is a MongoDB User-defined Role and How Does It Work?
MongoDB provides a variety of built-in roles that we can choose from to perform needed tasks; however, there are times when the specific access privileges needed for a user don’t fit any of these pre-defined roles. To handle these situations, we can create a “”user-defined”” role.
A role is uniquely defined by the combination of the database name where it was created and the role name itself. When you create a new role, you specify both the privileges that will be part of the role, as well as the roles from which it may inherit privileges.
NOTE: Roles created within a specific database will inherit roles and include resources within that database only.
If you want to share user-defined roles across databases, you’ll need to have a global role that defines the privileges; such roles must be created on the admin
database.
The Actions
As we mentioned earlier, privileges are composed of actions and resources, with actions referring to the operations that a user can perform within a resource in the database.
Let’s look at some of the actions supported by MongoDB:
- Query and Write Actions — Actions in this category relate to CRUD operations: Create, Read, Update and Delete.
find | insert | remove | update | byPassDocumentValidation |
---|
- Database Management — These actions relate to DDL (Data Definition Language) operations and structure roles for the database.
changeCustomData | changeOwnCustomData | changeOwnPassword | changePassword | createCollection |
---|---|---|---|---|
createIndex | createRole | createUser | dropCollection | dropRole |
dropUser | emptycapped | enableProfiler | grantRoll | killCursors |
revokeRole | unlock | viewRole | viewUser |
Although most of the actions have self-explanatory names, it’s important to note the difference between these two actions:
a. changeOwnPassword — this allows a user to change their own password. b. changePassword — This allows a user to change anyone’s password.
- Deployment Management — These actions manage your deployment and are only applied to the cluster resource.
authSchemaUpgrade | cleanupOrphaned | inprog | invalidUserCache |
---|---|---|---|
killop | planCacheRead | planCacheWrite | storageDetails |
- Replication — These actions are involved with the setting and getting of different replication settings.
appendOplogNote | replSetConfigure | replSetGetConfig | replSetGetStatus |
---|---|---|---|
replSetHeartbeat | replSetStateChange | resync |
- Sharding — This category consists of sharding actions.
addShard | enableSharding | flushRouterConfig | getShardMap |
---|---|---|---|
getShardVersion | listShards | removeShard | shardingState |
splitChunk | splitVector |
- Server Administration — The actions in this category are related to administering the database.
applicationMessage | closeAllDatabases | collMod |
---|---|---|
compact | connPoolSync | convertToCapped |
dropDatabase | dropIndex | fsync |
getParameter | hostinfo | logRotate |
reIndex | renameCollectionSameDB | repairDatabase |
setParameter | shutdown | touch |
- Diagnostic — These actions are typically used to monitor and diagnose the database. They will also have access to the metrics collected by profiling or by similar resources.
collStats | connPoolStats | cursorInfo | dbHash |
---|---|---|---|
dbStats | diagLogging | getCmdLineOpts | getLog |
indexStats | listDatabases | listCollections | listIndexes |
netstat | serverStatus | validate | top |
- Internal — As the name of this category implies, these actions are internal to the database– use good judgment before granting such a role to a user.
anyAction | internal |
---|
The Resources
Now that we’ve taken a good look at how actions work in relation to privileges, we’ll now turn our attention to resources. Resources can change their state and behavior as a result of an action. In this section, we’ll discuss the four key MongoDB resources:
- Collection
- Databases
- Cluster
- anyResource
Keep in mind that all of these resources will be defined by a resource document.
Collections and Databases
The generic template that we can use to define a collection or a database looks something like this:
{db: database, collection: collection}
.
Throughout this section, we’ll look at different variations of this statement.
- Specific Database
To denote a specific database, we’ll use an empty string as the value key for the collection:
1 | {db: ""users"", collection: """"} |
NOTE: The database and collection keys always go together.
The document shown above will allow anyone to perform actions for this particular resource on any collection within the users
database.
- Specific Collection
We can also perform any action to a specific collection across any database using the following syntax:
1 | {db: """", collection: ""usersProfile""} |
In this example, we specify an empty string for the database while we specify an actual collection name for the collection– in this case, userProfile
.
- Specific Database and Collection
We can also specify a specific database and collection together using the following syntax:
1 | {db: ""users"", collection: ""usersProfile""} |
- Any Collection in Any Database
Finally, we can provide access to a user or a particular group to perform on any non-system collection on any database. To accomplish this, use the following syntax:
1 | {db: """", collection: """"} |
Notice that we specified empty strings for both the database and collections.
Cluster
The cluster requires only one document that looks like the following:
1 | {cluster: true} |
Here, we simply specify cluster
to be true.
anyResource
As the name suggests, this resource will allow an action to be performed on any resource in the database:
1 | {anyResource: true} |
Like cluster
, the anyResource
resource requires only one document.
NOTE: This resource is for internal use only. Use caution before granting privileges for it to a user.
Conclusion
Roles are a key part of the MongoDB authorization model, so it’s important to have a solid understanding of how they work. In this article, we focused on user-defined roles and their place in the authorization model. With the information provided in this article, you’ll be prepared to manage roles in your own MongoDB deployment and ready to continue reading the next part of this series.
Pilot the ObjectRocket Platform Free!
Try Fully-Managed CockroachDB, Elasticsearch, MongoDB, PostgreSQL (Beta) or Redis.
Get Started