about summary refs log tree commit diff
path: root/modules/yubikey.nix
diff options
context:
space:
mode:
authorazahi <azat@bahawi.net>2025-03-12 20:17:13 +0300
committerazahi <azat@bahawi.net>2025-03-12 20:17:13 +0300
commitc81dc5a13b469c511fac6fa2390b70422d1b4da5 (patch)
tree4dab5909006ab5c25da6bd9fde6a714c7719ded7 /modules/yubikey.nix
parent2025-02-17 (diff)
2025-03-12 HEAD master
Diffstat (limited to 'modules/yubikey.nix')
-rw-r--r--modules/yubikey.nix114
1 files changed, 114 insertions, 0 deletions
diff --git a/modules/yubikey.nix b/modules/yubikey.nix
new file mode 100644
index 0000000..6473050
--- /dev/null
+++ b/modules/yubikey.nix
@@ -0,0 +1,114 @@
+{
+  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;
+          };
+        };
+      })
+    ]
+  );
+}

Consider giving Nix/NixOS a try! <3