142: MongoDB Security — Authentication, RBAC, TLS, Network Controls, Encryption, Auditing, and Queryable Encryption
Learning objectives
By the end of this lesson, you should be able to:
- secure MongoDB network access;
- explain how MongoDB authentication works;
- use role-based access control;
- apply least privilege to application credentials;
- configure and reason about TLS;
- explain what encryption at rest does and does not protect;
- understand client-side field-level encryption;
- describe Queryable Encryption conceptually;
- recognize the purpose of X.509, Kerberos, and LDAP enterprise options at a high level;
- use auditing appropriately;
- protect connection strings and credentials;
- secure Atlas deployments;
- prevent application-level operator injection and tenant leaks.
Security here is a layered responsibility. A database credential, by itself, does not make an exposed deployment safe. You need to control who can reach the deployment, how the connection is protected, which database identity is used, and what the application allows an authenticated user to do.
Security starts with network exposure
The first question is not which MongoDB role to grant. It is whether an attacker can reach the server at all. Never run production MongoDB open to the public internet with weak or missing authentication.
A practical security boundary usually includes several controls:
private network / firewall
Atlas network access / private endpoints
TLS
authentication
RBAC
application authorization
These layers address different problems. Network controls limit the clients that can connect. TLS protects traffic and helps the client verify the server. Authentication identifies the connecting service or user. RBAC limits that identity's database privileges, and application authorization decides whether the logged-in person is allowed to perform a particular business action.
Database authentication does not replace network controls. If a service is reachable from everywhere, attackers have more opportunities to discover, probe, and attack it, even when credentials are required.
When a connection fails, work through these boundaries in order. First ask whether the client can resolve and reach the endpoint. Then check TLS negotiation and certificate validation, followed by database authentication and authorization. This sequence prevents a team from weakening a later control to compensate for a problem in an earlier one.
Authentication
MongoDB authenticates users and services through mechanisms configured for the deployment. Authentication answers, "Who is this database client?" It does not answer whether that identity should be allowed to update a particular tenant's document.
Common application deployments use username/password SCRAM, or cloud and managed-identity integrations where the deployment supports them. Enterprise environments may use:
- X.509;
- Kerberos;
- LDAP proxy;
- cloud IAM integrations.
Use the mechanism supported by your deployment and security team. Choosing an enterprise mechanism is an operational and identity-infrastructure decision, not something to introduce casually in application code.
SCRAM
Username/password authentication uses SCRAM mechanisms. The client presents credentials through the driver, and the server verifies them using the configured database user rather than trusting the application to identify itself.
A connection URI may look like this:
mongodb+srv://appUser:...@cluster/...
The ellipsis is intentionally not a real secret. Never embed a literal password in source code, documentation that is committed, or a command that will be copied into a shared log.
Use a secret manager or environment injection instead. When credentials contain characters with a special meaning in a URI, they must be URL-encoded when a URI is built. Prefer the driver's URI and configuration facilities rather than hand-assembling a string, because parsing and escaping mistakes are easy to make.
Separate users by service
Do not share a root or admin credential across applications:
root/admin credential
Create a dedicated application user for each service, or for each well-defined trust boundary. Give that user only the permissions required for the databases and actions the service actually performs.
If a service performs only CRUD tasks, it should not receive cluster administration privileges:
do not grant clusterAdmin
Separate users make least privilege enforceable and make incidents diagnosable. If one service is compromised, its credential should not automatically provide control over unrelated services or the entire cluster.
RBAC
MongoDB's built-in roles include database and cluster administrative roles as well as read and write roles. Custom roles can grant more specific privileges when the built-in roles are broader than the service needs.
The governing principle is:
least privilege
An application credential should not be able to:
- create admin users;
- drop unrelated databases;
- change cluster configuration;
- read an unrelated tenant database when that access can be avoided.
Review roles against the actual operations in the service. A role that was convenient during development often becomes a permanent production risk if nobody revisits it.
App authorization still required
Suppose the MongoDB user has this database privilege:
readWrite on app database
MongoDB still does not know which logged-in tenant or user may access which task. Database RBAC identifies the service at the database boundary; it does not understand your application's business relationships.
The application must enforce the relevant conditions, such as:
tenantId
ownership
permissions
status
The useful distinction is that DB RBAC is a service-level boundary, while application ABAC/RBAC is a user-level boundary. You need both. Giving an application user readWrite does not authorize every human user of that application to read every document.
Atlas database users
Atlas separates Atlas project and cloud-user concepts from database users. These identities may both appear in the same product interface, but they control different things.
Understand which credential controls:
- Atlas administration;
- database access.
Do not grant developers a production database superuser merely because they need to log in to the Atlas UI. Atlas administration and the ability to read or modify production data should be separate permissions whenever the deployment allows it.
Network allowlist
Atlas can restrict which IP addresses are allowed to connect. This is a network admission control, not a replacement for TLS or authentication.
For production, a stronger design generally uses:
- a private endpoint or peering;
- stable egress addresses;
- a narrow allowlist.
0.0.0.0/0 means broad internet exposure. Avoid it unless there is a documented reason and strong compensating controls, and treat any temporary exception as a temporary policy that must be removed.
When debugging an allowlist problem, distinguish network reachability from authentication. A blocked client cannot complete a database login; a reachable client with bad credentials gets a different failure. Check the deployment's network rules, the service's actual egress address, and the connection configuration before changing security controls broadly.
TLS
TLS encrypts network traffic between the MongoDB client and server. It also gives the client a way to verify that it is talking to the intended server when certificate validation and hostname checks are configured correctly.
MongoDB clients and servers can verify certificates. Do not disable certificate verification in production to "fix" a TLS error:
tlsAllowInvalidCertificates=true
Instead, fix the CA chain, certificate configuration, or hostname mismatch. Encryption without proper certificate validation can still leave the client vulnerable to connecting to the wrong endpoint.
Certificate rotation
Certificate replacement is an availability concern as well as a security concern. Plan for:
- expiration monitoring;
- CA rotation;
- an overlap period;
- deployment of the new configuration.
A certificate expiring at midnight can cause a full outage if the replacement path has not been tested. Monitor expiration before the deadline and verify that clients trust the new CA before removing the old trust path.
X.509
In enterprise and security-managed environments, client and server certificates can authenticate database users. X.509 provides a strong machine identity based on certificates rather than a shared password.
The operational complexity is real:
- PKI;
- issuance;
- rotation;
- DN mapping.
The application's responsibility is usually to use the approved driver and certificate configuration. The organization must operate the certificate lifecycle and identity mapping safely.
Kerberos
Kerberos is an enterprise single-sign-on mechanism and is common in corporate identity environments. It can be appropriate when the organization already operates the required identity infrastructure.
Do not implement it simply because it sounds more enterprise-grade. Use it when the organization's identity architecture and security requirements call for it, and let the identity team define the operational model.
LDAP proxy
MongoDB Enterprise can integrate LDAP authorization and authentication workflows, depending on the product capability and deployment configuration. LDAP can centralize identity policy, but it introduces dependencies on the organization's directory and proxy setup.
For most application developers, this is a roadmap and integration topic. Applications usually consume centrally managed identity rather than implementing LDAP policy themselves.
Encryption at rest
Atlas, cloud providers, and disk-encryption systems can encrypt data at rest. This protects storage media, such as a lost disk or an exposed snapshot, according to the deployment's key-management configuration.
It does not prevent an authorized database query from reading plaintext fields. Once MongoDB has access to decrypt storage for normal operation, a user or service authorized to query a field can generally receive its plaintext value.
That limitation is the reason encryption at rest and field-level encryption are separate design decisions.
KMS
Encryption keys may be managed through a cloud KMS or customer-managed keys, depending on the deployment. Key access policy and rotation then become part of the security design, not merely an infrastructure detail.
Losing the key can mean losing access to the data. Plan key ownership, backup and recovery procedures, rotation, and the permissions that allow the database deployment to use the key.
Client-Side Field Level Encryption (CSFLE)
With Client-Side Field Level Encryption, the driver encrypts selected sensitive fields before sending data to MongoDB. The database can therefore store ciphertext without having plaintext access for those fields in the selected model.
The basic flow is:
app driver
→ encrypt field
→ Mongo stores encrypted
→ authorized client decrypts
A key vault and/or KMS is involved. This can be useful when database operators should not see sensitive fields, even though the application needs to store them.
CSFLE adds key-management and application complexity, and it introduces query limitations depending on the encryption type. Decide which fields need this protection and which operations must remain possible before choosing the encryption model.
Queryable Encryption
Queryable Encryption provides capabilities for querying selected encrypted fields while keeping plaintext protected from the server under its designed threat model. It is not a promise that every ordinary MongoDB query works unchanged on ciphertext.
Capabilities evolve by MongoDB version. In MongoDB 8.3, consult the official Queryable Encryption documentation for supported query types and index behavior rather than relying on an old example or assuming that a query is supported.
Do not invent custom deterministic encryption just so an application can query sensitive values. Custom cryptography is easy to get subtly wrong and can reveal patterns or create key-management failures. Use the supported design and accept its documented trade-offs.
Encryption and indexing
Ordinary randomly encrypted ciphertext cannot support normal plaintext index queries, because the database cannot compare the ciphertext as if it were the original value.
Queryable Encryption uses a specialized design to support selected operations. That design has performance and storage trade-offs, so measure the resulting workload and understand the supported query semantics before committing to it.
Field encryption threat model
Field-level encryption is defense in depth. It does not protect against:
- a compromised application that has the decryption key;
- a malicious authorized user;
- plaintext being logged before encryption;
- XSS or client-side data theft;
- business-layer authorization bugs.
Protect the keys, keep plaintext out of logs, secure clients, and enforce authorization separately. Encryption addresses a particular exposure path; it does not repair a compromised application or an incorrect access-control decision.
Before selecting field encryption, write down the threats it is meant to address and the clients that must decrypt the data. This makes the boundary testable: if a database administrator can run an ordinary query and see plaintext, at-rest encryption may be the relevant control; if the server itself must not see a field, client-side encryption is the stronger fit. Neither choice removes the need to protect the application and its keys.
Auditing
MongoDB Enterprise and Atlas can audit security, administrative, and data events depending on the product capability and configuration. Configure auditing around the events that matter to your threat model, rather than assuming that every useful business action will appear automatically.
Relevant audit categories can include:
authentication
user/role changes
privileged operations
selected data access
Audit logs can contain sensitive metadata, including identities, resource names, or details of access. Protect them, restrict who can read them, and retain them according to the organization's requirements.
Application audit
Business audit trails usually belong at the application level. Examples include:
who refunded order
who changed role
who exported data
A database audit record may show that an update occurred, but it cannot always infer the business action, user-facing reason, or request context. Store the actor, request, and reason when that information is needed for investigation or compliance.
Do not rely solely on generic database logs for business accountability.
Connection string security
A connection URI may contain a password. Never log it:
console.log(process.env.MONGODB_URI);
Redact credentials and other sensitive connection details in application logs, diagnostics, and error reports. Error messages can also disclose hostnames or deployment information, so review what crosses the logging boundary before sending it to a third-party system.
Secret rotation
Design the application so database credentials can rotate without a long outage. Common approaches include:
- overlapping old and new credentials;
- using managed IAM;
- restarting or reloading connections in a controlled way.
Do not keep one permanent password for years. Rotation only works operationally if the application can obtain the new secret, establish new connections, drain old connections, and recover cleanly when the old credential is revoked.
Test rotation before an incident requires it. A useful exercise is to introduce a second credential in a non-production environment, reload the service, verify new connections, and revoke the old credential. Check both long-lived processes and short-lived jobs; they often load secrets at different times.
Principle of separate environments
Development, test, and production should use separate:
- clusters or databases;
- credentials;
- networks.
Do not run tests against production. A test that deletes fixtures, exercises migrations, or sends deliberately malformed input should not have a path to live customer data.
Operator injection
An authentication query assembled from raw request objects can change meaning when the parser accepts MongoDB operators. For example, this is dangerous:
collection.findOne({
email: req.body.email,
password: req.body.password,
});
If the request parser allows email to be an object, a request such as this could alter query semantics in naive code:
{
"email": {
"$ne": null
}
}
Validate the schema at the boundary:
email must be string
Hash password verification separately. Do not construct an authentication query from raw objects. The exact validation library is less important than enforcing the expected runtime types before they become query operators.
$where
$where executes server-side JavaScript and has security and performance concerns. It is often disabled or inappropriate for ordinary application queries.
Do not expose user-controlled expressions to it. Use standard MongoDB operators and explicitly construct the small set of query shapes the application supports.
Regex injection
A user-provided search string can change regular-expression semantics. For example:
.*
matches broadly rather than behaving like a literal search term. Escape user input when a regular expression is genuinely required, or use search indexes designed for the search behavior. Limit input length as well, because even a valid pattern can create expensive work.
Tenant leakage
Tenant isolation should be part of the database query, not a check performed after an overly broad query has already returned data. Scope every query with the authenticated tenant:
{
tenantId: auth.tenantId,
_id: taskId
}
Do not query only by the task ID:
{
_id: taskId
}
and then check the tenant in JavaScript after returning the document. That approach increases exposure and makes it easier for a future code path to forget the check. Query scope reduces the data returned in the first place.
Unique indexes should also include the tenant field when uniqueness is meant to be per tenant. Otherwise, a globally unique index can incorrectly prevent two separate tenants from using the same value, or a schema may fail to express the intended isolation rule.
Backups are sensitive
A backup contains production data and must be treated as another production data store. Encrypt:
- storage;
- transfer;
- access.
Restrict who can restore or download backups. A backup leak can bypass live database controls, including the network allowlist and application authorization, so backup permissions and recovery tooling need their own review.
mongodump
Dump files may contain plaintext user data. Do not upload them to a public bucket.
Use supported encryption and storage controls, and check the resulting files and transfer path rather than assuming that the command itself protects the data. Cleanup and retention matter too: a forgotten local dump is still a copy of production information.
Security updates
MongoDB 8.3 patch releases in 2026 include security fixes. Use a supported patched release rather than pinning a deployment to only "8.3.0 forever."
Subscribe to security bulletins and plan a process for evaluating and applying updates. The Node.js driver and Mongoose are also part of the database stack and need updates; securing the server does not remove vulnerabilities in the client libraries.
Supply chain
The application database stack may include more than the official driver:
mongodb driver
Mongoose
plugins
monitoring agents
Review these dependencies, their permissions, and their maintenance status. Avoid abandoned Mongoose plugins with broad hooks, because code that runs around many database operations can expand both the attack surface and the difficulty of investigating behavior.
DoS/query cost
An authorized query can still exhaust database resources. Common expensive shapes include:
unindexed regex
huge sort
deep skip
massive aggregation
Apply:
- indexes;
- limits;
maxTimeMSwhere appropriate;- rate limits;
- a query allowlist;
- separate analytics.
The goal is not to reject useful work indiscriminately. It is to bound untrusted request-driven work, keep interactive traffic separate from expensive analytics, and fix the underlying query shape when timeouts reveal a missing index or an inefficient plan.
Availability is security. A service that is technically authorized but can consume all database capacity is still a security and reliability problem.
maxTimeMS
For untrusted or request-driven queries, a time limit can prevent one request from running without bound:
collection
.find(filter)
.maxTimeMS(2000)
The exact API form depends on the driver. Choose a value based on the workload and its legitimate latency requirements. A timeout can fail a valid slow query, so use it alongside indexes and query-shape fixes rather than using it to hide the root cause.
For debugging, inspect the query shape, its index use, the amount of data examined, and the timeout error. A timeout is evidence that the request exceeded a bound; it is not proof that the database is unhealthy. Compare the result with a representative indexed query and decide whether the endpoint needs a narrower filter, a pagination limit, or a separate workload.
Server-side scripting/map-reduce
Legacy features such as map-reduce have been superseded by aggregation in many cases. Avoid enabling powerful server-side scripting for user-controlled logic. The smaller and more explicit the set of operations exposed by the application, the easier it is to review resource use and security behavior.
Common mistakes
The recurring failure modes are:
- public database;
- admin credentials in the application;
- no TLS;
- bypassing invalid-certificate errors;
- connection strings in logs;
- no tenant scope;
- raw objects used as queries;
- unsecured backups;
- one credential across all environments or services;
- mistaking encryption at rest for field confidentiality;
- custom cryptography;
- no patching;
- no query-cost limits.
These mistakes usually come from treating one control as a complete security strategy. Review the layers together: network, transport, identity, database privileges, application authorization, data protection, auditability, and resource limits.
When reviewing a deployment, ask the same questions at each layer:
- Which clients can reach MongoDB?
- Can the client verify the server certificate?
- Which database user does the service present?
- Which operations can that user perform?
- Which tenant and ownership constraints does the application add?
- Which fields can an operator or backup reader see?
- Which security and business actions are recorded?
- What prevents one expensive request from consuming all capacity?
This review order also gives you a useful incident workflow. A connection failure may be caused by an allowlist, a TLS trust chain, or credentials, while a successful connection followed by a denied operation points toward database privileges. A successful database operation against the wrong tenant is an application authorization defect, not an authentication success that should be accepted. A slow request may be a query-shape or resource-boundary problem even when every identity check is correct.
Do not treat the checklist as a one-time setup task. Recheck it when a service is added, a network route changes, a credential rotates, a new sensitive field is introduced, or an operational tool gains production access. Security controls drift when the deployment evolves but the original assumptions are left undocumented.
For a production review, record the intended trust boundaries and the owner of each control. The service team may own request validation and tenant scoping; the platform team may own private connectivity and certificates; the security team may own key policy and audit retention. Clear ownership makes a missing control easier to detect and a failed control easier to investigate.
Exercises
- Design a least-privilege application database role.
- Threat-model Atlas network access.
- Configure TLS verification conceptually.
- Compare encryption at rest, CSFLE, and Queryable Encryption.
- Design database credential rotation.
- Add a tenant-scoped query.
- Fix NoSQL operator injection.
- Add a maximum query limit and timeout to a public search.
- Design a business audit event.
- Write a backup security checklist.
For each exercise, explain the boundary being protected, the failure mode the control addresses, and what you would inspect if the control did not behave as expected. The exercises progress from identifying controls to applying them to realistic application behavior.
For example, a tenant-scoped query exercise is not complete merely because tenantId appears in one code sample. The service should obtain that value from trusted authentication context, include it in the database filter, and test that a task belonging to another tenant is not returned. Similarly, a credential-rotation design should describe how old connections are drained and how failure is observed.
Useful checks for the exercises include:
- try the intended operation with the dedicated service identity;
- try an unrelated administrative operation and confirm it is denied;
- test a malformed type where a query value should be a string;
- test a task ID that belongs to a different tenant;
- inspect logs to confirm secrets and sensitive fields are redacted;
- run a deliberately expensive search and verify its limit or timeout;
- confirm that an audit event contains an actor, request context, and reason where required.
The point of these checks is to verify behavior at the boundary, not merely to confirm that a configuration screen contains a setting. A security control is useful when the expected unsafe action is denied, the safe action continues to work, and the result is observable enough to diagnose.
Mastery checklist
You should be able to explain:
- authentication;
- RBAC;
- least privilege;
- network and TLS controls;
- encryption at rest;
- CSFLE;
- Queryable Encryption;
- X.509, Kerberos, and LDAP awareness;
- auditing;
- connection-secret handling;
- tenant isolation and operator injection;
- patching and query DoS.
If you cannot distinguish authentication from authorization, or encryption at rest from field confidentiality, revisit those sections before applying the controls in production. The same distinctions are useful when debugging: identify whether the failure is at network reachability, TLS validation, database login, database privilege, application authorization, or query cost.
As a final self-check, explain why a private endpoint is not a substitute for RBAC, why a valid login is not proof of tenant access, and why an encrypted backup still requires access control. Then identify the first log, configuration, or query detail you would inspect for each failure. Those answers show that you can apply the controls rather than only name them.
Official references
Use the official documentation for deployment-specific configuration and version-sensitive behavior:
Check the documentation for the exact MongoDB version, deployment type, and driver version in use. Security settings and supported encrypted query behavior are areas where an otherwise reasonable example can become wrong when copied across versions.
Record those versions in the design review. Recheck version-specific guidance after upgrades. Treat security advisories as operational work, not optional reading.
