Ensure PAM Enforces Password Requirements - Enforce for root User
Set enforce_for_root in the pwquality configuration so the password policy (length, character classes, dictionary checks) is enforced for root too. Without it, pam_pwquality only prints a warning when root sets a weak password, then accepts it.
Checked against the content of a persistent configuration file, the source of truth that survives reboots.
A mapping is a cross-reference to where each standard places this requirement, anchored and cross-validated, not a claim of equivalence. A passing check is evidence toward these references, how to read it.
Why this rule matters
Use of a complex password helps to increase the time and resources required to compromise the password. Password complexity, or strength, is a measure of the effectiveness of a password in resisting attempts at guessing and brute-force attacks. Password complexity is one factor of several that determines how long it takes to crack a password. The more complex the password, the greater the number of possible combinations that need to be tested before the password is compromised.
What Pavois checks
Pavois greps for a non-commented enforce_for_root directive across /etc/security/pwquality.conf and the /etc/security/pwquality.conf.d/ drop-in directory, which together are the full set of files libpwquality actually reads. Checking only the main file would miss the directive when it is delivered by a drop-in (and, conversely, would not see one re-added there). enforce_for_root is a boolean directive: its mere presence enables it, which is why the check tests for the key rather than for a value.
describe command('grep -rqE \'^[[:space:]]*enforce_for_root\b\' /etc/security/pwquality.conf /etc/security/pwquality.conf.d/ 2>/dev/null && echo ok || echo ko') do
its('stdout.strip') { should eq 'ok' }
endHow to verify it is applied
Confirm the directive is present in the resolved configuration set:
grep -rE '^[[:space:]]*enforce_for_root' /etc/security/pwquality.conf /etc/security/pwquality.conf.d/
/etc/security/pwquality.conf.d/99-pavois.conf:enforce_for_root = 1
The effective test is behavioural: as root, run passwd root and enter a deliberately weak password. With the directive active it is rejected (BAD PASSWORD: The password is shorter than N characters) instead of merely warned about.
Inspect & investigate
A rejection is logged by PAM in /var/log/auth.log (Debian/Ubuntu) or journalctl (RHEL family):
passwd[7788]: pam_pwquality(passwd:chauthtok): bad password: The password fails the dictionary check
Without enforce_for_root, the same line still appears for root, but the password change succeeds anyway: the log alone does not tell you whether the policy was enforced, which is why the behavioural test above matters.
Remediation
The Pavois harden plan uses a keyval remediation that writes enforce_for_root = 1 into its own drop-in, /etc/security/pwquality.conf.d/99-pavois.conf, rather than patching the distribution's pwquality.conf. The resource is aggregated: Pavois rewrites that drop-in with the complete set of pwquality keys it manages (minlen, minclass, difok, …), so the file always carries the full desired state. A key you add to 99-pavois.conf by hand is therefore overwritten at the next apply; put your own overrides in a separate drop-in file. On distributions driven by authselect (RHEL family), Pavois also enables the matching authselect feature so the PAM stack keeps calling pam_pwquality.
Pavois applies this with its own harden engine, the plan below, not a shell script:
| file | /etc/security/pwquality.conf.d/99-pavois.conf |
|---|---|
| key | enforce_for_root |
| resource | keyval |
| value | 1 |
pavois harden plan localwhere the target is local, a user@host SSH alias, or a container , Docs
Impact & precautions
Without enforce_for_root, the most privileged account of the machine is the only one allowed to pick a trivially guessable password, which defeats the whole policy. Enabling it has no effect on existing passwords and cannot lock anyone out: it constrains only future password changes made through PAM (passwd). Two consequences to anticipate. First, a break-glass procedure that relies on setting a simple root password will now be rejected: prepare a compliant password beforehand. Second, the directive covers only the PAM path; scripted changes that bypass PAM (usermod -p, writing a hash straight into /etc/shadow) are not filtered by pwquality, so provisioning tooling must apply the policy on its own.
Standards mapping
| Standard | Reference | Type | Version | Confidence |
|---|---|---|---|---|
| CIS | 5.3.3.2.8 | direct | per OS, see the benchmark table | high |
| NIST | IA-5(c), IA-5(1)(a), CM-6(a), IA-5(4) | supporting | 800-53 Rev 5 · 800-171 Rev 2 (pinned) | medium |
Each reference is a cross-reference anchored in the upstream benchmark and cross-validated against the SCAP Security Guide and ansible-lockdown, not a claim of equivalence. Direct = a prescriptive, line-level requirement; supporting = an abstract control family (NIST) the check provides evidence toward. How to read a mapping.