{ config, lib, pkgs, ... }: let cfg = config.local.yubikey; control = if cfg.multi-factor.enable then "required" else "sufficient"; in { options.local.yubikey = with lib; { enable = mkEnableOption "yubikey"; serial = mkOption { type = types.nullOr types.str; default = null; }; multi-factor.enable = mkEnableOption "multi-factor" // { default = true; }; unplug = { enable = mkEnableOption "Do action when a Yubikey is unplugged"; model = mkOption { type = types.str; default = "407"; }; command = mkOption { type = types.str; default = "${pkgs.systemd}/bin/loginctl lock-sessions"; }; }; }; config = lib.mkIf cfg.enable { environment.systemPackages = [ pkgs.yubikey-manager pkgs.yubikey-personalization ]; security.pam = if cfg.serial == null then { u2f = { enable = true; inherit control; cue = lib.mkDefault true; }; services = { login.u2fAuth = lib.mkDefault true; sudo.u2fAuth = lib.mkDefault true; }; } else { yubico = { enable = true; inherit control; mode = "challenge-response"; id = [ cfg.serial ]; }; }; services.pcscd.enable = cfg.serial != null; services.udev = { packages = [ pkgs.yubikey-personalization ]; extraRules = lib.mkIf cfg.unplug.enable '' ACTION=="remove",\ ENV{DEVTYPE}=="usb_device",\ ENV{PRODUCT}=="1050/${cfg.unplug.model}/543",\ RUN+="${cfg.unplug.command}" ''; }; }; }