The NixOS security.pam module provides config options for Linux PAM (Pluggable Authentication Modules). PAM is how the authentication stack is configured for login and also programs like sudo, passwd, su, etc. With PAM, you can configure 2FA, LDAP/AD, encrypted home directories, automatic keychain unlock, and more.
The PAM infrastructure in NixOS needs some love. I have done some refactoring and I’m thinking about spinning up an RFC for a bigger design evolution. First, I want to hear from you:
What do YOU want the NixOS PAM module to do for you?
Below is my first stab, broken out by user category. Please comment with any corrections or additions!
Defaults are secure. “I don’t have to think about PAM.”
Enabling a feature (e.g. U2F, LDAP) is as easy as configuring a NixOS service.
Different PAM features “just work” together by default.
NixOS/PAM Power Users
PAM stack can be fine-tuned through NixOS config. (Reorder rules, change arguments, etc.)
Never need to manually write PAM config files.
New PAMs can be added through NixOS config.
Customizing parts of the PAM stack doesn’t require maintaining the whole stack yourself.
PAM options are defined entirely in their own files (NixOS modules).
Clear guidance exists for how new PAMs should fit into the stack of PAM rules.
Desktop environments and other software don’t need to duplicate the PAM stack.
Insecure or unsuitable defaults are fixed without breaking existing users.
Now that I have, I can see that we are thinking similarly about many things! A lot of the changes you made are on my todo list if not already implemented.
So far, I’ve focused on lifting PAM rules into the module system, offering a low-level abstraction for defining rules first. My thinking is that if a user has to use the text escape hatch, then they have to throw away all the benefits of the module system. (Imagine a user using five different security.pam settings happily, only to have to write all their PAM rules manually because one need isn’t met by the modules as defined.) Hence the desire to “never need to manually write PAM config files.”
We also want (and to some extent already have) higher-level abstractions for enabling “features” or “modules” that create many rules. These options can be more opinionated and offer useful defaults, like 2FA modules coming after password login. My hope is that I can defer these higher-level design changes until after reworking the rule generation internals.
It looks like your PR addressed both these needs, and our PRs have fairly minor differences in interface design. One area I’ve neglected that I discovered in testing yesterday is defaults, since it isn’t (AFAIK) possible for a user to extend every value in a config attrset.
Unfortunately their wasn’t much traction to make this happen when I worked on it, but hopefully you’ll have more luck!
My burning question for you is: Where did your PR get stuck? How can I make sure I don’t get similarly stuck? It looks like you did great work and documented it well.
Where did your PR get stuck? How can I make sure I don’t get similarly stuck? It looks like you did great work and documented it well.
I think it’s simply due to its size, and perhaps the lack of “advertising” around it. I think if you manage to make as many small, non-breaking changes as possible (at least to the exposed modules under security.pam like security.pam.yubico.enable) before changing that, you’ll be able to rework the backend and have a proper foundation for moving forward. And with that, try to get as many eyes as you can on the PRs to get traction from core maintainers to make this happen.
I’d also be careful of the timing, no one wants to merge potentially breaking changes before a stable release.
I don’t know if going through the RFC process would be appropriate for those changes, but if you decide to, I’d love to co-author it.
Thanks for your thoughts! I made some changes to #255547 to hopefully make things smoother:
Cleaned up some inconsistencies in how rules are defined up front. That made the rest of the commits more automated and consistent.
Set the new options visible = false and marked them experimental. The idea is to retain the flexibility to rework these options and minimize the impact of getting the design wrong the first time around.
I don’t know yet if an RFC makes sense, but I’d be happy to work with you on one if so. I’ll definitely want to bounce some ideas off you when I get to the user-facing option design regardless.
As for getting more eyes on this work, I’ll start now: this refactor PR is ready for review! If you believe these PAM changes are important, please take a look through the commits and leave a review. The changes are easy on the eyes, I promise.
i don’t super mind whether docs go to the wiki or the official manual, but either way some more clarity on how to use this would be nice.
tests are cool too but i’m not sure they’d be as accessible for newer users as a substitute for documentation.
I was trying to figure out a way to get the nextcloud client to work with autologin on SDDM and an empty kwallet password and couldn’t make it work. I found some instructions on how to edit pam.d files to facilitate this but couldn’t try them out because I don’t know how to change pam.d files in NixOS. So that would be my use case.