MongoDB out-of-the-box hat keine Authentication aktiviert. Eine fresh Installation akzeptiert Connections ohne Credentials – jeder mit Netzwerk-Zugriff hat vollen Admin-Access. Dies ist convenient für lokale Development, aber katastrophal für Production. Die erste Frage bei jedem Production-Deployment: “Ist Authentication aktiviert?” Wenn nicht, ist die Datenbank offen für die Welt – ein Sicherheits-Desaster.
User-Management in MongoDB basiert auf Role-Based Access Control (RBAC). Users haben Rollen, Rollen haben Privileges, Privileges definieren Actions auf Resources. Dies ist granular und flexibel – man kann einen User definieren, der nur Read-Access auf eine spezifische Collection hat, oder einen Admin mit Full-Cluster-Management. Aber Flexibilität kommt mit Komplexität. MongoDB hat dutzende Built-in-Rollen mit subtilen Unterschieden, und Custom-Roles können arbiträr komplex werden.
Dieses Kapitel behandelt User-Management systematisch – von Basics (User-Creation, Authentication) über Rollen-Design bis zu Production-Best-Practices für Security. Der Fokus ist nicht nur “wie erstellt man User”, sondern “wie designed man ein sicheres, auditbares Access-Control-System”.
Diese Begriffe werden oft verwechselt, aber sie sind fundamental unterschiedlich.
Authentication: “Wer bist du?” – Verification der Identity. MongoDB prüft: Ist dieser Username+Password valid? Ist dieses Certificate korrekt signiert? Dies ist der erste Schritt bei jeder Connection.
Authorization: “Was darfst du?” – Control of Actions. Nachdem Identity verified ist, prüft MongoDB: Hat dieser User Permission für diese Action (read, write, createIndex, etc.) auf dieser Resource (Database, Collection)?
Beide sind essentiell. Authentication ohne Authorization ist sinnlos – jeder kann alles. Authorization ohne Authentication ist unmöglich – man kann Permissions nicht enforcem ohne zu wissen, wer connected.
MongoDB’s RBAC-System handelt Authorization. User-Accounts mit Credentials handeln Authentication. Beides zusammen bildet MongoDB’s Security-Model.
Bevor man Users erstellen kann, muss ein Admin-User existieren. Bei einer fresh Installation mit aktivierter Authentication kann niemand connecten – ein Chicken-and-Egg-Problem. MongoDB’s Lösung: Die localhost-Exception.
Localhost Exception:
Wenn MongoDB Authentication aktiviert hat aber noch keine Users existieren, erlaubt es Connections von localhost, um den ersten Admin-User zu erstellen:
// Von localhost, bevor irgendein User existiert
mongosh --host localhost
use admin
db.createUser({
user: "admin",
pwd: "SecureAdminPassword123!",
roles: [{ role: "root", db: "admin" }]
})Nach diesem ersten User-Create ist die Localhost-Exception disabled. Alle weiteren Connections erfordern Authentication.
Die root-Rolle:
root ist die mächtigste Rolle – Full-Access auf alles.
Sie kombiniert alle Admin-Rollen und erlaubt jede Action. Für Production
sollte der root-User extrem restricted sein – nur von Admins in
Notfällen genutzt. Day-to-Day-Operations sollten Least-Privilege-Users
nutzen.
Ein MongoDB-User hat mehrere Components:
db.createUser({
user: "appUser", // Username
pwd: "Password123!", // Password
roles: [ // Roles array
{ role: "readWrite", db: "productionDB" },
{ role: "read", db: "analyticsDB" }
],
mechanisms: ["SCRAM-SHA-256"], // Auth mechanism
customData: { // Optional metadata
department: "Engineering",
createdBy: "admin@company.com"
}
})User ist Database-spezifisch:
Users werden in einer spezifischen Database erstellt – typischerweise
admin. Dies ist die “Authentication Database” – wo MongoDB
die User-Credentials speichert. Man connected zu MongoDB mit:
mongosh --username appUser --password Password123! --authenticationDatabase adminDie --authenticationDatabase ist kritisch – ohne sie
weiß MongoDB nicht, wo es den User suchen soll.
Warum admin als Auth-Database:
Per Convention speichert man alle Users in admin, auch
wenn sie nur auf andere Databases zugreifen. Dies zentralisiert
User-Management. Alternativ könnte man Users in jeder Database
erstellen, aber das ist verwirrend und schwer zu maintainen.
Password-Hashing:
Passwords werden nie im Klartext gespeichert. MongoDB hasht sie mit
SCRAM (Salted Challenge Response Authentication Mechanism). Das Password
in createUser() wird automatisch gehasht – man gibt
Plaintext, MongoDB speichert nur den Hash.
MongoDB hat dutzende Built-in-Rollen für Common-Use-Cases. Die wichtigsten:
Database-Level-Rollen:
// Read-only auf eine Database
{ role: "read", db: "myDB" }
// Read-Write auf eine Database
{ role: "readWrite", db: "myDB" }
// Database-Administration (Indexes, Stats, aber kein Data-Access)
{ role: "dbAdmin", db: "myDB" }
// User-Administration für eine Database
{ role: "userAdmin", db: "myDB" }
// dbOwner = readWrite + dbAdmin + userAdmin
{ role: "dbOwner", db: "myDB" }All-Databases-Rollen:
Für Users, die auf alle Databases zugreifen müssen (rare, meist nur Monitoring-Tools):
{ role: "readAnyDatabase", db: "admin" }
{ role: "readWriteAnyDatabase", db: "admin" }
{ role: "dbAdminAnyDatabase", db: "admin" }
{ role: "userAdminAnyDatabase", db: "admin" }Diese gelten für alle Databases im Cluster. Die
db: "admin"-Spec ist Pflicht – sie definiert, wo die Rolle
stored ist, nicht worauf sie zugreift.
Cluster-Management-Rollen:
Für Replica-Sets und Sharded-Clusters:
{ role: "clusterAdmin", db: "admin" } // Full Cluster-Management
{ role: "clusterManager", db: "admin" } // Shard/Replica-Management
{ role: "clusterMonitor", db: "admin" } // Read-only Cluster-Metrics
{ role: "hostManager", db: "admin" } // Server-Process-ManagementBackup/Restore-Rollen:
{ role: "backup", db: "admin" }
{ role: "restore", db: "admin" }Diese erlauben mongodump/mongorestore, aber
keinen normalen Data-Access – perfect für Backup-Scripts.
Die root-Rolle:
{ role: "root", db: "admin" }Superuser – kann alles. Nur für Admins, nie für Applications.
Scenario 1: Application-User
Eine Web-App braucht Read-Write auf ihre Database, sonst nichts:
db.createUser({
user: "webApp",
pwd: "AppPassword123!",
roles: [
{ role: "readWrite", db: "productionDB" }
]
})Dies ist Least-Privilege – die App kann weder andere Databases sehen noch Admin-Actions ausführen.
Scenario 2: Analytics-User
Ein Analytics-Tool braucht Read-only über mehrere Databases:
db.createUser({
user: "analyticsUser",
pwd: "AnalyticsPass123!",
roles: [
{ role: "read", db: "productionDB" },
{ role: "read", db: "logsDB" },
{ role: "read", db: "metricsDB" }
]
})Read-only verhindert versehentliche Writes durch Analytics-Queries.
Scenario 3: DevOps-Engineer
Ein Engineer braucht Admin-Access für Maintenance, aber kein Data-Access:
db.createUser({
user: "devopsEngineer",
pwd: "DevOpsPass123!",
roles: [
{ role: "dbAdmin", db: "productionDB" }, // Index-Management, Stats
{ role: "clusterMonitor", db: "admin" }, // Cluster-Health
{ role: "backup", db: "admin" } // Backups
]
})Kein readWrite – der Engineer kann keine Daten sehen
oder ändern, nur Infrastructure managen.
Scenario 4: Monitoring-System
Prometheus, Grafana oder andere Monitoring-Tools brauchen Read-only auf Metrics:
db.createUser({
user: "monitoring",
pwd: "MonitorPass123!",
roles: [
{ role: "clusterMonitor", db: "admin" }
]
})Dies erlaubt das Lesen von serverStatus,
dbStats, Replica-Set-Health, aber keinen Data-Access.
Scenario 5: Temporary Admin
Ein Consultant braucht temporären Full-Access:
db.createUser({
user: "consultant",
pwd: "TempPass123!",
roles: [
{ role: "root", db: "admin" }
]
})
// Nach dem Consulting-Engagement
db.dropUser("consultant")Temporary-Accounts sollten immer time-limited sein und promptly deleted.
Für spezifische Requirements, die Built-in-Rollen nicht abdecken, kann man Custom-Roles erstellen.
Example: Marketing-Team-Read-Access auf spezifische Collections
db.createRole({
role: "marketingReader",
privileges: [
{
resource: { db: "productionDB", collection: "campaigns" },
actions: ["find", "aggregate"]
},
{
resource: { db: "productionDB", collection: "customers" },
actions: ["find"]
}
],
roles: [] // Kann auch andere Rollen inheriten
})
// User mit dieser Role
db.createUser({
user: "marketingUser",
pwd: "MarketingPass123!",
roles: [
{ role: "marketingReader", db: "admin" }
]
})Dieser User kann nur zwei Collections sehen – campaigns
und customers – und nur Read-Actions (find, aggregate)
ausführen.
Privilege-Components:
Jedes Privilege hat: - resource: Was wird kontrolliert? (Database, Collection, Cluster) - actions: Welche Actions sind erlaubt? (find, insert, update, remove, createIndex, etc.)
MongoDB hat hunderte Actions. Die wichtigsten:
| Action | Beschreibung |
|---|---|
find |
Query-Documents |
insert |
Insert-Documents |
update |
Update-Documents |
remove |
Delete-Documents |
createIndex |
Index-Creation |
dropIndex |
Index-Deletion |
createCollection |
Collection-Creation |
dropCollection |
Collection-Deletion |
viewRole |
View-Roles |
createUser |
User-Creation |
dropUser |
User-Deletion |
Für eine komplette Liste: MongoDB-Dokumentation unter “Privilege Actions”.
Role-Inheritance:
Custom-Roles können andere Rollen inheriten:
db.createRole({
role: "dataScientist",
privileges: [
{
resource: { db: "analyticsDB", collection: "" }, // Alle Collections
actions: ["find", "aggregate"]
}
],
roles: [
{ role: "read", db: "productionDB" } // Inherit read auf production
]
})Dies kombiniert Custom-Privileges mit Built-in-Rollen – flexibel und maintainable.
Password-Complexity:
MongoDB enforced keine Password-Policies (anders als manche SQL-Datenbanken). Es akzeptiert jeden String als Password. Die Enforcement ist Application-Responsibility:
// Schlecht - weak password
db.createUser({
user: "app",
pwd: "123",
roles: [...]
})
// Gut - strong password
db.createUser({
user: "app",
pwd: "Kj$9mL#pQ2wX!vN8",
roles: [...]
})Best Practice: Mindestens 16 Zeichen, Mix aus Upper/Lower/Digits/Symbols, keine Dictionary-Words.
Password-Rotation:
Passwords sollten regelmäßig rotated werden:
db.updateUser("appUser", {
pwd: "NewSecurePassword456!"
})Dies updated nur das Password, Roles bleiben unverändert. Für Production-Applications sollte man Password-Rotation automatisieren – etwa quarterly oder after Security-Incidents.
Externe Password-Management:
Für Enterprise-Environments sollte man Passwords nicht in Scripts hardcoden. Optionen:
export MONGODB_PASSWORD="SecurePass123!"
mongosh --username app --password "$MONGODB_PASSWORD"Secrets-Management-Systems: HashiCorp Vault, AWS Secrets Manager, Azure Key Vault – diese speichern Credentials encrypted und rotaten sie automatisch.
Certificate-Based-Authentication: Statt Passwords nutzt man X.509-Certificates. Kein Password-Management nötig.
MongoDB unterstützt mehrere Authentication-Mechanisms für unterschiedliche Security-Requirements.
SCRAM-SHA-256 (Default):
Salted Challenge-Response – secure gegen Password-Sniffing und Rainbow-Tables. Dies ist der Default seit MongoDB 4.0:
db.createUser({
user: "app",
pwd: "Password123!",
mechanisms: ["SCRAM-SHA-256"], // Explicit, aber Default
roles: [...]
})SCRAM-SHA-1 (Legacy):
Weniger secure als SHA-256, aber für Compatibility mit sehr alten Clients:
mechanisms: ["SCRAM-SHA-1"]Nur nutzen wenn nötig für Backward-Compatibility.
X.509 Certificate Authentication:
Für höchste Security nutzt man Certificates statt Passwords:
db.createUser({
user: "CN=myapp,OU=Engineering,O=Company,C=US", // From certificate subject
roles: [{ role: "readWrite", db: "productionDB" }]
})Connection via Certificate:
mongosh --tls \
--tlsCertificateKeyFile /path/to/client.pem \
--tlsCAFile /path/to/ca.pem \
--authenticationMechanism MONGODB-X509Der Username ist aus dem Certificate-Subject extrahiert. Kein Password nötig – das Certificate ist die Identity.
Vorteile: - Kein Password-Management - Stärkere Crypto (RSA/ECC) - Automatisches Certificate-Rotation via PKI
Nachteile: - Komplexere Setup (Certificate-Authority, PKI) - Certificate-Lifecycle-Management
LDAP (Enterprise):
MongoDB Enterprise kann mit LDAP integrieren für centralized User-Management:
// LDAP-User
db.createUser({
user: "alice@company.com",
roles: [{ role: "readWrite", db: "myDB" }]
})Das Password wird gegen LDAP validated, nicht lokal in MongoDB gespeichert. User-Management passiert in Active Directory oder anderen LDAP-Systemen.
Kerberos (Enterprise):
Für Single-Sign-On in Enterprise-Umgebungen:
mongosh --authenticationMechanism GSSAPI \
--username user@REALM.COMDies nutzt Kerberos-Tickets – kein Password-Input nötig.
Listing Users:
// Alle Users in aktueller DB
db.getUsers()
// Spezifischer User
db.getUser("username")Output zeigt Username, Roles, customData, aber nie das Password (nur Hash).
Updating Roles:
// Roles komplett ersetzen
db.updateUser("appUser", {
roles: [
{ role: "readWrite", db: "productionDB" },
{ role: "read", db: "analyticsDB" }
]
})
// Role hinzufügen
db.grantRolesToUser("appUser", [
{ role: "dbAdmin", db: "productionDB" }
])
// Role entfernen
db.revokeRolesFromUser("appUser", [
{ role: "dbAdmin", db: "productionDB" }
])grantRolesToUser und revokeRolesFromUser
sind granularer als updateUser – sie ändern nur spezifische
Roles, nicht alle.
Deleting Users:
db.dropUser("username")Dies löscht den User permanent. Für Audit-Trails sollte man User nicht löschen, sondern deaktivieren (via Custom-Flag in customData).
1. Principle of Least Privilege:
Jeder User sollte nur minimale Permissions haben. Applications sollten nie root oder admin-Roles haben:
// Schlecht - zu viele Permissions
db.createUser({
user: "app",
pwd: "...",
roles: [{ role: "root", db: "admin" }] // BAD!
})
// Gut - nur nötige Permissions
db.createUser({
user: "app",
pwd: "...",
roles: [{ role: "readWrite", db: "productionDB" }] // Good
})2. Separate Users für separate Applications:
Nicht einen shared User für alle Apps. Jede Application sollte eigenen User haben:
db.createUser({ user: "webApp", roles: [...] })
db.createUser({ user: "mobileApp", roles: [...] })
db.createUser({ user: "batchJobs", roles: [...] })Dies erlaubt granulare Auditing und einfacheres Credential-Rotation.
3. Audit-Logging aktivieren (Enterprise):
MongoDB Enterprise hat Audit-Logging, das alle Auth-Events logged:
# mongod.conf
auditLog:
destination: file
format: JSON
path: /var/log/mongodb/audit.jsonDies logged alle Login-Attempts, Failed-Auths, User-Creation, Role-Changes – essentiell für Security-Audits.
4. Network-Restrictions:
Users sollten nur von spezifischen IP-Ranges connecten dürfen. MongoDB selbst hat kein IP-Whitelisting per User, aber Firewalls können dies enforcem:
# iptables - nur localhost und App-Servers
iptables -A INPUT -p tcp --dport 27017 -s 127.0.0.1 -j ACCEPT
iptables -A INPUT -p tcp --dport 27017 -s 10.0.1.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 27017 -j DROP5. TLS für alle Connections:
Authentication ohne Encryption ist vulnerabel zu Man-in-the-Middle. Alle Production-Connections sollten TLS nutzen:
# mongod.conf
net:
tls:
mode: requireTLS
certificateKeyFile: /path/to/server.pem
CAFile: /path/to/ca.pemClients müssen dann mit --tls connecten.
6. Regular Security-Audits:
Periodisch reviewen, welche Users existieren und welche Permissions sie haben:
// List all users mit ihren Rollen
db.getUsers().forEach(user => {
print(`User: ${user.user}`)
user.roles.forEach(role => {
print(` Role: ${role.role} on ${role.db}`)
})
})Inactive Users sollten deaktiviert oder deleted werden.
7. Password-Expiration (Custom-Implementation):
MongoDB hat keine Built-in-Password-Expiration. Man kann es via customData implementieren:
db.createUser({
user: "app",
pwd: "...",
roles: [...],
customData: {
passwordSetAt: new Date(),
passwordExpiresAt: new Date(Date.now() + 90 * 24 * 60 * 60 * 1000) // 90 days
}
})
// Application-Logic prüft passwordExpiresAt bei LoginDie folgende Tabelle fasst Security-Levels zusammen:
| Level | Authentication | Authorization | Encryption | Audit |
|---|---|---|---|---|
| Development | Optional | Basic (readWrite) | No TLS | No |
| Staging | Required | Role-based | TLS | Optional |
| Production | Required (Strong) | Least-Privilege | TLS Required | Required |
| High-Security | Certificate/LDAP | Custom Roles | TLS + Client-Certs | Full Audit |
User-Management in MongoDB ist nicht nur technisch – es ist fundamental für Security. Eine Datenbank ohne Authentication ist ein offenes Tor. Eine Datenbank mit schwachen Passwords oder Over-Privileged-Users ist kaum besser. Die Best Practice: Authentication immer aktiviert, strong Passwords (oder Certificates), Least-Privilege-Principle rigoros enforced, Audit-Logging für Compliance, und regelmäßige Security-Reviews. Mit diesen Practices wird User-Management von administrativem Overhead zu strategischem Security-Asset – die erste und wichtigste Defense-Line gegen unauthorized Access.