access.conf, In The Stack And Proven With PAM Itself
EL ships /etc/security/access.conf with no active rule and pam_access is not in the stack to read it, so every account is admitted from anywhere. This role writes the policy, adds the module through authselect, and refuses to write a rule set that would lock out the account running it. The live test asks PAM, with the origin set. Original role, live-tested on Rocky Linux 10.
Verification
Live-testedReally deployed to a container sandbox, proven idempotent (a second run changes nothing), verified against the role’s assertions, then torn down.
Conformance
- Static validation (yamllint · ansible-lint)
Provenance
- SHA-256 checksum
- Signature (pending)
Functional
- Live-tested - applied, verified, destroyed
Last verified 2026-09-27 · podman 4.9.3 · ansible 2.21.4 · how we verify
Cite it in your README
badge · attributionPaste this beside the module in the repository that uses it. The badge is rendered from this artifact's verification record, so it reads live-tested because the record says so, and the link lands on this page.
[](https://www.iac-bazaar.com/catalog/ansible-pam-access?utm_source=syndication&utm_medium=readme&utm_campaign=artifact)
Ansible role 1.0.0, live-tested on IaC Bazaar: [access.conf, In The Stack And Proven With PAM Itself](https://www.iac-bazaar.com/catalog/ansible-pam-access?utm_source=syndication&utm_medium=readme&utm_campaign=artifact)
```yaml
# access.conf, In The Stack And Proven With PAM Itself: https://www.iac-bazaar.com/catalog/ansible-pam-access (download from your IaC Bazaar account)
```Preview:
Documentation
pam-access
EL ships /etc/security/access.conf with no rules in it, and pam_access is
not in the stack to read them. 4,671 bytes of documentation, a control that
appears configured, and every account admitted from anywhere. This role writes
the policy, puts the module into the authentication stack through authselect -
/etc/pam.d/system-auth is a symlink into generated files, so editing it by hand
does not survive - and proves each rule by asking PAM.
No download, and no version to pin. pam and authselect are EL 10 packages.
What the role owns is access.conf in full and one authselect feature, and what
it proves is that a named account gets in from a named place and nobody else
does.
The order of the file is the policy. pam_access stops at the first rule
that matches, so a blanket allow above a deny makes the deny dead. That is why
the template renders the rules in a fixed order and why
pam_access_prepend_rules is documented as the dangerous escape hatch rather
than the convenient one.
This role can lock you out of a host, so it checks first. With
pam_access_deny_all and a group list that does not include you, the next login
is refused - and after - : ALL : ALL, root's ssh logins are refused too, because
pam_access_allow_root_from is LOCAL by default. Before writing anything the
role reads the account this play is connected as, the groups the host gives it,
and whether the connection arrived over ssh, and refuses to write a policy that
would shut that account out. The check has one limit, stated because it matters:
it requires that a non-LOCAL origin exists for root, not that the origin is
yours.
A line pam_access cannot parse is ignored, and the account is admitted.
Measured: with this is not a rule in the file, the account under test was still
allowed. Nothing validates access.conf - there is no checker to give a
template validate: - so the live test drives PAM with pamtester rather than
reading the file back, and it reads the refusal message as well as the exit code.
First match wins, in both directions. With + : ALL : ALL above
- : user : ALL the user was admitted; with the deny first the same user was
refused. This is the trap that makes a long access.conf unreadable: a rule
added at the top for one host silently retires everything below it.
LOCAL is a real origin, not the absence of one. A rule allowing a user from
10.99.0.0/24 refused that user from 203.0.113.7 and from a console login
with no remote host at all. + : root : LOCAL is what admits root on the
console, and it is what makes root's network logins refused.
License
Commercial - IaC Bazaar EULA. (c) IaC Bazaar.
Usage code & full reference need an account
The complete copy-paste usage, the full input/output reference, and operational notes are free with an account - shown here and bundled in the download. Sign in and this section fills in.
- Variables
- Test
Related modules
ansible-lynis
Lynis from EPEL on a systemd timer, with the units the package keeps only in its docs, your skipped tests in custom.prf, and a minimum hardening index below which the audit unit fails, so a falling score shows as a failed unit. The live test runs the audit, reads the index and the tests that ran, and finds the timer enabled. Original role, live-tested on Rocky Linux 10.
ansible-suricata
Suricata from EPEL watching the default-route interface as the suricata user, ET Open fetched at install and refreshed daily, plus a canary rule that proves the sensor is alive. A root-run check left root-owned logs and a daemon recording nothing; the role prevents it. The live test raises the canary alert while a second lookup is logged, not alerted. Original role, live-tested on Rocky Linux 10.
ansible-aide
AIDE from AppStream on EL 10: a watched tree, a baseline database built once, and the oneshot unit and timer the package does not ship. The live test passes on an unchanged host, FAILS when a file appears inside a watched path and names it, ignores one inside an excluded path, and passes again once the change is gone. Original role, live-tested on Rocky Linux 10.
ansible-389-ds
389 Directory Server from AppStream. A fresh instance listens on every interface and lets anonymous clients read the tree; this role binds both listeners to loopback and limits anonymous clients to the rootDSE. The live test adds a user who binds, sees a wrong password and an anonymous search refused, and reads the LDAPS certificate. Original role, live-tested on Rocky Linux 10.
ansible-krb5-kdc
An MIT Kerberos KDC: the realm created once with a stash, kadmind behind an ACL, a default policy that locks an account after five wrong passwords, every listener on loopback. The KDC starts on a broken config without a word, so the live test proves each setting by behaviour: the ticket lifetime, the refusals, the lockout. Original role, live-tested on Rocky Linux 10.
ansible-authelia
Authelia from the upstream release (sha256-verified) as a hardened system service on loopback with file users and sqlite; its secrets are generated once on the host and reach the service as AUTHELIA_*_FILE variables. The live test hashes a password with Authelia's hasher, logs in, sees a wrong password refused and an anonymous visitor sent to the portal. Original role, live-tested on Rocky 10.