Choose an encryption layer from a threat model, not from the vague requirement “encrypt the database.”

Threat Models: Disk Theft, Cloud Admin, Database Admin, Application Compromise, and Log Leakage

AtlasMart stores customer contact data, payment references, operational logs, and backups. Different attackers see different surfaces, so one encryption feature cannot protect every path.

Advanced120–200 minutesThreat-boundary labMongoDB 8.3.8 · mongosh 2.10.0 · PyMongo 4.17.0Last reviewed: September 2026

Learning objectives

01

Build a threat model that distinguishes disk theft, cloud/provider access, database administration, application compromise, and log/backup leakage.

02

Map transport TLS, storage encryption, CSFLE, and Queryable Encryption to what each layer does and does not protect.

03

Trace where plaintext can still exist: trusted application memory, logs, crash dumps, analytics exports, search indexes, and key-management paths.

04

Distinguish ciphertext confidentiality from authorization, integrity, availability, and recoverability.

05

Choose the minimum encryption layer that protects a stated threat without inventing guarantees it cannot provide.

Reproducible lab baseline

This lesson pins MongoDB Community Server 8.3.8 with mongodb/mongodb-community-server:8.3.8-ubuntu2204-slim, mongosh 2.10.0, and PyMongo 4.17.0 where driver behavior is used. Topology: one disposable Community standalone named atlasmart-ch23-l1. The lab does not claim native storage encryption; it uses Community specifically so the edition boundary is visible. Host publication is loopback-only on port 27181. Authentication/TLS state is stated next to the experiment. Default read/write concern and primary read preference are used unless noted. FCV is observed and never changed. The local KMS examples generate disposable 96-byte master keys at runtime and never embed a real cloud/KMIP credential. Atlas, Enterprise Advanced, AWS KMS, Azure Key Vault, GCP KMS, KMIP, and HSMs are optional production paths. Product runtime labs were not executed in the generation environment; ciphertext values, key identifiers, timings, storage amplification, and recovery results must be measured locally rather than copied as invented output.

1. Start with the attacker, not the checkbox

“Encrypt the database” is not a threat model. A stolen disk, a cloud administrator, a MongoDB database administrator, a compromised application process, and a verbose application logger observe different boundaries. Encryption only helps when the attacker is outside the boundary that owns the decryption key.

Threat What the attacker can see Layer that can help What remains exposed
stolen data disk / snapshot WiredTiger files, journal, backups Enterprise/Atlas at-rest encryption or encrypted storage a live authorized database process can still decrypt
cloud/storage operator provider disks/snapshots Atlas/provider encryption; customer-managed keys can change key custody application/server plaintext after decryption
database administrator server queries, memory-visible values CSFLE / Queryable Encryption with keys outside server trust authorized application plaintext and side channels
compromised application decryption keys and plaintext in process encryption alone is insufficient requires app isolation, IAM, secret controls, least privilege
logs/exports/backups values copied outside primary collection client-side encryption can keep protected fields ciphertext; redaction also required unprotected fields and keys can still leak

2. Encryption layers protect different boundaries

TLS protects data in transit between endpoints. At-rest encryption protects storage media after the database process has obtained its storage key. Client-Side Field Level Encryption (CSFLE) encrypts selected BSON values in the client before they reach MongoDB. Queryable Encryption (QE) is also client-side but adds server-maintained encrypted metadata so supported queries can operate without revealing the plaintext field to the server. None of these replaces authentication, authorization, backup, or key recovery.

Layer Plaintext at MongoDB server? Queryable? Typical key owner
TLS only Yes, after transport termination normal database queries server/client TLS identities
Enterprise/Atlas at rest Yes, while server is running normal database queries storage/KMS boundary
CSFLE random No for encrypted field no equality query on plaintext semantics application/client KMS
CSFLE deterministic No for encrypted field equality by encrypting the query value; leaks equality patterns application/client KMS
Queryable Encryption No for encrypted field configured equality/range; preview string patterns are separate application/client KMS

3. Make the edition boundary observable

The Community image should identify itself as Community. That evidence is important because native WiredTiger encryption at rest is an Enterprise capability outside Atlas. The lab does not “simulate Enterprise by renaming a flag”; it records the actual edition, then uses the later CSFLE/QE labs for Community-compatible client-side encryption.

