0026: Transient-unit executor (spike S1-c)
ADR-0026: Transient-unit executor (spike S1-c)
Section titled “ADR-0026: Transient-unit executor (spike S1-c)”- Status: Accepted: option 2 (decided by the maintainer, 2026-11-01); implementation scheduled before v0.1 (F2 milestone)
- Date: 2026-11-01
- Related: ADR-0007, ADR-0010, docs/threat-model.md
Context
Section titled “Context”The core unit grants ReadWritePaths=/etc /var/lib/ibexwall /run/ibexwall
because the in-process executor may write any path a manifest declares.
The spec asks whether the executor can instead run in a transient unit
(StartTransientUnit) whose ReadWritePaths= equals exactly the paths of
one transaction.
Spike results (Fedora 44, systemd, 2026-11-01, systemd-run -p ...)
Section titled “Spike results (Fedora 44, systemd, 2026-11-01, systemd-run -p ...)”ProtectSystem=strictplusReadWritePaths=<parent dir>: the atomic write (tmp file + rename) succeeds in that directory, while writes to other paths in/etcand to/usrfail with EROFS.ReadWritePaths=<file>only: rename fails (EROFS on the temporary file); only in-place writes work. In-place writes are not atomic, so the executor must expose the parent directory, not the file.sysctl.setworks withProtectKernelTunables=notogether withRestrictSUIDSGID=yes.- Starting a transient unit and waiting for it took about 26 ms.
- Not measured: behavior for a path that does not exist. The
systemd.exec(5) man page says unit start fails unless the path is
prefixed with
-; the daemon would need to create missing drop-in parent directories first or use the-prefix.
Options
Section titled “Options”- Keep the in-process executor (today). Simple. The daemon can write
anywhere under
/etc, so a path-validation bug has a large blast radius. - Executor helper in a transient unit per transaction (
ibexwall-execreads the validated ops, runs withReadWritePaths=set to the parent directories of that transaction, minimal capabilities). The daemon unit then shrinks to/var/lib/ibexwalland/run/ibexwall. - Static per-plugin sandbox (declare
ReadWritePathsfrom manifests in a drop-in). Coarser than option 2 and fixed at install time.
Recommendation
Section titled “Recommendation”Option 2 was adopted, to be implemented before v0.1: it is viable and cheap in latency. Be clear about what it buys: it contains bugs in path validation and plugin-proposed operations. It does not protect against a fully compromised daemon, which can still ask systemd to start any transient unit. The cost is a new helper binary, an IPC for the ops, and unit-start error handling inside the transaction (a failed start must roll back like any failed step).
Until accepted, the in-process executor stays and the threat model lists
the wide ReadWritePaths as an accepted risk.
Consequences if adopted
Section titled “Consequences if adopted”- New crate/binary
ibexwall-execand aSystemdtrait method with a fake for engine tests. - Per-op-type property sets (files, sysctl, nft needing
CAP_NET_ADMINandAF_NETLINK,systemctlactions through D-Bus). - The VM suite gains a scenario that proves a plan cannot write outside its declared directories.