Skip to main content

MongoDB Authorization

Introduction

Authorization is a critical component of MongoDB security that determines what actions authenticated users can perform on your database. Once a user has been authenticated (proven who they are), authorization controls what resources they can access and what operations they can perform.

MongoDB implements a Role-Based Access Control (RBAC) system to manage user privileges effectively. This approach allows administrators to assign specific roles to users that grant them precisely the permissions they need—no more, no less—following the principle of least privilege.

In this guide, we'll explore how MongoDB's authorization system works, how to set up and manage user roles, and best practices for implementing a secure authorization strategy.

Understanding MongoDB's Role-Based Access Control

MongoDB's RBAC system consists of several key components:

  1. Privileges: The basic unit of permission in MongoDB
  2. Actions: Specific operations that users can perform
  3. Resources: Database or collection objects that users can access
  4. Roles: Collections of privileges that can be assigned to users
  5. Users: Identities that can be authenticated and authorized

How Authorization Works in MongoDB

When a user attempts to perform an operation in MongoDB, the server checks:

  1. Is the user authenticated?
  2. Does the user have a role that grants privileges for this action on this resource?
  3. If yes, the operation proceeds; if not, it's denied.

Enabling Authorization

By default, MongoDB doesn't enforce access control. To enable authorization, you need to start MongoDB with the --auth option or set authorization: enabled in your configuration file.

Configuration File Example

yaml
security:
authorization: enabled

Command Line Example

bash
mongod --auth --dbpath /data/db

Built-in Roles in MongoDB

MongoDB provides several built-in roles that cover common use cases:

Database User Roles

  • read: Read data on specified database
  • readWrite: Read and write data on specified database

Database Administration Roles

  • dbAdmin: Perform administrative tasks on specified database
  • dbOwner: Perform any action on specified database
  • userAdmin: Create and manage users and roles on specified database

Cluster Administration Roles

  • clusterAdmin: Highest cluster-management role
  • clusterManager: Manage and monitor cluster operations
  • clusterMonitor: Read-only monitoring access
  • hostManager: Monitor and manage servers

Backup and Restoration Roles

  • backup: Privileges to back up data
  • restore: Privileges to restore data

Super User Roles

  • root: Access to all operations and resources

Creating Users and Assigning Roles

Let's look at how to create users and assign roles:

Creating a New User with a Role

javascript
use admin
db.createUser({
user: "dbAdmin",
pwd: "securePassword123",
roles: [{ role: "userAdminAnyDatabase", db: "admin" }]
})

This creates a user with administrative privileges over all databases.

Creating a Read-Only User for a Specific Database

javascript
use sales
db.createUser({
user: "salesAnalyst",
pwd: "analyzeThis456",
roles: [{ role: "read", db: "sales" }]
})

Creating a User with Multiple Roles

javascript
use reporting
db.createUser({
user: "reportingUser",
pwd: "report789",
roles: [
{ role: "read", db: "sales" },
{ role: "read", db: "marketing" },
{ role: "readWrite", db: "reporting" }
]
})

Custom Roles for Fine-Grained Control

When built-in roles don't provide the exact permissions needed, you can create custom roles:

Creating a Custom Role

javascript
use admin
db.createRole({
role: "analyticsRole",
privileges: [
{
resource: { db: "sales", collection: "transactions" },
actions: ["find", "aggregate"]
},
{
resource: { db: "marketing", collection: "campaigns" },
actions: ["find"]
}
],
roles: []
})

Assigning a Custom Role to a User

javascript
use admin
db.createUser({
user: "analyticsUser",
pwd: "analyze123",
roles: [{ role: "analyticsRole", db: "admin" }]
})

Managing Existing Users and Roles

Viewing All Users

javascript
use admin
db.getUsers()

Output:

json
[
{
"_id": "admin.dbAdmin",
"userId": UUID("7f3fdd52-8f0c-4edf-ae2d-45c3bd97238a"),
"user": "dbAdmin",
"db": "admin",
"roles": [
{
"role": "userAdminAnyDatabase",
"db": "admin"
}
],
"mechanisms": ["SCRAM-SHA-1", "SCRAM-SHA-256"]
},
// Other users would appear here
]

Viewing Users for a Specific Database

javascript
use sales
db.getUsers()

Viewing All Roles

javascript
use admin
db.getRoles({ showBuiltinRoles: true })

Grant Additional Roles to a User

javascript
use admin
db.grantRolesToUser(
"dbAdmin",
[{ role: "readWriteAnyDatabase", db: "admin" }]
)

Revoke Roles from a User

javascript
use admin
db.revokeRolesFromUser(
"dbAdmin",
[{ role: "readWriteAnyDatabase", db: "admin" }]
)

Updating a User's Password

javascript
use admin
db.changeUserPassword("dbAdmin", "newSecurePassword456")

Removing a User

javascript
use admin
db.dropUser("temporaryUser")

Practical Example: Setting Up Authorization for a Web Application

Let's walk through a complete example for a web application with different user types:

Step 1: Create an Admin User

First, start MongoDB without authentication to create your first admin user:

