/ Documentation / CLI reference / luksbox mount

luksbox mount

Mount a vault as a real drive (FUSE / WinFsp).

luksbox mount [OPTIONS] <PATH> [MOUNTPOINT]

Unlocks the vault and mounts it. The mountpoint becomes a normal filesystem from the OS's perspective: ls, cp, vim, your file manager - everything works.

<MOUNTPOINT> is required unless you pass --private-mount (macOS only, see below), in which case the path is derived from the vault name.

There is no separate open command: mount (or any command that reads the vault, such as ls) unlocks it. Pick the unlock method with --fido2, --tpm2, --tpm2-fido2 or --sep; without one, LUKSbox prompts for the passphrase.

Examples

# Linux / macOS
mkdir /tmp/v
luksbox mount my.lbx /tmp/v        # runs in the background

# Windows (drive letter); also runs in the background (0.6.1+)
luksbox mount my.lbx Z:

# Unlock with a FIDO2 key instead of the passphrase
luksbox mount my.lbx Z: --fido2

# Stay in the foreground (debugging); Ctrl-C unmounts
luksbox mount my.lbx /tmp/v --foreground     # or -f

# macOS + FUSE-T: mount inside ~/Library so other users can't see
# the mount name in `ls /Volumes` (see "Private mount" below)
luksbox mount my.lbx --private-mount

Background and foreground

By default mount unlocks the vault, waits until the drive is live, and gives you the prompt back. Unmount with luksbox umount (see Unmount).

-f / --foreground keeps the mount attached to the terminal, as mount behaved on Windows before 0.6.1: Ctrl-C in that window (or luksbox umount from another one) flushes and unmounts. deniable-mount takes the same flag and runs in the background the same way.

Private mount (macOS + FUSE-T)

On macOS with the kext-free FUSE-T backend, the default mountpoint under /Volumes/<name> is visible to every local user via ls /Volumes, the directory permissions block them from reading the data (mode 0700, owner = the mounting user), but the name itself leaks. On a shared Mac (multiple user accounts) this can be a metadata-disclosure concern.

--private-mount derives a per-user mountpoint under ~/Library/LUKSbox/Mounts/<vault-name> instead. ~/Library is mode 0700 by default on macOS, so the mountpoint path is unreachable from another account. Trade-off: the mount will NOT appear in Finder's Locations sidebar (you open it via the GUI's "Open mountpoint" button, or Finder > Go > Go to Folder).

# Derive ~/Library/LUKSbox/Mounts/my and mount there
luksbox mount my.lbx --private-mount

# Combined with --private-mount, an explicit <MOUNTPOINT> is an
# error (the flag exists precisely to skip picking one):
luksbox mount my.lbx --private-mount /some/path    # rejected

--private-mount only takes effect on macOS. On Linux and Windows it returns an error: Linux libfuse3 enforces mode 0700 at the mount root and there is no NFS-loopback exposure, so the metadata leak does not apply; Windows mounts under a drive letter, so there is no shared parent directory either.

Unmount

umount takes only the mountpoint: no vault file, no unlock flags.

luksbox umount /tmp/v             # Linux / macOS
luksbox umount Z:                 # Windows (LUKSbox 0.6.1+)
# or system tools:
fusermount -u /tmp/v              # Linux
diskutil unmount /tmp/v           # macOS

On Windows (0.6.1+), luksbox umount Z: works from any window of the same Windows session, for a background mount and for a --foreground one (where Ctrl-C in its window does the same). It waits until the vault has been flushed and closed, so once it returns you can run another luksbox command on the vault or unplug the drive that holds it. If it reports that the mount has not finished after 120 s, the vault is still being flushed: leave the drive plugged in until no luksbox process is left.

A mount started by LUKSbox before 0.6.1, or in another Windows session, cannot be reached this way (no luksbox mount at Z: found): press Ctrl-C in the window running luksbox mount.

Giving back free space when the mount ends

--shrink-on-close (0.6.1+) gives the free space at the end of the vault file back to the disk when the mount ends, as luksbox size --shrink does. Ignored for deniable vaults.

