Infrastructure engineering for East Africa's operators, platforms and regulators See the work →
MongoDB Backup Encryption: Dumps and Logs Stay Readable
Cybersecurity 7 min read

MongoDB Backup Encryption: Dumps and Logs Stay Readable

MongoDB backup encryption, tested: under LUKS and under Percona's encryption at rest, every mongodump we took held all 5,000 ID numbers in plain text.

CE
CloudSpinx Engineering
Infrastructure Engineering, Virtualization, Networking, Automation
26 October 2026
mongodbmongodb backup encryptionmongodumpencryption at rest

Encryption at rest keeps a MongoDB server's data files and journal from anyone holding the disk without the key. It does nothing for the dump once it leaves the server, and in our lab nothing for the slow-query log either until redaction was switched on. We loaded 5,000 records with made-up national ID numbers into four MongoDB 8.0.34 servers in our lab: stock Community, Community on a LUKS volume, Percona Server for MongoDB with its encryption key, and Percona with log redaction on top. Every mongodump, from all four, held all 5,000 IDs in plain text. The dump from the encrypted Percona server restored into a stock Community server that had never seen the key.

So MongoDB backup encryption is a separate job, and the log is a third. CloudSpinx sets up and runs MongoDB for businesses in Kenya that hold personal data under the Data Protection Act, and this is what that run says about which copies a key actually covers: the data files, the journal, the slow-query log, the dump, a copy of the files started on another server, and the raw disk.

Which copies stayed readable

All four took the same data and the same queries. The build, where encryption sat and, on the fourth, log redaction were the only differences. To count leaks we searched the data files, journal, diagnostic data, log and dump for the 5,000 random parts of the IDs, after a minute's wait so WiredTiger had written a checkpoint. Compression hides some IDs from a plain text search, which is why the unencrypted data files show 4,706 and not 5,000. Somebody holding a copy does not search it. They start mongod on it and read everything.

Which copies of MongoDB data stayed readable under encryption at rest
Which copies of MongoDB data stayed readable under encryption at restA grid of six copies of the same 5,000 records against four MongoDB 8.0.34 setups: stock Community on a plain disk, Community on a LUKS volume read through the mounted filesystem, Percona Server for MongoDB with its engine encryption key, and Percona with log redaction added. Engine encryption left no ID in the data files or the journal, LUKS left none in the raw container, and only redaction cleared the 70 IDs from the slow-query log. Every mongodump archive held all 5,000 IDs, and files copied off the mounted LUKS volume opened on stock Community with no key.COMMUNITYplain diskCOMMUNITYon LUKS, via mountPERCONAengine key filePERCONAkey + redactionWHAT THE ENGINE WRITESData files (.wt)IDs found, of 5,0004,7064,70200JournalIDs found95695300OUTSIDE THE STORAGE ENGINEmongod.logIDs logged, slowms 07070700mongodump archiveIDs found5,0005,0005,0005,000A COPY OF THE FILES, OR THE DISKCopy started elsewherestock mongod, no keynot run5,000 docsrefusednot runRaw LUKS container2 GiB, read as bytesno LUKS0no LUKSno LUKS
  • readable
  • no ID found, or refused
Three setups kept the IDs out of something, and none of the four kept them out of the dump: all 5,000 came out readable each time.

The counts come from a text search, which compression partly defeats, so 4,706 is a floor. Nobody who holds a copy needs the search: started under mongod with no key, the LUKS copy opened with all 5,000 documents.

The dump row is red in every column because mongodump reads documents through the running server, after decryption, and writes them out as BSON. The log row stays red under Percona's encryption too. Its 70 IDs are the 50 we queried and the 20 we updated, each written out in a "Slow query" line, and only redaction cleared them. The diagnostic.data directory held none of the IDs on any server.

Is mongodump encrypted?

No. mongodump 100.19.1 has no option for it, and the word does not appear in its help text. Whatever protects the data files, the dump that lands on the backup share is plain BSON that anyone can restore with free tools, and we restored the encrypted server's archive into stock Community to prove it.

Encrypt the stream before it touches a disk, to a public key, so the machine that writes and stores the backups cannot read them:

# once, on a machine that is neither the database host nor the backup host
age-keygen -o backup-key.txt
age-keygen -y backup-key.txt > recipient.txt   # only this file goes to the database host

# the backup job, on the database host
mongodump --archive | age -R /etc/mongo-backup/recipient.txt > /backup/app.archive.age

# the restore test, wherever the private key is brought for it
age -d -i backup-key.txt /backup/app.archive.age | mongorestore --archive

In a second run on another machine, with 5,000 records of the same shape, the encrypted archive came out at 496,303 bytes with no ID anywhere in it, and decrypting it straight into mongorestore put back 5,000 of 5,000 documents. The private key is now the backup. Keep two offline copies with two named people and restore from it every month, because an encrypted dump nobody can open is a deletion.

