fapolicyd (File Access Policy Daemon) is an application allowlisting framework for Linux, developed by Red Hat and shipped as a supported component of RHEL 8+. Its security premise is supply-chain integrity at the execution layer: only software that was installed through a trusted package manager (DNF/RPM) or explicitly declared as trusted by an administrator may execute on the system. An attacker who achieves a foothold and drops a new binary — a reverse shell, a lateral movement tool, a cryptominer — will find that binary blocked at execution time, because it is absent from the trust database, regardless of its Unix permissions or SELinux label. fapolicyd addresses a different dimension of access control than SELinux: SELinux models how applications behave (what resources they may access); fapolicyd models whether applications are trusted at all (whether they may execute in the first place). The two are complementary: SELinux confines a trusted application’s behaviour; fapolicyd prevents untrusted applications from running.
The kernel mechanism underlying fapolicyd is fanotify with the FAN_OPEN_EXEC_PERM event type. When any process calls execve(), execveat(), or uselib(), the kernel generates a FAN_OPEN_EXEC_PERM event and blocks the executing thread until fapolicyd returns a verdict. fapolicyd looks up the file in its trust database — an lmdb key-value store at /var/lib/fapolicyd/ — and evaluates the matching rule in its policy. The trust database is populated automatically via a DNF plugin that notifies fapolicyd whenever packages are installed or removed, keeping the database in sync with the RPM state without manual intervention; rpm-based installations outside DNF require a manual fapolicyd-cli --update to refresh the database. Files can also be added to the trust database explicitly via /etc/fapolicyd/fapolicyd.trust or the trust.d/ directory, for files delivered outside the package manager (custom scripts, vendored binaries, container runtimes). The policy rule language (/etc/fapolicyd/rules.d/) allows rules combining trust status, file path patterns, process path, UID/GID, and file type — for example, permitting any trusted executable to run from /usr, blocking execution from /tmp, /var/tmp, and /dev/shm unconditionally (a common dropper target), and denying untrusted scripts regardless of interpreter. Like SELinux and AppArmor, fapolicyd supports a permissive mode (permissive = 1 in fapolicyd.conf) that logs violations without enforcing them, enabling policy refinement before enforcement.
The three integrity checking modes are fapolicyd’s most security-relevant configuration axis. In the default mode (integrity checking off), fapolicyd trusts any file at a known path that is in the trust database by name — it does not verify the file’s contents, so a file replaced in-place with a malicious binary of the same name and size would pass. Size-based integrity adds a comparison of the file’s current size against the size recorded in the trust database, catching coarse tampering. SHA-256 hash integrity (integrity = sha256 in fapolicyd.conf) computes the SHA-256 hash of the file at execution time and compares it against the hash in the trust database — catching any content modification, at the cost of a hash computation on every execution of an uncached file. The third mode, IMA-based integrity (integrity = ima), reads the IMA-computed hash from the file’s security.ima extended attribute rather than computing it on the fly, combining the performance of a fast xattr lookup with the security of content-based verification — but requires IMA appraisal to be configured and the filesystem to support i_version. Red Hat does not recommend enabling hash integrity by default due to deadlock risk on systems where the hash computation itself triggers further fanotify events, but it is the correct mode for high-assurance deployments. fapolicyd integrates with the Linux audit subsystem for logging, composes naturally with USBGuard (USBGuard controls what hardware can connect; fapolicyd controls what software from that hardware can run), and pairs with IMA measurement for attestation: the combination of IMA’s runtime measurement log and fapolicyd’s execution gating gives a system where every executed file is both attested (IMA recorded its hash in TPM PCR 10) and authorised (fapolicyd confirmed it was trusted before allowing execution).
