Auditing PAM and Password Policy on Linux with AI
PAM controls who gets in and how. Here's how I use AI to audit pam.d stacks and password policy for weak lockout, missing MFA hooks, and silent authentication bypasses.
- #security
- #hardening
- #linux
- #authentication
- #ai
Pluggable Authentication Modules — PAM — is one of those subsystems that everyone depends on and almost nobody understands. It decides whether a login succeeds, whether a password is strong enough, how many failures trigger a lockout, and whether MFA is enforced. It’s configured in a stack of cryptic files under /etc/pam.d/, where the order of lines matters and a single misplaced sufficient can wave an attacker straight through.
I once inherited a server where someone had added auth sufficient pam_permit.so to the top of the SSH stack to “debug a login issue” and never removed it. That one line meant any password — or no password — authenticated successfully. It sat there for months. Auditing PAM by hand is brutal because the syntax is unforgiving and the failure mode is silent. So I let AI do the first read. Defensively: finding the bypasses, not building them.
What PAM gets wrong, and why it’s dangerous
PAM misconfigurations cluster around a few themes:
pam_permit.soin an auth stack — unconditionally succeeds. It belongs in narrow places; in anauthstack it’s an open door.- Control-flag mistakes —
sufficientshort-circuits the stack on success, so its placement determines whether later checks (like account expiry) even run. - Weak or missing password quality — no
pam_pwquality/pam_cracklibmeans users can setpassword123. - No account lockout — without
pam_faillock, an attacker can brute-force forever. - Missing MFA enforcement — an MFA module present but marked optional, or absent entirely.
These are all readable in the config, but reading PAM correctly requires holding the control-flow semantics in your head, which is exactly where a careful AI reviewer helps.
Gather the stack and the policy
Collect the relevant PAM files and the password-aging policy together — they interact:
# The authentication stacks that matter most
cat /etc/pam.d/sshd /etc/pam.d/common-auth /etc/pam.d/system-auth 2>/dev/null
# Password quality and aging policy
cat /etc/security/pwquality.conf 2>/dev/null
grep -E "^PASS_(MAX|MIN|WARN)" /etc/login.defs
# Lockout config if present
cat /etc/security/faillock.conf 2>/dev/null
I feed these to the model as a set, because the password policy in login.defs and pwquality.conf only means something in the context of which PAM modules actually enforce it.
A PAM audit prompt that respects control flow
PAM is all about ordering and control flags, so I tell the model to reason about the stack as a flow:
You are a Linux authentication auditor. Below are PAM stacks and the
password policy from a production server. Find security weaknesses ONLY:
1. Any module that could bypass authentication (pam_permit, misplaced
sufficient, nullok allowing empty passwords).
2. Control-flag ordering issues where a sufficient/required line lets a
later critical check be skipped.
3. Missing or weak password quality enforcement (length, complexity).
4. Missing account lockout (pam_faillock/pam_tally2) against brute force.
5. Whether MFA is enforced or merely optional.
Reason about the stack as a top-to-bottom control flow. Explain each
finding's impact. Do not rewrite the files.
<paste pam.d files + pwquality.conf + login.defs excerpts>
Run this against the file with the rogue pam_permit.so and the model flags it immediately: a sufficient (or pam_permit) line near the top of the auth stack short-circuits success before any real authentication runs. It also reliably catches nullok, which silently permits empty passwords — a setting that’s easy to copy from a tutorial and forget.
Pro Tip: Ask the model to trace, line by line, “what happens if the password check fails?” for each auth stack. A correctly built stack should deny on failure; if the trace shows a path to success despite a failed password, you’ve found a bypass. This flow-tracing is where AI saves the most time, because it’s exactly the reasoning humans skip.
Harden with concrete modules
Once a gap is confirmed, the fixes are well-known modules. For lockout, pam_faillock denies after repeated failures:
# /etc/pam.d/common-auth — lock for 15 min after 5 failures
auth required pam_faillock.so preauth silent deny=5 unlock_time=900
auth [default=die] pam_faillock.so authfail deny=5 unlock_time=900
For password strength, pam_pwquality enforces real complexity:
# /etc/security/pwquality.conf
minlen = 14
minclass = 3
maxrepeat = 3
The AI is good at recommending these, but PAM is one of the few places where a mistake locks everyone — including you — out of the box. Always keep a root session open while testing PAM changes, and verify the model’s proposed stack in that second session before closing your safety line. I treat every PAM edit as a change that needs the same care as a risky shell command pre-flight.
Make it a recurring audit
Authentication config drifts as people debug things and forget to revert. I run this audit on a schedule and on every change to /etc/pam.d/, flagging diffs the way our code review dashboard flags risky changes generally. For the review itself I use Claude with the flow-tracing prompt; reusable versions live in the prompt library.
Defensive, verified, secrets-free
The model is a fast junior auditor that genuinely understands PAM control flow better than most engineers remember it — and it never gets the ordering tired-and-wrong the way a human does at the end of a long day. But it can misjudge intent (some optional lines are deliberate) and a wrong fix can lock out the whole machine. So I verify every recommendation in a second root session before committing. PAM files don’t contain secrets, but I still strip real usernames and any LDAP/AD bind details before pasting — the module structure is what the model needs, not your directory layout.
Conclusion
PAM decides who gets in, and its silent failure modes make it one of the highest-leverage things to audit and one of the most-skipped. An AI reviewer that traces the auth stack as a control flow turns that skipped audit into a fast, repeatable one — while you keep the open root session, verify the fix, and own the change. Build it into your wider security and hardening baseline.
Download the Free 500-Prompt DevOps AI Toolkit
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.