start the Community boundary lab and inspect build information
docker rm -f atlasmart-ch23-l1 2>/dev/null || truedocker volume rm atlasmart-ch23-l1-db 2>/dev/null || truedocker run -d --name atlasmart-ch23-l1 \  -p 127.0.0.1:27181:27017 \  -v atlasmart-ch23-l1-db:/data/db \  mongodb/mongodb-community-server:8.3.8-ubuntu2204-slim \  --bind_ip_all --port 27017until mongosh "mongodb://127.0.0.1:27181/admin" --quiet --eval 'db.runCommand({ping:1}).ok' 2>/dev/null | grep -q 1; do sleep 1; donemongosh "mongodb://127.0.0.1:27181/admin" --quiet --eval '  printjson(db.adminCommand({buildInfo:1}));  printjson(db.adminCommand({getParameter:1,featureCompatibilityVersion:1}));' mongosh "mongodb://127.0.0.1:27181/atlasmart" --quiet --eval '  db.customers.insertOne({customerId:"C-2301",email:"alice@example.test",supportNote:"refund requested"});  printjson(db.customers.findOne({customerId:"C-2301"}));  const b=db.adminCommand({buildInfo:1});  printjson({version:b.version,modules:b.modules,allocator:b.allocator});' 
What this proves

The server can read plaintext because no client-side encryption was configured. An empty/non-enterprise module list on the pinned Community image supports the edition check; it does not prove how a separately licensed Enterprise deployment or Atlas cluster is configured.

4. The deliberately wrong design: put keys beside ciphertext

If the application repository contains the local master key, database URI, and an encrypted data export together, one repository leak can collapse the intended trust separation. Likewise, encrypting a field but logging the original request body creates a plaintext copy outside the encrypted collection. The repair is to separate key custody from data custody and to inventory every secondary data path.

deterministic boundary inventory — no cryptography is faked
from dataclasses import dataclass@dataclassclass Surface:    name: str    plaintext: bool    key_present: boolsurfaces = [    Surface("mongodb data file", False, False),   # only true after CSFLE/QE    Surface("application memory", True, True),    Surface("request log", True, False),    Surface("key service", False, True),    Surface("analytics export", True, False),]for s in surfaces:    print(f"{s.name:20} plaintext={s.plaintext} key_present={s.key_present}")# The lab is an inventory aid, not an encryption implementation.

5. Production judgment

Choose encryption from an explicit attacker model. If disk theft is the threat, storage encryption and key custody matter. If the database administrator must not see a field, storage encryption is insufficient and client-side encryption is relevant. If the trusted application is compromised, a field key loaded into that process is no longer a boundary. Treat logs, caches, search/vector systems, backups, observability payloads, and data-science extracts as separate copies that need their own controls. The next lesson focuses specifically on the storage-key boundary and why Community, Enterprise, and Atlas must not be conflated.

Check your understanding

  1. Why does storage encryption not hide data from an authorized database administrator?
  2. What new trust boundary does CSFLE create?
  3. Does Queryable Encryption protect against a compromised application that can access the keys?
  4. Why is logging part of the encryption threat model?
  5. What does ciphertext confidentiality not guarantee?
Review the answers

1. Because the running database process obtains the storage key and presents plaintext to authorized queries.

2. The application/client and its KMS hold the key; MongoDB stores the encrypted BSON value without the plaintext key.

3. No. If the application can decrypt legitimately, compromise of that application can usually reach plaintext and keys.

4. A log can become an independent plaintext copy even if the primary database field is encrypted.

5. It does not itself guarantee authorization, integrity, availability, correct query semantics, or recoverability.

Authoritative references

Version-, edition-, driver-, topology-, and preview-sensitive encryption behavior was checked against current MongoDB documentation at generation time. Re-check these sources before applying the procedure to a later release.

Keep knowledge open

Help the academy stay free and grow.

If these tutorials save you time, a small donation supports new lessons, technical review, diagrams, examples, and long-term maintenance.

ETHEthereum / ERC-20 only
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0

Send only Ethereum or ERC-20 compatible assets to this address.