# SSH + GPG agent — one agent for everything. # # gpg-agent fronts SSH (enableSshSupport), so a single pinentry handles # every passphrase: GPG signing/decryption and SSH key unlocks alike. SSH # keys are added with `ssh-add` (gpg-agent stores them by keygrip). # # Pinentry is pinentry-qt — reliable native-Wayland under Hyprland (no # GNOME session to lean on) and themed by Stylix's Qt config, so the # passphrase dialog tracks the palette. # # SSH_AUTH_SOCK reaches both terminal and GUI clients: the agent's zsh # integration sets it in interactive shells (home.shell.enableZshIntegration # in shell.nix), and a session-level home.sessionVariables export (below) # covers GUI clients launched outside a shell — e.g. from the rofi launcher — # which never inherit the interactive shell's copy. Both resolve the same # socket via gpgconf, so they can't drift. # # gnome-keyring (system side) stays the Secret Service for application # secrets; modern gnome-keyring no longer runs an SSH agent, so there is no # SSH_AUTH_SOCK contention with gpg-agent. Screen lock (hyprlock/hypridle) # doesn't flush the agent cache — unlocked keys persist across a lock, as # expected; the cache TTLs below govern re-prompting instead. { config, lib, pkgs, ... }: let cfg = config.nomarchy; in { config = lib.mkIf cfg.keys.enable { programs.gpg.enable = true; services.gpg-agent = { enable = true; enableSshSupport = true; pinentry.package = pkgs.pinentry-qt; # Cache unlocked keys for a working session, then re-prompt. defaultCacheTtl = 1800; # 30 min since last use maxCacheTtl = 7200; # 2 h hard cap defaultCacheTtlSsh = 1800; maxCacheTtlSsh = 7200; }; # Session-level SSH_AUTH_SOCK so GUI clients launched outside a shell # (rofi launcher, autostarted apps) reach the agent — the shell # integration only covers interactive shells. Resolved with gpgconf at # session-init time (the same lookup the shell integration uses), so it # tracks the agent's real socket rather than a hardcoded path; valid # before first use since the socket is systemd-activated. Reaches GUI # apps the way NIXOS_OZONE_WL does — sourced into the login shell that # starts Hyprland, so every spawned client inherits it. home.sessionVariables.SSH_AUTH_SOCK = "$(${pkgs.gnupg}/bin/gpgconf --list-dirs agent-ssh-socket)"; }; }