FreeBSD Β· FIDO2 Β· OpenZFS Β· Python

eZFS2FA+

Hardened encrypted ZFS datasets with FIDO2 hardware-token two-factor authentication β€” FreeBSD-first, Linux-compatible, zero lock-in.

FreeBSD
Primary Platform
FIDO2
Auth Method
mdmfs -M
Transient Key Storage
MIT
License
0
Lock-in
By Billie Badin Β· SIGORYX Engineering Commentary: Vivian Voss GitHub Repository β†— v1.0.0 Β· May 2026

What is eZFS2FA+?

eZFS2FA+ is a hardened FreeBSD-first interactive workflow for wrapping encrypted OpenZFS dataset keys with FIDO2-backed two-factor authentication β€” with full Linux compatibility built in.

The core idea: protected services do not start at boot. Their secrets live inside encrypted OpenZFS datasets that remain locked until the operator explicitly unlocks them with a FIDO2-compatible hardware token (such as those made by Yubico), a passphrase, or both.

On FreeBSD, the transient raw key material is held in mdmfs -M (malloc-backed md(4) storage) β€” never touching swappable memory or hard storage. On Linux, the equivalent is ramfs. The raw key is wiped immediately after the dataset is unlocked.

Created by Billie Badin of SIGORYX Engineering, developed on Pi-BSD running on an untethered battery-powered stack. MIT licensed. Code in the open.

Vivian Voss's Commentary

"This is what FreeBSD-first looks like when someone actually means it."
β€” Vivian Voss on LinkedIn Β· System Architect & Philosopher

Three Things Vivian Admires

1

The threat model is stated honestly. eZFS2FA+ protects against a powered-off machine being lost, stolen, or imaged β€” not against a live compromise at unlock time. The right line to draw, drawn out loud. One sees that less often than one would hope.

2

The zero lock-in principle is structural, not promotional. Back up the ZFS raw key offline and the framework becomes optional. The user keeps their own dataset.

3

The development platform is Pi-BSD on an untethered battery-powered stack. The kind of small, deliberate, hand-built work that one used to see more of β€” a nod to Wabi-Sabi (δΎ˜ε―‚) design philosophy.

Threat Model

eZFS2FA+ states its threat model explicitly β€” a quality that Vivian Voss specifically praises. The boundaries are clear:

βœ… Protects Against

A powered-off machine being lost, stolen, or forensically imaged. Without the enrolled FIDO2 token (and passphrase if configured), the encrypted ZFS dataset cannot be decrypted.

⚠️ Does NOT Protect Against

A live, fully compromised root or kernel at the time of unlock. If an attacker has root access when you unlock the dataset, the key can be extracted from memory.

Architecture

πŸ”΄
FreeBSD Β· Primary

mdmfs -M (malloc-backed md(4))

Transient ZFS key held in malloc-backed kernel memory. Never swapped, never written to disk. Wiped immediately after dataset unlock. Uses FreeBSD's native md(4) primitive.

🐧
Linux Β· Compatible

ramfs (RAM Filesystem)

Linux-equivalent of mdmfs -M. An in-kernel filesystem that cannot be swapped to disk. Holds the transient ZFS key during the unlock window. Design respects BSD primitives rather than pretending the two systems are interchangeable.

πŸ”‘
Cryptography

FIDO2 Token Key Wrapping

The ZFS encryption key is wrapped (encrypted) using a FIDO2 hardware token (e.g., YubiKey), a passphrase, or both. The raw key is never stored directly.

πŸ“‹
State Management

Single JSON State File

All wrapped key copies for enrolled tokens live in a single JSON file. Easily backed up for disaster recovery. The raw key is never in this file β€” only the wrapped form, safe to store.

πŸ”“
Zero Lock-in

Raw Key Export

The raw ZFS key can be backed up independently and used with standard zfs send to any target. Once the key is secured offline, eZFS2FA+ becomes optional β€” the user retains full ownership of their dataset.

🍊
Development

Pi-BSD Untethered Stack

Developed on Pi-BSD running on a battery-powered ARM single-board computer. A deliberate, minimal development environment β€” as Vivian Voss notes, the kind of hand-built work one used to see more of.

Features

πŸ—οΈ

Multiple Enrolled Keys

Enrol several FIDO2 tokens so any one can unlock the dataset. Supports backup-key workflows without compromising the zero lock-in principle.

πŸ”’

Service-Start Prerequisite Checks

Dependent services are held until the dataset is explicitly unlocked by the operator. No accidental service startup with a locked dataset.

⏱️

Delayed Forced Locking

Configurable timer that forces the dataset to re-lock after a defined period, limiting the window during which the key is accessible.

πŸ“Έ

Optional Lock-Time Snapshots

Automatically take a ZFS snapshot at lock time, providing a consistent restore point before the dataset is secured again.

πŸ”Œ

Removable / Mirrored Media

Support for encrypted ZFS removable media (including mirrored configurations) is coming soon. Proxmox Server Solutions integration is also in progress.

πŸ› οΈ

Install via Script

Simple setup: git clone + doas sh ./install.sh (FreeBSD) or sudo sh ./install.sh (Linux). Python 3, cryptography, and libfido2/fido2-tools required.

How-To: Secure a ZFS Dataset with eZFS2FA+

