{ config, inputs, lib, pkgs, this, ... }: let cfg = config.nixfiles.modules.yubikey; in { options.nixfiles.modules.yubikey = { enable = lib.mkEnableOption "Yubikey support"; serials = lib.mkOption { type = with lib.types; listOf str; default = [ ]; description = "List of YubiKey device serials."; }; }; config = lib.mkIf cfg.enable ( lib.mkMerge [ { security.pam = { rssh = { enable = true; settings.cue = true; }; services.sudo.rssh = true; }; } (lib.mkIf this.isHeadful { secrets.u2f.file = "${inputs.self}/secrets/u2f"; hm = { home.packages = with pkgs; [ yubikey-manager yubioath-flutter ]; programs = { git.extraConfig = { gpg = { format = "ssh"; ssh = { # https://git-scm.com/docs/git-config#Documentation/git-config.txt-usersigningKey defaultKeyCommand = pkgs.writeShellScript "default-key-command" '' key="$(ssh-add -L | head -n 1 | cut -d ' ' -f 1-2)" printf 'key::%s\n' "$key" '' |> toString; # https://man7.org/linux/man-pages/man1/ssh-keygen.1.html#ALLOWED_SIGNERS allowedSignersFile = config.my.openssh.authorizedKeys.keys |> map (x: x |> lib.splitString " " |> lib.take 2 |> lib.concatStringsSep " ") |> map (x: ''${lib.my.email} namespaces="git" ${x}'') |> lib.concatLines |> pkgs.writeText "allowed-signers-file" |> toString; }; }; commit.gpgSign = true; tag.gpgSign = true; }; # https://wiki.archlinux.org/title/YubiKey#gpg:_no_such_device gpg.scdaemonSettings = { disable-ccid = true; pcsc-shared = true; }; }; services = { gpg-agent.enableScDaemon = true; ssh-agent.enable = false; }; }; programs.yubikey-touch-detector.enable = true; # NOTE: This needs setting up with `yubikey-agent -setup`[1]. For # firmware version 7.2+ see these issues[2] in case of an error. # # [1]: https://filippo.io/yubikey-agent # [2]: https://github.com/FiloSottile/yubikey-agent/issues/153 # [2]: https://github.com/sigstore/cosign/issues/3742 # # ``` # yubikey-agent -setup # ``` services.yubikey-agent.enable = true; # NOTE: This also needs setting up[1]. # # [1]: https://developers.yubico.com/pam-u2f/ security.pam.u2f = { enable = true; settings = { origin = "pam://nixos"; appid = "pam://nixos"; authfile = config.secrets.u2f.path; cue = true; }; }; }) ] ); }