MongoDB Collection-Level Access Control

MongoDB has RBAC (Role Based Access Control) enabled that we all know. Different teams having integration with their separate collection, we might have to create collection specific access control by defining userDefine Role. How to create user define role and how to assign user, you can check it from the mongodb documentations. Here in this article, I am trying to demonstrate how to manage collections in different teams and when it will become big in size how to create user define role quickly and manage efficiently.

I am taking few teams in our software development team are listed below, each team have 5 -10 collections they are using.

  • Payment
  • Etl
  • Content Management
  • Social Media Messaging
  • Product

So, As an administrator you need to make a prefix of this each department collection like below for better control. This is an example collection list will be in actual scenario 80 – 100

  • payment_scurity, payment_transaction, payment_refund
  • etl_loadStatus, etl_odsSync
  • conMan_grevance, conMan_geographis
  • smm_whatsApp, smm_rcs, smm_google
  • product_catalogue, product_upcoming

I assume that you know what are MongoDB resource, action, role, if not then please check at documentation. Now I am going to create a user define role for a team for their collection in bulk manner using javascript. Each collection I will give them only Read, Write access. [ “insert”,”find”,”remove”,”update”]

use admin;
var resource=[];
var vil=db.getSiblingDB('yourDbName');
vil.getCollectionNames().forEach(function(doc){
    var regex = /^payment|product/i;     //Name start with payment or product 
    var found = doc.match(regex);
    if(found){
        resource.push({ resource: { db: "yourDbName", collection: doc }, actions: [ "insert","find","remove","update"] })
    }
});

From this code you will made all the collection of payment, product team read, write access and I am making a role name ‘OPERATIONS_MANAGER’ because it will use by operation manager and he wants the mixed access. So, instead of selecting one by one collection and giving them respective privilege, you can automatically assign them by this script. Now I am creating role as following, remember for understanding I am spitted this code into two parts, but in real case you have to run with conjugation.

// Role will be created against admin DB, resource -> variable will add collection specific access.
db.createRole(
    {
        role: "OPERATIONS_MANAGER",
        privileges: resource,
        roles: [
            {
            role: "read",
            db: "yourDbName"
            }
        ]
    }
)

Now ‘OPERATIONS_MANAGER’ role was created, now you can create an user against your ‘yourDbName’ and assign the role created on admin db. Remember all builtIn roles you can not assign an user created on other DB.

//creating user against yourDbName
use yourDbName;
db.createUser({
    user: "nameOpsManager",
    pwd: "password",  
    roles: [
        { role: "OPERATIONS_MANAGER", db: "admin" } 
    ]
})

Conclusion

This user can see all the collection but only write (insert, update, delete) to his designated collection of payments and products. So this is how we can access control our user with minimum time spend, other wise finding 25 collections from 100 list and assigning them their access are very much tedious job, do not you think?