nixos/modules/defaults/yubikey.nix
2025-04-03 23:42:38 +02:00

51 lines
1.7 KiB
Nix

{ config, lib, pkgs, ... }: let
cfg = config.security.pam.yubico;
in {
options.security.pam.yubico = {
logoutOnRemove = lib.mkEnableOption "Logout on Yubikey remove";
asClient = lib.mkEnableOption "Use Yubikey as client";
clients = lib.mkOption {
type = with lib.types; attrsOf (listOf str);
example = { myUser = [ "myYubikeyTokenID" ]; };
default = {};
description = "The users that are allowed to use the Yubikey";
};
product_id = lib.mkOption {
type = lib.types.str;
default = "1050/407/543";
description = "The product id of the Yubikey";
};
};
config = lib.mkIf cfg.enable {
systemd.tmpfiles.rules = let
keysFiles = builtins.mapAttrs (n: v: pkgs.writeText "authorized_yubikeys_${n}" ''
${lib.concatStringsSep ":" ([ n ] ++ v)}
'') cfg.clients;
in if cfg.asClient then
(builtins.concatMap (n: [
"d /home/${n}/.yubico 0655 ${n} users -"
"L+ /home/${n}/.yubico/authorized_yubikeys 0644 ${n} users - ${keysFiles.${n}}"
"Z /home/${n}/.yubico - root root"
]) (builtins.attrNames cfg.clients))
else
[ "d /var/yubico 0700 root root -" ];
services.udev.extraRules = lib.mkIf (cfg.logoutOnRemove && !cfg.asClient) ''
SUBSYSTEM=="usb", ACTION=="remove", ENV{PRODUCT}=="${cfg.product_id}", RUN+="${pkgs.systemd}/bin/loginctl lock-sessions"
'';
security.pam = {
services.hyprlock.yubicoAuth = lib.mkIf config.programs.hyprlock.enable false;
yubico = {
id = "106508";
mode = if cfg.asClient then "client" else "challenge-response";
control = "required";
challengeResponsePath = lib.mkIf (!cfg.asClient) "/var/yubico";
};
};
};
}