Backup strategy
What to back up, what NOT to back up, and how often.
What to back up
| Item | Frequency | Why |
|---|---|---|
<vault>.lbx |
Whenever contents change | The actual encrypted data |
<vault>.lbx.hdr (if detached) |
Once per keyslot change | Required to unlock |
<vault>.lbx.hybrid (if hybrid-PQ) |
Once per keyslot change | Sidecar with ML-KEM data |
<vault>.lbx.anchor |
Whenever vault is modified | Rollback-detection metadata |
.kyber seed file (if hybrid-PQ) |
At creation, then never modified | Required to derive PQ shared secret |
header-backup file |
After every keyslot change | Repairs a damaged header. An older one brings back the keyslots it had, see below |
<vault>.lbx.meta-bak, <vault>.lbx.header-bak |
Together with the .lbx (optional) |
Crash-recovery copies, see below |
Moving or copying a vault
A vault is more than its .lbx file. LUKSbox finds these files by
name next to it:
| File | Needed to open? | What it is |
|---|---|---|
vault.lbx |
Yes | The vault |
vault.lbx.hybrid |
Yes, for hybrid-PQ keyslots | ML-KEM data; without it those keyslots cannot unlock |
vault.lbx.meta-bak |
No | Crash-recovery copy of the encrypted file tree, the size of the metadata region (about 64 MiB by default) |
vault.lbx.header-bak |
No | Crash-recovery copy of the 8 KiB header. With a detached header it sits next to the header file instead (<header file>.header-bak) |
The detached header (--header), the rollback anchor (--anchor) and
the .kyber seed file are passed explicitly, so they can live anywhere.
The two .bak files are a safety net, not part of the vault. LUKSbox
reads them only when the copy inside vault.lbx is damaged, for
example by a power cut or an unplugged drive in the middle of a save,
and then opens the vault from its last good state. A vault.lbx
without them opens normally: LUKSbox writes a new .meta-bak at its
next save and a new .header-bak the next time the header changes
(adding or removing a keyslot, for example). Until then the copy has
no crash protection.
When you move or copy a vault:
- Close it first. Unmount it (
luksbox umount <mountpoint>, for exampleluksbox umount Z:on Windows, or the GUI's Unmount) and use the GUI's Lock + close. A mounted vault saves its changes every 30 seconds, so a copy taken while it is open can miss recent changes or catch a save halfway. - Copy the vault and its files together:
vault.lbx, its.hybridfile if it has one, and both.bakfiles, so the copy keeps its crash protection. - Rename them together. If you rename
vault.lbxtowork.lbx, renamevault.lbx.hybrid,vault.lbx.meta-bakandvault.lbx.header-baktowork.lbx.hybrid,work.lbx.meta-bakandwork.lbx.header-bak. A.hybridfile left under the old name leaves the hybrid-PQ keyslots unable to unlock. - Don't leave old
.bakfiles behind. If you copy a newervault.lbxover an older one, copy its.bakfiles too, or delete the old ones. A stale.bakis used only if the newvault.lbxis damaged, but it could then bring back the older state.
Deniable vaults have no .bak files: files with
predictable names and sizes next to the vault would give it away.
What NOT to back up to the same place
The fundamental rule: don't co-locate everything an attacker would need to brute-force the vault.
| Don't put together with the .lbx | Why |
|---|---|
| Your passphrase written down | Defeats the entire vault |
The .kyber seed file |
Defeats the PQ layer (becomes a passphrase-only vault to an attacker) |
| Your FIDO2 device | A device + a vault file gets the attacker past the second factor |
| The detached header | Defeats the "vault file is opaque" property of --header |
The point of --header, .kyber, and FIDO2 is that compromise of
ONE storage location doesn't compromise the vault. Backing up
everything to one S3 bucket undoes that.
Recommended setups
Personal vault (one user, one machine)
vault.lbxlives wherever you use itvault.lbx.anchoron separate storage (a USB stick you carry), passed with--anchorso every change updates it- Backup of
vault.lbxto a different drive / cloud (encrypted at rest by you, not by the cloud provider) - Passphrase memorised + written on paper in a safe place (separate from the vault file itself)
- FIDO2 device on your keychain; backup FIDO2 device in a safe deposit box
High-value vault (financial, legal, archival)
- Detached header (
--header)- Vault file: any storage (the file is opaque without the header)
- Header file: USB stick + cloud-encrypted backup
- Hybrid-PQ keyslot
.kyberseed: a SECOND USB stick, kept somewhere different
- Two FIDO2 devices enrolled (primary + safe-deposit backup)
- Backup passphrase, written on paper, in a third safe location
Team vault (multiple people, shared)
- Each team member enrolls their own FIDO2 keyslot
- One emergency-passphrase slot, custodian-held + sealed envelope
- Detached header on a TPM-protected file share
- Anchor + sidecars in the same place as the .lbx
- Document the recovery procedure where the team can find it (NOT in the vault!)
Restoring from backup
# Copy all the pieces back into place
cp /backups/vault.lbx ~/secure/
cp /usb-key/vault.lbx.hdr ~/secure/ # if detached
cp /backups/vault.lbx.anchor ~/secure/ # rollback metadata
cp /usb-key/vault.lbx.hybrid ~/secure/ # if hybrid-PQ
cp /backups/vault.lbx.meta-bak /backups/vault.lbx.header-bak ~/secure/
# crash-recovery copies, if backed up
# .kyber stays on its separate trusted storage; reference at unlock
# Verify it opens
luksbox ls ~/secure/vault.lbx --header ~/secure/vault.lbx.hdr \
--pq-hybrid /usb-key-2/vault.kyber
Older backups and the anchor
Restoring a backup puts the vault back to an older state, which is
exactly what the rollback anchor is there to catch. When you open a
vault with --anchor:
- An older copy of the vault is refused (
ROLLBACK DETECTED): the anchor has seen newer contents. Since 0.6.0 every save advances the vault's generation, so this also catches a copy taken before files were deleted or renamed. If you restored the copy on purpose, restore the anchor from the same backup, as above. - An older copy of the header is refused on header format v3
vaults (
header rollback detected). The header holds the keyslots: a header saved before arevokewould bring the revoked credential back. Every keyslot change (enroll, revoke, update, rotate-mvk) gives the header a new generation number, which the anchor records when the command runs with--anchor.
To put a header backup back on purpose, use
luksbox header-restore (add --anchor
so the anchor records it). It checks that the backup was sealed under
the vault's current master key, then saves it as a new header
generation, so the anchor accepts it. A header backup holds the
keyslots as they were when you took it: take a new one after every
keyslot change.
Header format v3 is the default for vaults created with LUKSbox
0.6.0+, and those vaults need 0.6.0+ to open. A vault on header format
v2 (created by an older version, or with create --header-v2) has no
header generation: an older header put back over it goes unnoticed,
even with an anchor. luksbox upgrade-header
moves it to v3. This is one-way (LUKSbox before 0.6.0 can no longer
open the vault); pass the vault's --anchor so the anchor starts
recording the header right away.
Things to test BEFORE you need them
Twice a year, do a recovery dry run:
- Restore from your backup to a scratch directory
- Unlock using your backup passphrase (NOT your daily one)
- Read a known file via
luksbox get - Compare bytes against the original
If this fails, the time to find out is during a calm Sunday afternoon, not at 2 AM during an actual incident.