MongoDB Security Architecture

MongoDB Security Architecture

Security Layers Overview

Client Authentication → Network Isolation → Authorization (RBAC) → 
Audit Logging → Encryption (Transit + Rest + Field-Level)

Client Authentication

Authentication Mechanisms

Mechanism Atlas Self-Managed Notes
SCRAM-SHA-256 Yes Yes Default; password-based
SCRAM-SHA-1 Legacy only Yes Deprecated; disable if possible
X.509 Certificates Yes (M10+) Yes Mutual TLS; strong security
LDAP (PLAIN/GSSAPI) Yes (M10+) Yes Deprecated in MongoDB 8.0
OIDC (MONGODB-OIDC) Yes (M10+) 7.0+ Workforce + Workload Federation
AWS IAM (MONGODB-AWS) Yes (M10+) No Passwordless via IAM role
Kerberos (GSSAPI) No Yes Enterprise only

SCRAM-SHA-256 Configuration

// Create user with SCRAM (most common)
db.createUser({
  user: "appService",
  pwd: "StrongPassword123!",
  roles: [
    { role: "readWrite", db: "myapp" },
    { role: "read", db: "analytics" }
  ]
})

// Verify authentication mechanism
db.runCommand({ usersInfo: "appService", showCredentials: true })
// Check SCRAM-SHA-256 mechanism is present

X.509 Certificate Authentication

# Connect with X.509 certificate
mongosh "mongodb://cluster.mongodb.net:27017" \
  --tls \
  --tlsCertificateKeyFile /path/to/client.pem \
  --tlsCAFile /path/to/ca.pem \
  --authenticationMechanism MONGODB-X509

# Create a certificate-authenticated user
db.createUser({
  user: "CN=appService,OU=Applications,O=MyOrg,C=US",  // Must match certificate Subject DN
  customData: { role: "app" },
  roles: [{ role: "readWrite", db: "myapp" }]
})

MONGODB-OIDC (OIDC/Workforce/Workload)

// Connection string for OIDC with Azure Managed Identity
"mongodb+srv://cluster.mongodb.net/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:azure,TOKEN_RESOURCE:<audience>"

// Connection string for OIDC with GCP
"mongodb+srv://cluster.mongodb.net/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:gcp,TOKEN_RESOURCE:<audience>"

// AWS (IRSA/EKS Workload Identity)
"mongodb+srv://cluster.mongodb.net/?authMechanism=MONGODB-AWS"

MONGODB-AWS (AWS IAM)

// IAM Role database user (create in Atlas)
// Username = ARN of IAM user or role
db.createUser({
  user: "arn:aws:iam::123456789:role/app-production",
  roles: [{ role: "readWrite", db: "myapp" }]
})

// Connection string with IAM (IRSA picks up credentials automatically)
"mongodb+srv://cluster.mongodb.net/?authMechanism=MONGODB-AWS"

Network Security

TLS Requirements

Atlas enforces TLS 1.2+ by default. For self-managed:

# mongod.conf
net:
  tls:
    mode: requireTLS           # enforces TLS for all connections
    PEMKeyFile: /etc/ssl/server.pem
    CAFile: /etc/ssl/ca.pem
    disabledProtocols: TLS1,TLS1_1  # require TLS 1.2+
    allowedTLSCiphers: "ECDHE-RSA-AES256-GCM-SHA384:..."

Network Access Controls

For Atlas:

For self-managed:

Encrypted Transit Verification

// Check TLS on connection
db.runCommand({ connectionStatus: 1, showPrivileges: false })
// Result includes: sslVersion, sslProtocol

Role-Based Access Control (RBAC)

Built-in Role Hierarchy

Organization Roles → Project Roles → Database Roles → Collection Roles

Principle of Least Privilege: Each application component gets only the minimum roles needed.

Common Role Patterns

// Read-only analytics service
db.createUser({
  user: "analyticsReader",
  roles: [{ role: "read", db: "analytics" }]
})

// Write-only ingest service (insert only, no reads, no deletes)
db.createUser({
  user: "ingestWriter",
  roles: [{ role: "insert", db: "raw_data" }]  // custom role with only insert action
})

// Admin service (cluster operations only, no data access)
db.createUser({
  user: "clusterAdmin",
  roles: ["clusterMonitor", "backup"]
})

Custom Database Roles

// Create fine-grained custom role
db.createRole({
  role: "orderReader",
  privileges: [
    {
      resource: { db: "ecommerce", collection: "orders" },
      actions: ["find"]
    },
    {
      resource: { db: "ecommerce", collection: "customers" },
      actions: ["find"]
    }
  ],
  roles: []  // no inherited roles
})

Encryption

Encryption at Rest

Atlas: Default AES-256 encryption at rest using MongoDB-managed keys. For BYOK (Customer Key Management):

# Terraform: enable KMS encryption at rest
resource "mongodbatlas_encryption_at_rest" "atlas" {
  project_id = var.project_id
  aws_kms_config {
    enabled                = true
    customer_master_key_id = var.kms_key_id
    region                 = "us-east-1"
    role_id                = mongodbatlas_cloud_provider_access_setup.atlas.role_id
  }
}

Encryption in Transit

All client connections: TLS 1.2+. Internal replication traffic: TLS optional on self-managed (required on Atlas).

Field-Level Encryption (CSFLE / Queryable Encryption)

For sensitive fields that must be encrypted even from DBA access:

See mongodb-encryption for complete implementation guide.

Audit Logging

Atlas Database Auditing (M10+)

// Configure audit filter (in Atlas UI → Advanced → Database Auditing)
// Or via Admin API:
{
  "atype": {
    "$in": ["authenticate", "authCheck", "createUser", "dropUser",
            "createCollection", "dropCollection", "createDatabase",
            "dropDatabase", "createIndex", "dropIndex", "logout"]
  }
}

Self-Managed Audit Logging

# mongod.conf
auditLog:
  destination: file
  format: JSON
  path: /var/log/mongodb/audit.log
  filter: '{ "atype": { "$in": ["authenticate", "authCheck"] } }'

SIEM Integration

Route Atlas audit logs to SIEM:

Secrets Management

MongoDB Credentials in Applications

# BAD: credentials in code
client = MongoClient("mongodb+srv://user:hardcoded@cluster...")

# GOOD: credentials from environment (secrets manager)
import os
from pymongo import MongoClient
client = MongoClient(os.environ["MONGODB_URI"])

# BEST: passwordless (OIDC/AWS IAM)
client = MongoClient("mongodb+srv://cluster.../?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:aws")

Secrets Manager Integration

Security Hardening Checklist

Atlas

Self-Managed

Common Security Anti-Patterns

References