javascript
use admin
db.createUser({
user: "adminUser",
pwd: "superSecureAdminPwd!123",
roles: [{ role: "userAdminAnyDatabase", db: "admin" }]
})

Step 2: Restart MongoDB with Authentication Enabled

bash
mongod --auth --dbpath /data/db

Step 3: Connect as Admin and Create Application-Specific Users

javascript
// Connect as admin
mongosh admin --username adminUser --password superSecureAdminPwd!123

// Create a database for your application
use myWebApp

// Create a read-write user for your application server
db.createUser({
user: "appServer",
pwd: "appServerPwd!456",
roles: [{ role: "readWrite", db: "myWebApp" }]
})

// Create a read-only user for reporting purposes
db.createUser({
user: "reportingService",
pwd: "reportingPwd!789",
roles: [{ role: "read", db: "myWebApp" }]
})

// Create a backup user
use admin
db.createUser({
user: "backupUser",
pwd: "backupPwd!101112",
roles: [{ role: "backup", db: "admin" }]
})

Step 4: Configure Your Application to Connect with Credentials

javascript
// Node.js example using the MongoDB driver
const { MongoClient } = require('mongodb');

const uri = "mongodb://appServer:appServerPwd!456@localhost:27017/myWebApp";
const client = new MongoClient(uri);

async function connectToDatabase() {
try {
await client.connect();
console.log("Connected to MongoDB");
const database = client.db("myWebApp");
const collection = database.collection("users");
// Perform operations on the collection
} catch (error) {
console.error("Connection error:", error);
}
}

connectToDatabase();

Collection-Level Access Control

MongoDB allows you to define permissions at the collection level for more granular control:

javascript
use admin
db.createRole({
role: "userProfileManager",
privileges: [
{
resource: { db: "myWebApp", collection: "users" },
actions: ["find", "update", "insert"]
},
{
resource: { db: "myWebApp", collection: "preferences" },
actions: ["find", "update"]
}
],
roles: []
})

db.createUser({
user: "profileManager",
pwd: "profile123!",
roles: [{ role: "userProfileManager", db: "admin" }]
})

Best Practices for MongoDB Authorization

  1. Follow the principle of least privilege: Give users only the permissions they need
  2. Use separate users for different applications: Don't share credentials between applications
  3. Create custom roles when needed: For fine-grained control
  4. Regularly audit user permissions: Remove unused accounts and unnecessary privileges
  5. Never use the root user for applications: The root user should only be used for system administration
  6. Rotate passwords regularly: Set a password rotation policy
  7. Never store credentials in code: Use environment variables or secure secret management systems
  8. Set strong password policies: Require complex passwords
  9. Use separate users for read and write operations: If possible

Field-Level Security

For even more granular control, MongoDB Enterprise Edition offers field-level redaction:

javascript
// Create a role that can see all fields except 'ssn' in the 'customers' collection
use admin
db.createRole({
role: "customerServiceRole",
privileges: [
{
resource: { db: "myWebApp", collection: "customers" },
actions: ["find"]
}
],
roles: []
})

// Create a view that redacts sensitive fields
use myWebApp
db.createView(
"customersRedacted",
"customers",
[
{
$project: {
name: 1,
email: 1,
address: 1,
// ssn field is excluded
}
}
]
)

// Grant access to the view instead of the collection
use admin
db.grantPrivilegesToRole(
"customerServiceRole",
[
{
resource: { db: "myWebApp", collection: "customersRedacted" },
actions: ["find"]
}
]
)

Troubleshooting Authorization Issues

If you're experiencing authorization issues:

  1. Check the user's roles: Ensure the user has the necessary roles for the operation

    javascript
    db.getUser("username")
  2. Check role privileges: Verify what actions a role allows

    javascript
    db.getRole("roleName", { showPrivileges: true })
  3. Review MongoDB logs: Look for authorization failure messages

    2023-09-15T14:30:45.123+0000 I ACCESS [conn12345] Unauthorized: not authorized on admin to execute command
  4. Test with a different user: Try with a user that has more privileges to isolate the issue

Summary

MongoDB's authorization system provides robust Role-Based Access Control to protect your data. By properly configuring authorization:

  • You control who can access your data and what they can do with it
  • You can implement the principle of least privilege
  • You can segregate duties among different users and roles
  • You can create fine-grained access control at database, collection, or even field level

Using the combination of authentication and authorization ensures that your MongoDB deployment is secure and compliant with security best practices.

Additional Resources

To deepen your understanding of MongoDB authorization:

  • Practice creating custom roles that implement the principle of least privilege
  • Explore how to migrate from no authentication to full RBAC implementation
  • Research how to integrate MongoDB authentication with external systems like LDAP or Kerberos

Exercises

  1. Create a user with read-only access to one collection and read-write access to another collection in the same database
  2. Design a role hierarchy for a typical web application with user management, content management, and analytics functions
  3. Implement field-level security to hide sensitive customer information from customer service representatives
  4. Create a script to audit all user roles in your MongoDB deployment and identify users with excessive privileges

By following these practices and continually refining your authorization strategy, you'll ensure that your MongoDB deployment remains secure while still enabling users to access the data they need.



If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)