From 357d69f4ce7da70e746c465c8fa32c8d6dbe815e Mon Sep 17 00:00:00 2001 From: Arpit Chakladar Date: Wed, 29 Jul 2026 23:36:51 +0530 Subject: feat(ssh): lazy-loading ssh keys from gopass - Loading ssh keys from gopass only when ssh command runs for the first time --- modules/security/gopass/default.nix | 97 ++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 49 deletions(-) (limited to 'modules/security/gopass/default.nix') diff --git a/modules/security/gopass/default.nix b/modules/security/gopass/default.nix index 23692bf..d6848d8 100644 --- a/modules/security/gopass/default.nix +++ b/modules/security/gopass/default.nix @@ -5,6 +5,43 @@ pkgs, ... }: +let + gopass-ssh-load = pkgs.writeShellScriptBin "gopass-ssh-load" '' + export SSH_AUTH_SOCK="$(${pkgs.gnupg}/bin/gpgconf --list-dirs agent-ssh-socket)" + + if [ -z "$SSH_AUTH_SOCK" ] || [ ! -S "$SSH_AUTH_SOCK" ]; then + echo "Error: SSH_AUTH_SOCK is not set or valid." >&2 + exit 1 + fi + + if ${pkgs.openssh}/bin/ssh-add -l 2>/dev/null | grep -qE "(ED25519|RSA|ECDSA)"; then + exit 0 + fi + + for key in github gitlab bitbucket codeberg sourcehut; do + if ${config.security.gopass.package}/bin/gopass cat "ssh/$key" > /dev/null 2>&1; then + tmpdir=$(mktemp -d) + keyfile="$tmpdir/key" + ${config.security.gopass.package}/bin/gopass cat "ssh/$key" > "$keyfile" 2>/dev/null + chmod 600 "$keyfile" + + if ! ${pkgs.openssh}/bin/ssh-add "$keyfile" 2>/dev/null; then + passphrase=$(${config.security.gopass.package}/bin/gopass cat "ssh/$key/passphrase" 2>/dev/null) + if [ -n "$passphrase" ]; then + tmpcopy=$(mktemp) + cp "$keyfile" "$tmpcopy" + chmod 600 "$tmpcopy" + if ${pkgs.openssh}/bin/ssh-keygen -p -P "$passphrase" -N "" -f "$tmpcopy" 2>/dev/null; then + ${pkgs.openssh}/bin/ssh-add "$tmpcopy" 2>/dev/null + fi + rm -f "$tmpcopy" + fi + fi + rm -rf "$tmpdir" + fi + done + ''; +in { options.security.gopass = { enable = lib.mkEnableOption "Enables gopass."; @@ -16,9 +53,16 @@ }; ssh-agent = { enable = lib.mkEnableOption "gopass-backed SSH keys for git"; + script = lib.mkOption { + type = lib.types.package; + description = "The package containing the gopass-ssh-load script."; + }; }; }; + config = lib.mkIf config.security.gopass.enable { + security.gopass.ssh-agent.script = gopass-ssh-load; + programs.password-store = { enable = true; package = config.security.gopass.package; @@ -26,58 +70,13 @@ PASSWORD_STORE_DIR = "${config.home.homeDirectory}/.local/share/pass"; }; }; + home.sessionVariables = { PASSWORD_STORE_DIR = config.programs.password-store.settings.PASSWORD_STORE_DIR; }; - systemd.user.services.gopass-ssh-load = lib.mkIf config.security.gopass.ssh-agent.enable { - Unit = { - Description = "Load SSH keys from gopass into SSH agent for git"; - After = [ - "gpg-agent.socket" - "graphical-session.target" - ]; - Requires = [ - "gpg-agent.socket" - ]; - PartOf = [ - "graphical-session.target" - ]; - }; - Service = { - Type = "oneshot"; - ExecStart = "${pkgs.writeShellScript "gopass-ssh-load" '' - export SSH_AUTH_SOCK="$(${pkgs.gnupg}/bin/gpgconf --list-dirs agent-ssh-socket)" - - if [ -z "$SSH_AUTH_SOCK" ] || [ ! -S "$SSH_AUTH_SOCK" ]; then - exit 1 - fi - for key in github gitlab bitbucket codeberg sourcehut; do - if ${config.security.gopass.package}/bin/gopass cat "ssh/$key" > /dev/null 2>&1; then - tmpdir=$(mktemp -d) - keyfile="$tmpdir/key" - ${config.security.gopass.package}/bin/gopass cat "ssh/$key" > "$keyfile" 2>/dev/null - chmod 600 "$keyfile" - if ! ${pkgs.openssh}/bin/ssh-add "$keyfile" 2>/dev/null; then - passphrase=$(${config.security.gopass.package}/bin/gopass cat "ssh/$key/passphrase" 2>/dev/null) - if [ -n "$passphrase" ]; then - tmpcopy=$(mktemp) - cp "$keyfile" "$tmpcopy" - chmod 600 "$tmpcopy" - if ${pkgs.openssh}/bin/ssh-keygen -p -P "$passphrase" -N "" -f "$tmpcopy" 2>/dev/null; then - ${pkgs.openssh}/bin/ssh-add "$tmpcopy" 2>/dev/null - fi - rm -f "$tmpcopy" - fi - fi - rm -rf "$tmpdir" - fi - done - ''}"; - }; - Install = { - WantedBy = [ "graphical-session.target" ]; - }; - }; + home.packages = lib.mkIf config.security.gopass.ssh-agent.enable [ + config.security.gopass.ssh-agent.script + ]; }; } -- cgit v1.2.3