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.
- Linux / macOS: an existing, empty directory.
- Windows: a free drive letter (
Z:) or a path that does not exist yet. An existing folder fails withSTATUS_OBJECT_NAME_COLLISION.
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).
-
Linux and macOS: the process daemonizes. With FUSE-T on macOS this works since 0.6.0: before,
mountstayed in the foreground and held a script's output open until unmount; now it returns once the mount is live, and a mount that fails returns a non-zero exit code. -
Windows (0.6.1+): a WinFsp mount lives only as long as the process holding it, so LUKSbox unlocks the vault in your terminal (passphrase, FIDO2 and TPM prompts as usual), then hands the vault key over a private pipe to a hidden
luksboxprocess that holds the mount:> luksbox mount my.lbx Z: passphrase: mounted C:\vaults\my.lbx at Z: (background, pid 4242) unmount: luksbox umount Z:Your passphrase never reaches that process, and it gets none of the
LUKSBOX_*secret variables (LUKSBOX_PASSPHRASEand the like). It has no window: closing the terminal or pressing Ctrl-C there leaves the drive mounted (unless the terminal runs inside a Windows job object that does not let processes leave it: the mount then ends with that job). It checks the--anchoragain when it opens the vault, keeps it current, and honours--syncand--shrink-on-close.
-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:
- FUSE-T (kext-free,
brew install --cask fuse-t): serves the vault to macOS over a local NFS connection. Copies into the mount are faster in 0.6.1: the mount asks for a 1 MiB NFS read/write size (it was 32 KiB), so a large copy triggers far fewer durable saves, and closing a file no longer forces a metadata save of its own (it waits for the 30-second timer or the unmount, as on Linux).fsync, or a--syncmount, is still durable. The macOS NFS client still asks for a durable save when it closes each file, so each small file you copy in still costs one save. - macFUSE (kernel extension): same
fusercrate as Linux. Mount permissions follow the calling user.
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.