The agent's SSH socket was only exported via the zsh integration, so a GUI client launched outside a shell (rofi launcher, autostarted apps) couldn't use gpg-agent for SSH. Add a home.sessionVariables export resolving the socket with gpgconf --list-dirs agent-ssh-socket — the same lookup the shell integration uses, so the two can't drift — which reaches GUI apps via the login shell that starts Hyprland (the path NIXOS_OZONE_WL already takes). Eval-verified: the var resolves to the gpgconf substitution; the home config still builds. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
56 lines
2.4 KiB
Nix
56 lines
2.4 KiB
Nix
# 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)";
|
|
};
|
|
}
|