2f4f4257a3
The gpg-agent systemd Environment=INSIDE_EMACS=1 hack never worked:
gpg-agent calls gnupg_unsetenv("INSIDE_EMACS") on itself at startup by
design, expecting the variable per-connection from the client instead.
Move it to home.sessionVariables so git/gpg invocations themselves carry
it and forward it to gpg-agent via "OPTION putenv=...", which is what
actually routes a pinentry request to Emacs instead of failing on
curses with no tty.
Bump azos-core for the project-brain-aligned todo/workplate/work-history
skills and the global org-roam Read/Edit permission rules.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
81 lines
3.1 KiB
Nix
81 lines
3.1 KiB
Nix
{...}: {
|
|
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 needs INSIDE_EMACS set, but NOT on gpg-agent itself:
|
|
# gpg-agent calls gnupg_unsetenv("INSIDE_EMACS") on its own process at
|
|
# startup (agent/gpg-agent.c, both supervised and daemon mode) -- by
|
|
# design, it expects this to arrive per-connection from the CLIENT,
|
|
# not statically from its own daemon environment. Each gpg/git
|
|
# invocation reads INSIDE_EMACS from its own env and forwards it to
|
|
# gpg-agent via "OPTION putenv=INSIDE_EMACS=..." (common/asshelp.c:
|
|
# send_pinentry_environment); gpg-agent stores that per-session and
|
|
# copies it into the forked pinentry's actual env for that one
|
|
# request (agent/call-pinentry.c:atfork_core). So the var has to be
|
|
# set on whatever shell/process runs git or gpg -- a prior attempt
|
|
# at this set it on gpg-agent.service's systemd Environment instead,
|
|
# which gpg-agent silently discards before it can ever be read.
|
|
#
|
|
# Only safe to set globally 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).
|
|
home.sessionVariables = lib.mkIf config.azos.suites.exwm.enable {
|
|
INSIDE_EMACS = "t";
|
|
};
|
|
|
|
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"
|
|
'';
|
|
};
|
|
};
|
|
}
|