/ 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 (see below), in which case the path is derived from the vault name.

Examples

# Linux / macOS
mkdir /tmp/v
luksbox mount my.lbx /tmp/v        # daemonizes by default

# Windows (drive letter)
luksbox mount my.lbx Z:

# Foreground (debugging)
luksbox mount my.lbx /tmp/v --no-daemonize

# 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

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

luksbox umount /tmp/v             # POSIX
luksbox umount Z:                 # Windows
# or system tools:
fusermount -u /tmp/v              # Linux
diskutil unmount /tmp/v           # macOS

Platform notes

Linux

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

macOS

Requires macFUSE (the kernel-extension flavour). Same fuser crate as Linux. Mount permissions follow the calling user.

Apple Silicon caveat: 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 / open / 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.

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. 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.

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