pinwheel: set ASKPASS
And cache the git signing key
This commit is contained in:
@@ -6,6 +6,38 @@
|
|||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
enabled = config.mod.git.enable;
|
enabled = config.mod.git.enable;
|
||||||
|
|
||||||
|
# Wrapper around `ssh-keygen` used as git's SSH signing program. Before a
|
||||||
|
# signing operation it ensures the passphrase-protected signing key is loaded
|
||||||
|
# into the agent — `ssh-keygen -Y sign` reads the key from disk and re-prompts
|
||||||
|
# every commit otherwise, since `AddKeysToAgent` only ever caches auth keys.
|
||||||
|
# Loading it once (through the GUI askpass) lets later commits reuse the
|
||||||
|
# cached key from the agent. Verification and every other op pass straight
|
||||||
|
# through to the real ssh-keygen untouched.
|
||||||
|
sshSignWrapper = pkgs.writeShellApplication {
|
||||||
|
name = "git-ssh-sign";
|
||||||
|
runtimeInputs = [
|
||||||
|
pkgs.openssh
|
||||||
|
pkgs.gawk
|
||||||
|
pkgs.gnugrep
|
||||||
|
];
|
||||||
|
text = ''
|
||||||
|
key="${config.age.secrets."alex.pinwheel-github.com-signing".path}"
|
||||||
|
|
||||||
|
case " $* " in
|
||||||
|
*" -Y sign "*)
|
||||||
|
fp=""
|
||||||
|
fp="$(ssh-keygen -lf "$key.pub" 2>/dev/null | awk '{print $2}')" || true
|
||||||
|
if [ -n "$fp" ] && ! ssh-add -l 2>/dev/null | grep -qF "$fp"; then
|
||||||
|
# </dev/null detaches stdin so ssh-add uses SSH_ASKPASS (the GUI).
|
||||||
|
ssh-add "$key" </dev/null || true
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exec ssh-keygen "$@"
|
||||||
|
'';
|
||||||
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options = {
|
options = {
|
||||||
@@ -33,6 +65,11 @@ in
|
|||||||
|
|
||||||
# Tells Git to use SSH instead of the default GPG
|
# Tells Git to use SSH instead of the default GPG
|
||||||
gpg.format = "ssh";
|
gpg.format = "ssh";
|
||||||
|
|
||||||
|
# Sign via a wrapper that loads the signing key into the agent on
|
||||||
|
# first use, so subsequent signed commits reuse the cached key
|
||||||
|
# instead of re-prompting for the passphrase every time.
|
||||||
|
gpg.ssh.program = "${sshSignWrapper}/bin/git-ssh-sign";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,20 @@
|
|||||||
components = [ "secrets" ];
|
components = [ "secrets" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
home.sessionVariables = {
|
||||||
|
# gnome-keyring's PAM hooks export SSH_AUTH_SOCK pointing at a dead gcr
|
||||||
|
# socket (gcr-ssh-agent is disabled above), which shadows openssh's own
|
||||||
|
# agent and silently breaks passphrase caching. Force it back to the
|
||||||
|
# openssh agent started by `programs.ssh.startAgent`.
|
||||||
|
SSH_AUTH_SOCK = "$XDG_RUNTIME_DIR/ssh-agent";
|
||||||
|
|
||||||
|
# Route passphrase prompts through seahorse's GUI askpass instead of the
|
||||||
|
# terminal. `prefer` uses the GUI even when a tty is attached (ssh only
|
||||||
|
# falls back to askpass with no controlling terminal otherwise).
|
||||||
|
SSH_ASKPASS = "${pkgs.seahorse}/libexec/seahorse/ssh-askpass";
|
||||||
|
SSH_ASKPASS_REQUIRE = "prefer";
|
||||||
|
};
|
||||||
|
|
||||||
programs.ssh = {
|
programs.ssh = {
|
||||||
enable = true;
|
enable = true;
|
||||||
enableDefaultConfig = false;
|
enableDefaultConfig = false;
|
||||||
|
|||||||
@@ -56,6 +56,14 @@ in
|
|||||||
|
|
||||||
initContent = lib.strings.concatStringsSep "\n" [
|
initContent = lib.strings.concatStringsSep "\n" [
|
||||||
"export KEYTIMEOUT=1"
|
"export KEYTIMEOUT=1"
|
||||||
|
|
||||||
|
# Point every interactive shell at openssh's ssh-agent. home-manager's
|
||||||
|
# session vars set this too, but hm-session-vars runs once and is then
|
||||||
|
# inherited — so a tmux server that outlives this change (or started
|
||||||
|
# with the stale gcr socket) hands new panes a dead SSH_AUTH_SOCK.
|
||||||
|
# Re-exporting the fixed path per-shell keeps every pane on the same
|
||||||
|
# agent, so each key is only ever prompted for once per session.
|
||||||
|
''export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/ssh-agent"''
|
||||||
"bindkey -v '^?' backward-delete-char"
|
"bindkey -v '^?' backward-delete-char"
|
||||||
"bindkey '^a' beginning-of-line"
|
"bindkey '^a' beginning-of-line"
|
||||||
"bindkey '^e' end-of-line"
|
"bindkey '^e' end-of-line"
|
||||||
|
|||||||
Reference in New Issue
Block a user