DEV Community

ScaleGrid for ScaleGrid

Posted on • Updated on • Originally published at scalegrid.io

MongoDB Basics: Configuring Role-Based Access Control (RBAC)

MongoDB Basics: Configuring Role-Based Access Control (RBAC)

MongoDB, an open-source document store and most popular NoSQL database on the market today, offers a variety of advanced features to administer security over your MongoDB deployments. In this tutorial post, we're going to show you how to set up role-based access control (RBAC) to manage user access across your MongoDB systems for reIndex, mongodump and mongorestore.

If you're the administrator of your MongoDB databases, you've likely received requests to provide an individual user with the capabilities to perform a certain action(s). MongoDB's security features are fairly mature now, and allow you to create and assign very granular role-based access control.

We're going to walk through an example of granting a user the specific privilege of performing the reIndex action in a step-by-step approach through its resolution. Before we demonstrate how to perform this common security action, let's go through an overview of MongoDB's role-based action control.

How MongoDB RBAC Works

MongoDB allows you to use a RBAC mechanism to restrict access to users through assigned 'roles'. RBAC access control is not enabled by default and must be configured by an administrator on your team. By granting a user access to a specific resource, you are authorizing that role or user to perform actions on that resource.

  • Resources

    A database, collection, set of collections, or the cluster.

  • Actions

    Specific operations a user can perform on a resource (usually a database).

MongoDB supports pre-defined roles called built-in roles with actions collated into logical groups such as read(-Only), readWrite, backup, etc. MongoDB also supports the creation of user-defined roles.

Authorizing MongoDB reIndex RBAC Privileges

Now that you have some context, let's jump into the steps of authorizing a user the privilege of performing the reIndex action.

  1. Determine the Privilege Actions

    Actions in the MongoDB context are known as Privilege Actions and you can find an exhaustive list of these actions in MongoDB's documentation. The action we're interested in is reIndex, or the privilege that allows a user to execute the reIndex command on a given database or collection. Since the reIndex command can be expensive for collections with large amounts of data or a large number of indexes, it's part of administrative roles by default.

  2. Grant Privileges to a Role

    Once we've determined the privileges we need, we move on to granting those privileges to a role. You can also simply pick a built-in role that already has the privilege, but we recommend creating your own user-defined role over modifying built-in roles as they're good defaults to return to.

    1. Create a New User-Defined Role

      Here's what we'll use to create our new user-defined role:

      > use test
      switched to db test
      > db.createRole({role: "reIndexing", privileges: [], roles: ["readWrite"]}) // Create a new role out of the default readWrite rule.
      { "role" : "reIndexing", "privileges" : [ ], "roles" : [ "readWrite" ] }
      > db.getRole("reIndexing")
      {
          "role" : "reIndexing",
          "db" : "test",
          "isBuiltin" : false,
          "roles" : [
              {
                  "role" : "readWrite",
                  "db" : "test"
              }
          ],
          "inheritedRoles" : [
              {
                  "role" : "readWrite",
                  "db" : "test"
              }
          ]
      }
    2. Grant Privileges to the New Role

      Now we're going to assign our desired privileges to our newly created user-defined role.

      > db.grantPrivilegesToRole("reIndexing", [ { resource: { db : "test", collection: "" }, actions: ["reIndex"] } ])
      > db.getRole("reIndexing", {showPrivileges: true})
      {
          "role" : "reIndexing",
          "db" : "test",
          "isBuiltin" : false,
          "roles" : [
              {
                  "role" : "readWrite",
                  "db" : "test"
              }
          ],
          "inheritedRoles" : [
              {
                  "role" : "readWrite",
                  "db" : "test"
              }
          ],
          "privileges" : [
              {
                  "resource" : {
                      "db" : "test",
                      "collection" : ""
                  },
                  "actions" : [
                      "reIndex"
                  ]
              }
          ],
          "inheritedPrivileges" : [
      ....
          ]
      }
      
      
  3. Grant the Role to a User

    The last step is to simply assign the user this new role:

    > db.getUser("indexUser")
    {
        "_id" : "test.indexUser",
        "user" : "indexUser",
        "db" : "test",
        "roles" : [
            {
                "role" : "readWrite",
                "db" : "test"
            }
        ]
    }
    > db.grantRolesToUser("indexUser", ["reIndexing"])
    > db.getUser("indexUser")
    {
        "_id" : "test.indexUser",
        "user" : "indexUser",
        "db" : "test",
        "roles" : [
            {
                "role" : "reIndexing",
                "db" : "test"
            },
            {
                "role" : "readWrite",
                "db" : "test"
            }
        ]
    }
    

    Remember to perform these steps on a dummy user so you can test and confirm the new privileges work before granting and notifying the relevant user of their authorization.

Additional Privileges: mongodump & mongorestore

We demonstrated the reIndex example first to illustrate both granting privileges to roles and granting roles to users.

A more common use case is providing authorization to perform backup and restore actions using mongodump and mongorestore. This can be done in a single step through MongoDB's built-in roles, and both backup and restore privileges can be granted to enable users to run mongodump and mongorestore, respectively.

For example, here's how we would grant a user permissions to backup and restore any database. Note that these roles are only available to users on the admin database.

> db.grantRolesToUser("backupUser", ["backup", "restore"])
> db.getUser("backupUser")
{
    "_id" : "admin.backupUser",
    "user" : "backupUser",
    "db" : "admin",
    "roles" : [
        {
            "role" : "restore",
            "db" : "admin"
        },
        {
            "role" : "backup",
            "db" : "admin"
        },
        {
            "role" : "readWrite",
            "db" : "admin"
        }
    ]
}

Adding permissions to backup and restore on a single database or collection requires more work. For mongodump, you must additionally grant a find privilege on that given database, however, mongorestore has more complicated privilege requirements.

Interested in MongoDB security? Here are the top posts on MongoDB security topics:

 

Top comments (0)