If you moved off Atlas onto your own replica set, the backup job is yours now, and this is the first thing to check in it.

Not sure where your dumps land or who can read that share? Send the job through the database scoping form and we will tell you.

A key left in a door lock with spare keys hanging from its ring, the way a key file on the database server sits beside the data it opens

The slow-query log is the copy nobody counts

MongoDB's manual says so in one sentence: "A mongod running with logging may output potentially sensitive information to log files as a part of normal operations, depending on the configured log verbosity." The lab run logged every query, so we put the threshold back to its default of 100 ms and sent one deliberately slow query to the encrypted Percona server. It took 172 ms, and the line carried "filter":{"phone":"254700000000",...} in full next to "planSummary":"COLLSCAN". A query that crosses the threshold is logged the same way, values included.

Stock Community cannot hide them. MongoDB marks the redaction setting "Available in MongoDB Enterprise only", and Community's mongod rejects --redactClientLogData as an "unrecognised option", the same answer it gives --enableEncryption. Percona's build accepts it, and on our fourth server the same kind of line read "filter":{"national_id":"###"}. Percona's log redaction page names two gaps: debug messages are not redacted, and with the profiler on, the query still lands in system.profile unredacted. That collection sits in the database's own data files, which Percona encrypts with that database's key. We did not switch the profiler on to check.

On Community, the slow-operation threshold and sample rate decide how many queries reach the log, and after that the controls are where it is written and who can read it. Ours sat on the root disk, outside the LUKS volume. Move it onto the encrypted volume, readable by the mongod user and root only, and it at least leaves with the disk encrypted.

LUKS or Percona: what each key stops

LUKS encrypts the block device. The raw 2 GiB container held none of the 5,000 IDs, which is what a pulled disk, a returned drive or a block-level image of the encrypted device gives away. Through the mounted filesystem the same files are as plain as the unencrypted server's, because that is how any root process or file-level backup agent on the running machine reads them. We copied the data directory off the LUKS volume, started stock Community on the copy with no key, and counted 5,000 documents.

Percona encrypts inside the storage engine, so the files stay ciphertext wherever they travel. A copy of its data directory would not start under stock Community, or under Percona without the key; both stopped with WiredTiger's "unable to read root page" error, which lists encrypted files first among its possible causes. With the key it came up with all 5,000. The catch is where the key lives. Ours was a key file on the same server, and a root user who can copy the data directory can copy the key file too. Percona's encryption page lists "Integration with an external key server (recommended)", meaning HashiCorp Vault, OpenBao or KMIP.

So pick by the copy that worries you. Disks leaving the building: LUKS, on any edition, at no license cost. Data directories copied around by file-level backups or sync jobs: Percona's engine encryption with the key on a key server. Neither encrypts the dump or the log as they are written. Percona's key never reaches either, and LUKS covers them only if they sit on its volume, and then only against a disk leaving. MongoDB Enterprise's own encrypted engine is the third route, and the license question that comes with it is on our managed database page.

A 3.5-inch hard disk turned over to show its circuit board: a pulled or retired disk is the copy LUKS protects

What the Data Protection Act does with it

Section 43(6) of Kenya's Data Protection Act is where encryption earns money. After a breach that carries a real risk of harm, the controller must tell the affected people in writing, unless it "has implemented appropriate security safeguards which may include encryption of affected personal data". That waiver covers the letter to data subjects and nothing else.

The 72-hour notice to the Data Commissioner under section 43(1)(a) stands either way, as does the processor's duty to tell the controller without delay, within 48 hours where reasonably practicable, the two clocks we set side by side in what a managed IT contract must cover.

On our reading, "affected personal data" means the copy that leaked, so a dump lifted off a backup share is affected personal data in plain text, whatever the server it came from was running. Section 41(4)(c) lists "pseudonymisation and encryption" among the measures to consider, and the copies that travel are where it is missing.

Fix them in this order

  1. The dump: encrypt the stream to a public key as above, and prove a restore from it every month.
  2. The log: --redactClientLogData on Percona; on Community, the log on the encrypted volume and closed to everyone but root and mongod.
  3. The files: LUKS where the worry is a disk leaving, Percona's engine encryption with Vault, OpenBao or KMIP where the worry is the files themselves being copied.

One server whose dumps go to a disk only you can reach does not need us. The commands above and a monthly restore cover it, and where the data may physically sit is a separate rule, set out in where your servers can legally live.

Replica sets with dumps going offsite, snapshot jobs on the VM, and reporting users reading production are where copies multiply. Send us the mongod.conf from one member, the backup job and where it writes, where the logs go, and anything else that copies the data directory, through the scoping form or on WhatsApp at +254 713 403 044. You get back every copy of the data marked encrypted or readable, who can read it, and the change for each. If we end up running it, the database can sit on a server in Nairobi that we hand over in about 24 hours, with encrypted dumps and the monthly restore test inside one monthly figure. The answer costs nothing and you owe us nothing for it.

WhatsApp