MongoDB Security & Authentication

Protect your database with authentication and authorization

🔐 What is MongoDB Security?

MongoDB security protects your data through authentication, authorization, encryption, and network security. It ensures only authorized users access specific data with appropriate permissions, preventing unauthorized access and data breaches.


// Create user with authentication
db.createUser({
  user: "appUser",
  pwd: "securePassword123",
  roles: [{ role: "readWrite", db: "myapp" }]
})
                                    

Result:

User created with read/write access to myapp database

Key Security Features

👤

Authentication

Verify user identity

db.auth("username", "password")
🔑

Authorization

Control user permissions

roles: ["readWrite", "dbAdmin"]
🔒

Encryption

Encrypt data at rest and in transit

--tlsMode requireTLS
🛡️

Network Security

Restrict network access

--bind_ip 127.0.0.1

🔹 Enabling Authentication

Enable authentication to require users to identify themselves before accessing the database. Start MongoDB with authentication enabled and create an admin user first.

// 1. Start MongoDB without authentication
mongod --port 27017 --dbpath /data/db

// 2. Connect and create admin user
use admin
db.createUser({
  user: "admin",
  pwd: "strongAdminPassword",
  roles: [
    { role: "userAdminAnyDatabase", db: "admin" },
    { role: "readWriteAnyDatabase", db: "admin" }
  ]
})

// 3. Restart MongoDB with authentication
mongod --auth --port 27017 --dbpath /data/db

// 4. Connect with authentication
mongosh --port 27017 -u "admin" -p "strongAdminPassword" --authenticationDatabase "admin"

// Or authenticate after connecting
use admin
db.auth("admin", "strongAdminPassword")

// In application code (Node.js)
const { MongoClient } = require('mongodb');
const uri = "mongodb://admin:strongAdminPassword@localhost:27017/?authSource=admin";
const client = new MongoClient(uri);

Result:

Authentication enabled. Users must provide credentials to access database.

🔹 Creating Users and Roles

Create users with specific roles to control database access. Assign built-in roles or create custom roles with precise permissions for different application needs.

// Create application user with read/write access
use myapp
db.createUser({
  user: "appUser",
  pwd: "appPassword123",
  roles: [
    { role: "readWrite", db: "myapp" }
  ]
})

// Create read-only user
db.createUser({
  user: "analyst",
  pwd: "analystPass",
  roles: [
    { role: "read", db: "myapp" }
  ]
})

// Create user with multiple roles
db.createUser({
  user: "developer",
  pwd: "devPassword",
  roles: [
    { role: "readWrite", db: "myapp" },
    { role: "dbAdmin", db: "myapp" }
  ]
})

// Built-in roles:
// - read: Read data from all non-system collections
// - readWrite: Read and write data
// - dbAdmin: Database administration tasks
// - userAdmin: Create and modify users and roles
// - clusterAdmin: Cluster administration
// - root: Full access to all resources

// View user information
db.getUser("appUser")

// Update user password
db.changeUserPassword("appUser", "newPassword456")

// Grant additional role
db.grantRolesToUser("appUser", [{ role: "dbAdmin", db: "myapp" }])

// Revoke role
db.revokeRolesFromUser("appUser", [{ role: "dbAdmin", db: "myapp" }])

// Delete user
db.dropUser("appUser")

Result:

Users created with appropriate permissions for their roles

🔹 Custom Roles

Create custom roles with specific privileges for fine-grained access control. Define exactly which actions users can perform on which resources for enhanced security.

// Create custom role with specific privileges
use myapp
db.createRole({
  role: "ordersManager",
  privileges: [
    {
      resource: { db: "myapp", collection: "orders" },
      actions: ["find", "insert", "update"]
    },
    {
      resource: { db: "myapp", collection: "customers" },
      actions: ["find"]  // Read-only on customers
    }
  ],
  roles: []  // No inherited roles
})

// Create role with inherited roles
db.createRole({
  role: "seniorDeveloper",
  privileges: [
    {
      resource: { db: "myapp", collection: "" },  // All collections
      actions: ["find", "insert", "update", "remove"]
    }
  ],
  roles: [
    { role: "read", db: "logs" }  // Also read logs database
  ]
})

// Assign custom role to user
db.createUser({
  user: "orderManager",
  pwd: "managerPass",
  roles: ["ordersManager"]
})

// Common actions:
// - find, insert, update, remove
// - createCollection, dropCollection
// - createIndex, dropIndex
// - viewRole, viewUser

// View role details
db.getRole("ordersManager", { showPrivileges: true })

// Update role
db.updateRole("ordersManager", {
  privileges: [
    {
      resource: { db: "myapp", collection: "orders" },
      actions: ["find", "insert", "update", "remove"]  // Added remove
    }
  ]
})

Result:

Custom role created with precise permissions

🔹 Connection String Security

Secure your connection strings by using environment variables, avoiding hardcoded credentials, and implementing proper authentication mechanisms in your application code.

// ❌ BAD: Hardcoded credentials
const uri = "mongodb://admin:password123@localhost:27017/myapp";

// ✅ GOOD: Use environment variables
const uri = `mongodb://${process.env.DB_USER}:${process.env.DB_PASS}@${process.env.DB_HOST}:27017/myapp`;

// Connection string format
// mongodb://[username:password@]host[:port][/database][?options]

// With authentication database
const uri = "mongodb://appUser:appPass@localhost:27017/myapp?authSource=admin";

