Handbook sections▾
Foundations
Understanding the threats to a Linux hostWhy we hardenThe defense principles behind every ruleEffective configuration: the truth no file holdsThe standards Pavois maps toSOCLE control ID modelEvidence & exportsHow the A-E grade is computedWhat a PASS proves: the qualified verdictTrust model for the evidence bundleIs SOCLE just your own norm? (governance & the circularity question)What Pavois covers, and what it doesn'tDomains
Hardening SSHHardening PAMMandatory Access Control (SELinux / AppArmor)Hardening the host firewallHardening sudoFile Permissions & OwnershipMount & filesystem hardeningHardening kernel modulesHardening the kernel & network with sysctlAudit logging with auditdHardening logging with journald and rsyslogHardening systemd servicesPackage hygieneHardening the bootloader (GRUB)Synchronizing timeLogin banners and MOTDControlling cron and at accessHardening the GNOME desktop (dconf)Tooling
Undo a hardening run: restore pointsOperating Pavois: privileges, air-gap, timing, exceptionsRun Pavois in CI (GitHub Actions)Feature status: delivered, partial, roadmapGovernance: licence, versioning, provenance, securityWhat a PASS proves: the qualified verdict
Last reviewed
Most scanners answer with one bit: pass or fail. Pavois qualifies every PASS on two axes, what evidence it read and whether it survives a reboot, and the verdict feeds the A-E grade.
Most scanners answer a control with one bit: pass or fail. That bit hides the question that actually matters on a running system: what does this PASS prove, and will it still be true after a reboot? Pavois makes that explicit. Every control carries a qualified verdict built from two independent axes, and the verdict feeds the A-E grade.
Two axes, not one
Evidence type: what the check actually reads (detailed in evidence and exports). Pavois uses four types:
| Evidence type | What a PASS proves |
|---|---|
effective-runtime |
the value resolved in the running system (sshd -T, sysctl, auditctl -l) |
persistent-config |
the setting is written where it survives a reboot |
inventory-state |
a package or component is installed or absent (dpkg/rpm) |
filesystem-state |
a file's mode, owner or content on disk |
Reboot-survivability (reboot_survivable): whether a PASS proves a state that survives a reboot. This is independent of the evidence type: a runtime read can still be reboot-proof (a kernel's compiled config, sshd -T re-parsing the config files), while another is purely live (sysctl of the running kernel, a mount -o remount, a rule loaded with auditctl but absent from disk). It answers will it still hold after a reboot?
A pass proves: three columns
Each control's fiche shows what a PASS establishes across running now, on disk, and survives reboot, each as proven, not measured, or not applicable. A sysctl checked only against the live kernel proves running now but leaves survives reboot unknown; the same check that also asserts the value is pinned in /etc/sysctl.d proves all three.
The grade cap
A runtime-only PASS, active now with persistence unproven, does not count as a full pass. It caps the grade: a host whose conformance rests on live-only state cannot earn a clean A; the grade is shown runtime-qualified (capped to B) until persistence is proven. The points themselves stay failure-driven (a qualified pass never adds a failure), so the cap is honest, not punitive: it refuses to hand out an A for a posture that would regress on the next boot. In --format json this is visible as runtime_qualified and qualified_passes:
{
"grade": "B",
"points": 100,
"runtime_qualified": true,
"qualified_passes": 7,
"passed": 150,
"total": 150
}Here the points are 100 (no control failed), an A on arithmetic alone, but 7 passes rest on unproven persistence, so the letter is capped to B while the points stay 100.
How persistence is actually proven
Pavois doesn't leave this as a caveat, it folds the persistence proof into the check itself wherever there is a clean source of truth:
- sysctl asserts the live value and that it is pinned in a sysctl config file.
- mount options assert the live option and an entry in
/etc/fstabor a systemd.mountunit. - kernel command line asserts
/proc/cmdlineand the parameter in the bootloader config. - audit rules assert the rule is loaded and present in
/etc/audit/rules.d. - kernel modules are reboot-proof by construction (
be_disabledreads the persistentmodprobe.dconfig).
A handful of controls remain legitimately runtime-only (a MAC mode via getenforce, a service's live is-active, the live firewall) with no clean persistent source to fold. They stay runtime-qualified, honestly.
Reboot-proven
The strongest proof is empirical. pavois harden apply --reboot --scan converges the fixes, reboots the target, waits for it to return, and re-scans, so a PASS in that report survived a real reboot. Controls that only take effect after a boot (a kernel cmdline parameter, an immutable audit ruleset) are then reboot-proven, not merely asserted. That is the bar a clean A is held to.
FAQ
What does a PASS actually prove? Exactly what its evidence type and reboot-survivability say: an effective-runtime PASS proves the value is in force now; only a check that also reads the persistent source (or a post-reboot re-scan) proves it survives a reboot.
Why was my A capped to B? Because some passes are runtime-only with unproven persistence. The grade is shown runtime-qualified; prove persistence (or re-scan after a reboot with --reboot --scan) to lift the cap.
Which controls can never be reboot-proven without a reboot? Genuinely live-only ones: SELinux/AppArmor mode, a service's is-active, the running firewall. Pavois marks them runtime-qualified rather than pretending the live state is persistent.