File integrity monitoring is a simple idea: record a cryptographic hash of every file you care about, re-check periodically, alert when a hash changes unexpectedly. Almost every compliance framework asks for it. Far fewer teams run it well.
What it catches
Webshells. An attacker drops a script into your web root. No new process, no new port, nothing in auth logs, but a new file exists, and FIM sees it.
Backdoored binaries. A replaced ls or ps that hides the attacker's activity. Rootkits do this routinely, and the modified binary hashes differently.
Config tampering. Changes to sshd_config, sudoers, cron, or systemd units, the exact drift a hardening pass can't catch once it's done. Persistence usually requires touching one of these.
Silent drift. Not every finding is an attack. Sometimes a deploy script overwrote a config nobody meant to change. That is still worth knowing.
What it misses
FIM is blind to anything that does not touch the filesystem: in-memory attacks, credential theft, data exfiltration over an existing connection, or abuse of legitimate credentials. It is one layer, not a strategy.
A minimal baseline, by hand
Before reaching for a dedicated tool, this is what FIM actually does under the hood:
# Baseline
find /etc /usr/bin /usr/sbin /root -type f -exec sha256sum {} \; > baseline.sha256
# Re-check later
sha256sum -c baseline.sha256 --quiet
Every real FIM tool (AIDE, Tripwire, osquery, Wazuh's syscheck) is a more efficient, scheduled version of that loop.
Why most FIM deployments fail
The failure mode is always the same: too many alerts. Monitor /var naively and every log rotation, cache write, and package update fires a change event. Within a week nobody reads the alerts.
Three things fix this:
Scope deliberately. Monitor /etc, /usr/bin, /usr/sbin, /root, and your web root. Do not monitor log directories, caches, or temp.
Baseline per server. A web server and a database server have different normal. A shared baseline generates noise on both.
Distinguish expected change. A file changing during a deploy window is different from the same file changing at 3am. Timing and context matter as much as the hash.
Self-healing baselines
The practical problem is that legitimate change happens constantly. If every package update requires manually re-approving hundreds of hashes, the system gets switched off. A better approach: recognise package-manager-driven change as expected, update the baseline automatically, and reserve alerts for changes that have no legitimate explanation. That is how SecAI runs FIM - scoped defaults, per-server baselining, and an AI validation pass that suppresses expected change before it reaches a human, so the compliance checkbox actually reflects something being watched. See it alongside the rest of the detection stack.