// MongoDB Atlas connection (cloud)
const uri = "mongodb+srv://username:[email protected]/myapp?retryWrites=true&w=majority";

// With TLS/SSL
const uri = "mongodb://user:pass@host:27017/db?tls=true&tlsCAFile=/path/to/ca.pem";

// Connection options for security
const client = new MongoClient(uri, {
  useNewUrlParser: true,
  useUnifiedTopology: true,
  tls: true,
  tlsAllowInvalidCertificates: false,  // Validate certificates
  authSource: 'admin',
  authMechanism: 'SCRAM-SHA-256'
});

// .env file example
// DB_USER=appUser
// DB_PASS=securePassword123
// DB_HOST=localhost
// DB_NAME=myapp

// Load environment variables
require('dotenv').config();
const uri = `mongodb://${process.env.DB_USER}:${process.env.DB_PASS}@${process.env.DB_HOST}:27017/${process.env.DB_NAME}`;

Best Practice:

Always use environment variables, never commit credentials to version control

🔹 Network Security

Restrict network access to your MongoDB instance using IP whitelisting, firewalls, and binding to specific network interfaces. Limit exposure to trusted networks only.

// Bind to specific IP (localhost only)
mongod --bind_ip 127.0.0.1

// Bind to multiple IPs
mongod --bind_ip 127.0.0.1,192.168.1.100

// Configuration file (mongod.conf)
net:
  port: 27017
  bindIp: 127.0.0.1,192.168.1.100
  
security:
  authorization: enabled

// Enable TLS/SSL
net:
  tls:
    mode: requireTLS
    certificateKeyFile: /path/to/mongodb.pem
    CAFile: /path/to/ca.pem

// Firewall rules (Linux iptables)
// Allow only specific IP
sudo iptables -A INPUT -p tcp -s 192.168.1.100 --dport 27017 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 27017 -j DROP

// MongoDB Atlas (cloud) - IP Whitelist
// Add your application server IPs in Atlas dashboard
// Network Access → IP Access List → Add IP Address

// VPC Peering for private connections
// Connect Atlas to your cloud provider's VPC

// Use VPN for remote access
// Don't expose MongoDB directly to the internet

Security Checklist:

✅ Bind to specific IPs ✅ Enable firewall ✅ Use TLS ✅ Whitelist IPs

🔹 Encryption

Protect data with encryption at rest and in transit. Use TLS for network encryption and enable encryption at rest for sensitive data stored on disk.

// Encryption in Transit (TLS/SSL)
// Start MongoDB with TLS
mongod --tlsMode requireTLS \
  --tlsCertificateKeyFile /path/to/mongodb.pem \
  --tlsCAFile /path/to/ca.pem

// Connect with TLS
mongosh --tls \
  --tlsCertificateKeyFile /path/to/client.pem \
  --tlsCAFile /path/to/ca.pem \
  --host mongodb.example.com

// In application (Node.js)
const client = new MongoClient(uri, {
  tls: true,
  tlsCertificateKeyFile: '/path/to/client.pem',
  tlsCAFile: '/path/to/ca.pem'
});

// Encryption at Rest (Enterprise feature)
// mongod.conf
security:
  enableEncryption: true
  encryptionKeyFile: /path/to/keyfile

// Client-Side Field Level Encryption (CSFLE)
const { ClientEncryption } = require('mongodb-client-encryption');

const encryption = new ClientEncryption(client, {
  keyVaultNamespace: 'encryption.__keyVault',
  kmsProviders: {
    local: {
      key: Buffer.from(process.env.MASTER_KEY, 'base64')
    }
  }
});

// Encrypt sensitive field
const encryptedSSN = await encryption.encrypt(
  '123-45-6789',
  {
    algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic',
    keyId: dataKeyId
  }
);

// Store encrypted data
await db.users.insertOne({
  name: "John Doe",
  ssn: encryptedSSN  // Encrypted field
});

Encryption Types:

In Transit (TLS) | At Rest (Enterprise) | Field-Level (CSFLE)

🔹 Security Best Practices

Follow these essential security guidelines to protect your MongoDB deployment. Implement defense in depth with multiple security layers for comprehensive protection.

✅ Essential Security Measures:

  • Enable authentication: Always require user credentials
  • Use strong passwords: Minimum 12 characters, mixed case, numbers, symbols
  • Principle of least privilege: Grant minimum required permissions
  • Enable TLS/SSL: Encrypt data in transit
  • Restrict network access: Use firewalls and IP whitelisting
  • Regular updates: Keep MongoDB version current
  • Audit logging: Track database access and changes
  • Backup encryption: Encrypt backup files

❌ Security Mistakes to Avoid:

  • Running without authentication enabled
  • Using default ports without firewall
  • Exposing MongoDB directly to internet
  • Hardcoding credentials in code
  • Granting excessive permissions
  • Ignoring security updates
  • Not encrypting sensitive data
// Security configuration checklist
// mongod.conf
security:
  authorization: enabled
  
net:
  bindIp: 127.0.0.1,192.168.1.100
  tls:
    mode: requireTLS
    certificateKeyFile: /path/to/cert.pem

systemLog:
  destination: file
  path: /var/log/mongodb/mongod.log
  
auditLog:
  destination: file
  path: /var/log/mongodb/audit.log

🧠 Test Your Knowledge

Which role provides read and write access to a database?