1

Install Dependencies

On FreeBSD: install python3, py-cryptography, and libfido2 via ports or pkg. On Linux: install python3-cryptography and fido2-tools. Then clone the repo:

git clone https://github.com/BillieBadin/eZFS2FA.git
2

Run the Installer

Execute the installation script with appropriate privileges:

# FreeBSD
doas sh ./install.sh

# Linux
sudo sh ./install.sh
3

Enrol Your FIDO2 Token

Follow the interactive workflow to enrol your FIDO2-compatible hardware token. You may also enrol a passphrase, or use both (recommended for maximum protection). The wrapped key is stored in the JSON state file.

4

Configure and Lock Your Dataset

Configure the encrypted ZFS dataset to remain locked at boot. Set up service-start checks so that dependent services only start after the dataset is unlocked. Optionally configure delayed forced locking and lock-time snapshots.

5

Unlock at Operator Request

To unlock the dataset, present your FIDO2 token (and passphrase if configured). The transient ZFS key is materialised in malloc-backed md(4) (FreeBSD) or ramfs (Linux), the dataset is unlocked, the key is immediately wiped. Dependent services may then start.

Frequently Asked Questions

It protects against a powered-off machine being lost, stolen, or imaged. The ZFS dataset cannot be decrypted without physical possession of the enrolled FIDO2 hardware token and (if configured) the passphrase.
It does not protect against a live, fully compromised root or kernel at the time of unlock. If an attacker has root access while you are unlocking the dataset, the key can be extracted from memory.
eZFS2FA+ uses FreeBSD's mdmfs -M (malloc-backed md(4)) for transient key storage, a native primitive with superior memory isolation guarantees. Linux support uses ramfs as a compatible alternative, but FreeBSD's primitives are used where they exist rather than pretending the two systems are interchangeable.
The raw ZFS key is materialised only in malloc-backed md(4) memory (FreeBSD) or ramfs (Linux) β€” never in normal filesystems or swappable memory. It is wiped immediately after use and never touches hard storage at any point.
Yes. eZFS2FA+ supports multiple enrolled FIDO2 keys. Any one of the enrolled tokens can be used to unlock the dataset, enabling backup-key workflows without compromising security.
The raw ZFS encryption key can be backed up independently of eZFS2FA+. If you back up this key securely offline, you can decrypt your dataset with standard ZFS tools without eZFS2FA+ at any time. The framework is optional, not mandatory.
A single JSON file that stores the wrapped (encrypted) copies of the ZFS key for each enrolled token. This file can be backed up for disaster recovery. The raw key is never stored β€” only the wrapped form, which is safe to retain.
Pi-BSD is a FreeBSD system for Raspberry Pi and compatible single-board computers. Billie Badin developed eZFS2FA+ on a Pi-BSD installation running on an untethered battery-powered stack β€” a deliberate, minimal, hand-built environment reflecting Wabi-Sabi (δΎ˜ε―‚) design philosophy.
Yes. eZFS2FA+ supports passphrase-only wrapping, FIDO2-token-only wrapping, or both combined (recommended). Using both maximises security by requiring physical token presence and knowledge of the passphrase.
Support for encrypted ZFS removable media (including mirrored configurations) is listed as coming soon. Proxmox Server Solutions integration is also in progress to extend eZFS2FA+ to lab environments.

Glossary

FIDO2

Open authentication standard enabling hardware-token-based authentication. In eZFS2FA+, a FIDO2 token wraps the ZFS encryption key.

mdmfs -M

FreeBSD command creating a malloc-backed memory filesystem. Non-swappable, non-persistent β€” ideal for transient cryptographic key storage.

OpenZFS

Open-source ZFS filesystem with native encryption. eZFS2FA+ secures OpenZFS-encrypted datasets by wrapping their keys with FIDO2 tokens.

ramfs

Linux in-memory filesystem that cannot be swapped. Used by eZFS2FA+ on Linux for transient key storage, analogous to mdmfs -M on FreeBSD.

Wrapped Key

A ZFS key encrypted by a FIDO2 token or passphrase. Stored safely in the JSON state file; the raw key only recoverable by presenting the original credential.

Transient Key Material

The raw ZFS key in usable form, held only in volatile RAM during the unlock window and wiped immediately after use.

Zero Lock-in

Design principle ensuring that users can always recover their data without eZFS2FA+, by maintaining an offline backup of the raw ZFS key.

Threat Model

Formal statement of what a security system protects against and what it does not. eZFS2FA+'s: offline attack protection, not live root compromise protection.

MFA

Multi-Factor Authentication β€” two or more independent credentials. eZFS2FA+ implements MFA for ZFS unlock via FIDO2 token (something you have) + passphrase (something you know).

Pi-BSD

FreeBSD for Raspberry Pi and ARM SBCs. Used as eZFS2FA+'s development platform β€” a deliberate, minimal, untethered stack embodying Wabi-Sabi (δΎ˜ε―‚) design.

Knowledge Graph Explorer

Interactive D3.js force-directed visualization of the eZFS2FA+ knowledge graph. Click any node to explore its entity description via URIBurner; click edge labels to resolve predicate IRIs. Double-click a node to pin/unpin it.

Person
Organization
Concept
Resource
Settings
Enable physics


Sources