luksbox mount vault.lbx /tmp/v --shrink-on-close

Platform notes

Linux

Uses libfuse3 via the fuser crate. The mount appears in /proc/mounts as fuse.luksbox.

macOS

macOS builds use one of two FUSE backends; luksbox --version prints which one yours needs:

Apple Silicon caveat (macFUSE): macFUSE installs a third-party kernel extension. On M-series Macs, Apple's default Full Security boot policy refuses to load any non-Apple kext. You have to opt in once via Recovery Mode -> Startup Security Utility -> Reduced Security -> "Allow user management of kernel extensions from identified developers", then approve macFUSE specifically in System Settings -> Privacy & Security. The full walkthrough is on the macOS install page. Without this setup luksbox mount fails with a permission error because the kext never loaded - but every other LUKSbox feature (create / ls / get / put / GUI extract) keeps working.

Windows

Uses WinFsp - a FUSE-equivalent driver that registers the vault as a real Windows volume. Drive letters work; UNC paths work; Explorer shows it as a drive with a custom icon. Since 0.6.1 the mount runs in a hidden background process (see Background and foreground); -f keeps it in the terminal. Either way, luksbox umount Z: ends it (see Unmount).

Flush policy: --sync (eager) vs default (deferred)

Since v0.2.2, mounted vaults defer metadata flushes by default. Ops that mutate the tree (create, mkdir, unlink, rmdir, rename, setattr, symlink, link, FUSE flush / release, WinFsp Cleanup) mark the in-memory tree dirty and return immediately; a per-mount luksbox-flush-timer thread persists changes every 30 seconds when dirty. Explicit fsync(2) / fsyncdir(2) syscalls still flush eagerly (POSIX-required), and a final flush always runs on unmount.

Default (recommended for almost everyone): deferred. On a 10k-file vault, a single rm of one small file used to take 3+ minutes pre-v0.2.2 because every metadata op rewrote the entire 64 MiB metadata mirror. With deferred flush, rm returns in milliseconds and cp -r 10k_files /mnt/vault completes in seconds. Durability profile matches ext4 / btrfs / xfs commit intervals: a host crash without an explicit fsync can lose up to 30 seconds of metadata changes.

Eager: --sync. Every metadata-mutating op drives an immediate flush before returning, restoring pre-v0.2.2 per-op durability semantics. Cost scales with total file count, so on large vaults this can make basic operations dramatically slower (see the 3-minute rm above). Recommended only for small vaults or specific workflows where every operation must be crash-durable on return.

# Default: deferred, fast
luksbox mount my.lbx /tmp/v

# Eager: every metadata op flushes before returning
luksbox mount my.lbx /tmp/v --sync

Platform coverage: deferred flush ships on every backend in v0.2.2: Linux libfuse3, macOS macFUSE, macOS FUSE-T, and Windows WinFsp all host their own timer thread and honour --sync identically. On Windows, since 0.6.0, --sync also saves file and directory creation, overwrites, resizes and timestamp changes right away, and the 30-second timer keeps running to catch writes Windows delivers after a file is closed. On FUSE-T, closing a file waits for the timer since 0.6.1 (see macOS). The wizard exposes the same toggle as an "Eager flush?" prompt before mounting, and the GUI shows it as an "Eager flush (--sync)" checkbox next to the Mount-as-volume button. Default is off (deferred) in all three.

The chunk-data area itself retains the v0.2.2 durability fence: chunk-list blocks are durable on disk before the metadata mirror commits, so the post-flush state is always crash-consistent regardless of which flush mode you pick.

Performance

Steady-state I/O matches local-disk speed for small files; large sequential I/O is bounded by per-chunk AEAD throughput (250 MB/s write, 590 MB/s read on a Ryzen 9 with AES-NI). Use --cipher chacha if you're on a CPU without hardware AES. Since 0.6.1 every metadata save is about 2.5 times faster, on every backend.

For the full bench numbers, see docs/PROJECT_OVERVIEW.md Section 5.3 in the source repository.