Have you come across a situation where ‘someone accidentally dropped an entire collection in production?’ Unless you can restore the data from a backup, you are in a terrible situation.
I came across a few clients who faced this situation at one point in time. So, it is important that you take security measures to prevent such situation from happening in the first place. You can easily achieve it by making use of the user-defined roles.
This is one of the many articles in multi-part series, Mastering MongoDB - One tip a day, solely created for you to master MongoDB by learning ‘one tip a day’. In a few series of articles, I would like to give various tips to tighten the security on MongoDB. In this article, I would discuss how an user-defined role can help prevent someone accidentally dropping a collection.
Mastering user-defined role
What is a role
MongoDB employs Role-Based Access Control (RBAC) to govern access to a MongoDB system. A role grant users access to MongoDB resources. Outside of role assignments, the user has no access to the system.
Here are a few concepts that I want you to be aware of
- A user is granted one or more roles.
- A role grants privileges to perform sets of actions on a resource.
- A privilege consists of a resource and the actions permitted on them.
- A resource is a database, collection or set of collections.
- An action specifies the operation allowed on the resource.
Why user-defined role
MongoDB provides a number of built-in roles that administrators can use to control access to a MongoDB system. Every database includes the following roles
Database User Roles
Database Administration Roles
However, if these roles cannot describe the desired set of privileges, you can create a new user-defined role by using the db.createRole() method. While creating a role, you can specify the set of privileges you want to grant access.
readWrite role has dropCollection action
The database administrators typically make use of the built-in ‘read’ and ‘readWrite’ roles to restrict the access to data. The below ‘getRole’ command shows the various set of actions a user with ‘readWrite’ role can execute.
Based on the context of the current article, the riskiest action among them is the ‘dropCollection’ action. If there is truly a need for (a human) user to have a read & write permission, it is recommended to have a user-defined role with all the actions but the ‘dropCollection’ action from ‘readWrite’ role. By assigning this user-defined role to such users, the administrators prevent someone accidentally drop a collection.
Hands-On lab exercises
This lab exercise helps you create a user-defined role and illustrate how readWriteMinusDropRole can prevent someone accidentally drop a collection when compared to a user with readWrite role.
First, you would need an environment to play around. I recommend using mlaunch, a utility tool from mtools, to setup a test environment on your local machine. If you already have an environment with authentication turned on, you may skip this step.
Create app_user with readWrite role
Log in to the test environment using the above credentials and create app_user with readWrite role on the social database.
A user with readWrite role can drop collection
Log in to the test environment using the app_user credentials and create a sample person document on the social database. Since the app_user has readWrite role which grants access to dropCollection action, the command db.person.drop() execution succeeds and the collection is dropped.
Create a user-defined role
Log in to the test environment using the user credentials and create the following on the social database.
- a user-defined role, readWriteMinusDropRole
- a user human_user with readWriteMinusDropRole role
Notice that there is no dropCollection action from the set of actions being granted to readWriteMinusDropRole.
User with readWriteMinusDropRole role cannot drop collection
While MongoDB provides various built-in roles that provide the different levels of access commonly needed in a database system, you would need user-defined roles to grant fine-grained actions to MongoDB resources.
Don’t wait till you regret of not doing it earlier. Tighten your security measures using user-defined roles and prevent someone accidentally drop a collection.
Here are a few measures taken by my clients to tighten the security.
- No access to the production environment for developers (more drastic)
- If access is required, give ‘read’ role to developers (much needed)
- Create a user-defined role with all ‘readWrite’ actions but ‘dropCollection’
- If ‘read & write’ permissions is required for any users, assign above user-defined role (highly recommended)
- Create a separate app_user with ‘readWrite’ permissions for your application to interact with MongoDB
With the MongoDB v3.6, you could further tighten the security by defining the range of IP addresses a user is allowed to authenticate from using authenticationRestrictions. But that’s a topic for another day. Hopefully, you learned something new today on you scale the path to “Mastering MongoDB - One tip a day”.