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:
- Privileges: The basic unit of permission in MongoDB
- Actions: Specific operations that users can perform
- Resources: Database or collection objects that users can access
- Roles: Collections of privileges that can be assigned to users
- 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:
- Is the user authenticated?
- Does the user have a role that grants privileges for this action on this resource?
- 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
security:
authorization: enabled
Command Line Example
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 databasereadWrite
: Read and write data on specified database
Database Administration Roles
dbAdmin
: Perform administrative tasks on specified databasedbOwner
: Perform any action on specified databaseuserAdmin
: Create and manage users and roles on specified database
Cluster Administration Roles
clusterAdmin
: Highest cluster-management roleclusterManager
: Manage and monitor cluster operationsclusterMonitor
: Read-only monitoring accesshostManager
: Monitor and manage servers
Backup and Restoration Roles
backup
: Privileges to back up datarestore
: 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
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
use sales
db.createUser({
user: "salesAnalyst",
pwd: "analyzeThis456",
roles: [{ role: "read", db: "sales" }]
})
Creating a User with Multiple Roles
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
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
use admin
db.createUser({
user: "analyticsUser",
pwd: "analyze123",
roles: [{ role: "analyticsRole", db: "admin" }]
})
Managing Existing Users and Roles
Viewing All Users
use admin
db.getUsers()
Output:
[
{
"_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
use sales
db.getUsers()
Viewing All Roles
use admin
db.getRoles({ showBuiltinRoles: true })
Grant Additional Roles to a User
use admin
db.grantRolesToUser(
"dbAdmin",
[{ role: "readWriteAnyDatabase", db: "admin" }]
)
Revoke Roles from a User
use admin
db.revokeRolesFromUser(
"dbAdmin",
[{ role: "readWriteAnyDatabase", db: "admin" }]
)
Updating a User's Password
use admin
db.changeUserPassword("dbAdmin", "newSecurePassword456")
Removing a User
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:
use admin
db.createUser({
user: "adminUser",
pwd: "superSecureAdminPwd!123",
roles: [{ role: "userAdminAnyDatabase", db: "admin" }]
})
Step 2: Restart MongoDB with Authentication Enabled
mongod --auth --dbpath /data/db
Step 3: Connect as Admin and Create Application-Specific Users
// 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
// 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:
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
- Follow the principle of least privilege: Give users only the permissions they need
- Use separate users for different applications: Don't share credentials between applications
- Create custom roles when needed: For fine-grained control
- Regularly audit user permissions: Remove unused accounts and unnecessary privileges
- Never use the root user for applications: The root user should only be used for system administration
- Rotate passwords regularly: Set a password rotation policy
- Never store credentials in code: Use environment variables or secure secret management systems
- Set strong password policies: Require complex passwords
- 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:
// 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:
-
Check the user's roles: Ensure the user has the necessary roles for the operation
javascriptdb.getUser("username")
-
Check role privileges: Verify what actions a role allows
javascriptdb.getRole("roleName", { showPrivileges: true })
-
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
-
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
- Create a user with read-only access to one collection and read-write access to another collection in the same database
- Design a role hierarchy for a typical web application with user management, content management, and analytics functions
- Implement field-level security to hide sensitive customer information from customer service representatives
- 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! :)