{
config,
pkgs,
lib,
...
}:
with lib;
let
parentConfig = config;
overrideServices =
{ name, config, ... }:
{
options = {
use2Factor = mkOption {
description = "If set to true u2f is used as 2nd factor.";
default = parentConfig.security.pam.use2Factor;
};
u2fModuleArgs = mkOption {
description = "Additional arguments to pass to pam_u2f.so";
default = parentConfig.security.pam.u2fModuleArgs;
};
};
config = lib.mkIf config.use2Factor {
rules.auth.unix = {
control = lib.mkForce "required"; # was sufficent
order = lib.mkForce 12900;
};
rules.auth.u2f = {
order = lib.mkForce 12910; # after pam_unix
};
};
};
in
{
options = {
security.pam.services = mkOption {
type = with types; attrsOf (submodule overrideServices);
};
security.pam.use2Factor = mkOption {
description = ''
If set to true u2f is used as 2nd factor in all pam services.
A service definition may override this setting.
'';
default = false;
};
};
config = {
environment.systemPackages = with pkgs; [
yubikey-personalization
yubioath-flutter
];
services.pcscd.enable = true;
services.udev.packages = with pkgs; [
yubikey-personalization
];
security.pam.u2f.enable = true;
security.pam.u2f.settings.cue = true;
security.pam.services."polkit-1".use2Factor = false;
security.pam.services."doas".use2Factor = false;
security.pam.services."sudo".use2Factor = false;
};
}