passfs stores selected files encrypted with
age and keeps them available at their original
paths through one local FUSE filesystem and symbolic links. Decrypted contents
stay in memory and every file open requires authorization by default.
- macOS
- Linux
- macOS 13 or later;
passfs setupguides the required macFUSE installation - Linux: a systemd user session; the installer configures FUSE automatically when supported by the distribution package manager
Download and open the signed and notarized installer:
The package installs PassFS.app in /Applications and the passfs command
in /usr/local/bin. The application is already signed by the passfs
developer; users do not need an Apple Developer certificate, a provisioning
profile, Go, or Git.
Before the first mount, run:
passfs setupIf macFUSE is missing, passfs opens its official download page and explains
how to finish setup. It never installs a system extension silently. Check the
result at any time with passfs doctor.
Installing a newer package also reloads an existing passfs service.
curl -fsSL https://getpassfs.com/passfs | bashThe installer selects the x64 or arm64 binary, verifies its SHA-256
checksum, installs it in ~/.local/bin, and installs fuse3 with the detected
package manager when needed. On a desktop it also installs a graphical
password dialog and update notifications when the distribution does not
provide them. System package installation may request sudo.
Set PASSFS_NO_INSTALL_FUSE=1 to require FUSE to be installed in advance.
Run once:
passfs initThis creates one age identity and one encrypted vault shared by every protected file on the computer:
~/.config/passfs/
├── config.json
├── mnt/
└── vault/
Start the filesystem:
passfs mountThe command returns after mounting at ~/.config/passfs/mnt. The filesystem
runs as a supervised background service, survives terminal closure, restarts
after a failure, and starts automatically after login. On macOS it is also
shown in Finder as the passfs volume.
Only one passfs filesystem is mounted for all protected files.
Given:
/Users/menxit/Development/project/.env
run:
passfs encrypt /Users/menxit/Development/project/.envpassfs asks for authorization, encrypts the file, and removes its plaintext
contents. The original pathname becomes a symbolic link:
/Users/menxit/Development/project/.env
-> ~/.config/passfs/mnt/Users/menxit/Development/project/.env
Applications keep using the original path:
fs.readFileSync("/Users/menxit/Development/project/.env", "utf8")Following the link opens the protected file through passfs and requests
authorization. No change is required in the application. The same command
works with any regular file, not only .env files:
passfs encrypt file.md config/settings.jsonLinux desktops show a password window. On a server or SSH terminal, passfs uses a full-screen terminal prompt associated with the process opening the file. Test the selected prompt without opening a protected file:
passfs doctor --test-promptRunning passfs encrypt FILE again is safe. If an older passfs version already
encrypted the file but removed its original pathname, the command recreates the
missing link without re-encrypting the data.
Deleting the symbolic link deletes its encrypted file shortly afterward. If the service is stopped, the deletion is applied at the next mount. Deleting a directory containing protected links has the same effect. Moving a protected link is treated as deleting its old pathname; moving protected links is not currently supported.
Do not replace a protected link with a regular file. Some editors implement atomic saves by replacing the pathname and can therefore bypass the link.
If a command reports an unavailable mount, recover it with:
passfs reloadTo convert one protected link back into a regular plaintext file while leaving every other file protected:
passfs unprotect /absolute/path/to/.envThe service is stopped briefly and restored automatically if it was active.
The command requires typing UNPROTECT, writes the plaintext atomically, and
permanently deletes that file's encrypted copy only after the write succeeds.
To convert every protected link back into a regular plaintext file:
passfs unprotectThe command displays a security warning and requires typing UNPROTECT. It
unmounts passfs, requests authorization once, writes each plaintext file
atomically, and then permanently deletes its encrypted copy. If a pathname has
changed or conflicts with another file, that ciphertext is preserved and the
problem is reported.
After a successful run, passfs remains initialized but is unmounted and automatic startup is disabled.
The default is:
passfs config --unlock-for 0Every open asks for Touch ID on macOS or the passphrase on Linux. To authorize each opened file for five minutes:
passfs config --unlock-for 5mThe cache is per file and exists only in the passfs process memory. Restart the service after changing this value:
passfs reloadChange the global passphrase with:
passfs passwdThis re-encrypts the single age identity; it does not need to re-encrypt every file.
passfs init attempts to enable Touch ID by default on macOS. A device-local
copy of the age identity is protected by the currently enrolled fingerprints.
The distributed application includes the Developer ID signature, provisioning
profile, and Keychain entitlements required by macOS.
On a Mac without Touch ID, initialization continues normally and reports that
passphrase authorization will be used instead. With --unlock-for 0, every
protected file open then asks for the passphrase.
When Touch ID is enabled, the default --unlock-for 0 requires it for every
file open. passfs edit FILE requires it once for the whole edit session.
Check or disable it with:
passfs touchid status
passfs touchid disable
passfs reloadChanging the fingerprints enrolled on the Mac invalidates the protected copy;
use passfs touchid -h to restore it with the passphrase. Touch ID does not
replace the backup described below: its copy is tied to this Mac and is not a
recovery key. Linux continues to use the passphrase.
passfs status
passfs reload
passfs unmount
passfs mountUse passfs reload after installing a new passfs version or changing its
configuration. It unmounts and starts the supervised filesystem again without
disabling automatic startup.
passfs unmount also disables automatic startup. Running passfs mount enables
it again.
The background service checks GitHub Pages at most once per day. macOS and Linux desktops receive a passive notification when a new release is available; terminal commands also report the cached update.
Check without installing:
passfs update --checkInstall the update:
passfs updateOn macOS, passfs verifies the package checksum, Developer ID Installer signature, and Gatekeeper assessment before opening the standard macOS Installer. On Linux, it verifies the checksum and embedded version, replaces the user-installed executable atomically, and reloads the service. Updates are never installed silently.
The source:
/Users/menxit/Development/project/.env
is stored as:
~/.config/passfs/vault/
├── .passfs/
│ ├── config.json
│ ├── identity.age
│ └── metadata.json
└── files/
└── Users/
└── menxit/
└── Development/
└── project/
└── .env.age
The absolute path is recreated only to organize encrypted files. passfs does not maintain a project registry and does not copy other project files.
The age private identity is stored at:
~/.config/passfs/vault/.passfs/identity.age
Copy it to a secure offline location:
cp ~/.config/passfs/vault/.passfs/identity.age /path/to/secure-backup/identity.ageidentity.age is encrypted with the passphrase chosen during passfs init.
Store that passphrase separately in a password manager. The device-local Touch
ID copy is not a substitute for this backup.
passfs does not write decrypted protected-file contents to its own backing storage, but it cannot hide plaintext from the application that opens a file. Plaintext exists in the passfs process memory and is delivered to the requesting process.
Applications may copy secrets into logs, caches, crash dumps, or other files.
The initial import removes the live plaintext pathname but cannot securely erase
previous SSD blocks, snapshots, or backups. Software running as the same OS user
may also inspect processes or access a file while it is authorized.
During a passfs edit session, this includes other processes running as the
same user that open the file being edited.
A process that can write to the protected file's parent directory can remove its
symbolic link and thereby delete the ciphertext. If it replaces the link with a
new entry, passfs preserves the ciphertext and refuses to overwrite that entry,
but it cannot prevent an unprotected plaintext file from occupying the original
pathname. Use passfs edit or software known to preserve symbolic links.
Use full-disk encryption, trusted applications, restricted permissions, and an appropriate backup policy as additional protections.
MIT. See LICENSE.md.
Development and release procedures are documented in docs/DEVELOPMENT.md and docs/RELEASING.md.
Machine-readable installation, usage, and safety guidance is available at getpassfs.com/llms.txt.