Skip to content

FAQ

Why a user namespace but not a full container or VM? The part that needs isolating is ZFS, and zfs zone isolates exactly that: the kernel filters which datasets a namespace can see. A container would still need /dev/zfs, and the usual container setup makes the tenant root inside its namespace, which ZFS treats as the zone's administrator: that bypasses zfs allow, so the tenant could, for example, destroy the root dataset you created for them. zfs-tenant maps the tenant to its own uid inside the namespace instead, so delegation keeps deciding what it may change. The old VM setup existed only because TrueNAS replication needed root on the receiving end; delegation removes that need.

Why a holder service? In OpenZFS 2.4, zfs zone attaches a dataset to one running namespace, so something has to keep that namespace alive. OpenZFS master can attach datasets to a uid instead (zoned_uid). Once that is released, it may replace the holder, after checking that its permission and capability rules still leave zfs allow in charge.

Why not zrepl? zrepl's sink mode does per-client subtrees, but it replaces sanoid and syncoid on both sides and runs as root on the receiver. Here the kernel enforces the boundary, and both sides keep the tools they already use.

Why push instead of pull? With pull, the host would need rights on the friend's machine, and the friend could not create or remove datasets on their own. With push, the friend owns their corner of your pool and you hold no keys to theirs.

Why Python and not a shell script? The gate's input is an untrusted string. Parsing it in shell invites word splitting and injection; Python gives a real tokenizer, strict allowlists, exec of an argument list, and unit tests. It stays dependency-free so it runs from a single file on appliances.