{...}: { config.flake.modules.homeManager.encryption = { lib, config, pkgs, ... }: { options.azos.encryption.enable = lib.mkOption { default = true; type = lib.types.bool; }; config = lib.mkIf config.azos.encryption.enable { programs.password-store = { enable = true; settings = { PASSWORD_STORE_KEY = "26B851F81F8F7C55"; }; }; home.packages = with pkgs; [ yubikey-personalization ]; programs.gpg = { enable = true; }; programs.browserpass = { enable = true; browsers = ["chromium"]; }; services.gpg-agent = { enable = true; enableSshSupport = true; grabKeyboardAndMouse = false; pinentry.package = pkgs.pinentry-emacs; extraConfig = '' allow-emacs-pinentry allow-loopback-pinentry ''; }; # pinentry-emacs only attempts its Emacs-loopback socket when ITS OWN # process env has INSIDE_EMACS set (see pinentry-emacs.c) -- and that # process is gpg-agent's child, so it inherits gpg-agent's daemon env, # not the env of whichever client (git, pass, ...) asked it to sign. # Without this, any signing request from outside Emacs (e.g. a plain # terminal, or an agent shelling out to git) always falls through to # the curses pinentry, which fails outright when there's no real tty. # # Only safe to force on when Emacs is structurally guaranteed to be # up and responsive -- i.e. under EXWM, where Emacs *is* the window # manager. Elsewhere Emacs may not be running (fine: the loopback # socket connect fails instantly, same fast fallback as today) or may # be running but transiently busy (not fine: pinentry then blocks on # the Assuan handshake for up to its 60s timeout before falling back, # which is strictly worse than today's instant failure). systemd.user.services.gpg-agent.Service.Environment = lib.mkIf config.azos.suites.exwm.enable ["INSIDE_EMACS=1"]; home.file.".ssh/config".source = ./ssh-config; home.file.".ssh/gpg-as-ssh.pub".source = ./gpg-as-ssh.pub; home.file.".gnupg/sshcontrol".source = ./sshcontrol; # home-manager creates ~/.gnupg (via the files above) with the default # umask, which can leave it group/other-readable. gpg refuses to trust # a homedir like that and prints an "unsafe permissions" warning on # every invocation, which pollutes anything that captures gpg/pass # output (e.g. shell-command-to-string). Enforce 700 on every switch. home.activation.gnupgPerms = lib.hm.dag.entryAfter ["writeBoundary"] '' $DRY_RUN_CMD chmod 700 "$HOME/.gnupg" ''; }; }; }