diff --git a/nix-darwin/home/common.nix b/nix-darwin/home/common.nix index a337e7f1..6c9bb177 100644 --- a/nix-darwin/home/common.nix +++ b/nix-darwin/home/common.nix @@ -1,5 +1,6 @@ { config, + inputs, libDir, lib, pkgs, @@ -7,6 +8,53 @@ }: let dotfilesDir = builtins.dirOf (toString libDir); outOfStore = config.lib.file.mkOutOfStoreSymlink; + replaceRuntimeDir = builtins.replaceStrings ["$XDG_RUNTIME_DIR"] ["\${XDG_RUNTIME_DIR}"]; + gpgKeyPath = replaceRuntimeDir config.age.secrets.gpg-keys.path; + gpgPassphrasePath = replaceRuntimeDir config.age.secrets.gpg-passphrase.path; + importGpgKeyScript = pkgs.writeShellScript "import-gpg-key" '' + set -eu + + key_path=${gpgKeyPath} + passphrase_path=${gpgPassphrasePath} + + attempts=0 + while [ "$attempts" -lt 30 ]; do + if [ -r "$key_path" ] && [ -r "$passphrase_path" ]; then + break + fi + attempts=$((attempts + 1)) + sleep 1 + done + + if [ ! -r "$key_path" ] || [ ! -r "$passphrase_path" ]; then + echo "Timed out waiting for agenix GPG secrets" >&2 + exit 1 + fi + + normalized_key_file="$(mktemp)" + trap 'rm -f "$normalized_key_file"' EXIT + + # Some historical exports omitted the required blank line after the + # armor header. GnuPG imports the keys but exits non-zero in that case. + awk ' + pending_blank { + if ($0 != "") { + print "" + } + pending_blank = 0 + } + { print } + /^-----BEGIN PGP PRIVATE KEY BLOCK-----$/ { + pending_blank = 1 + } + ' "$key_path" > "$normalized_key_file" + + exec ${pkgs.gnupg}/bin/gpg \ + --batch \ + --pinentry-mode loopback \ + --passphrase-file "$passphrase_path" \ + --import "$normalized_key_file" + ''; excludedTopLevelEntries = [ "agents" @@ -40,6 +88,11 @@ in { programs.home-manager.enable = true; + imports = [inputs.agenix.homeManagerModules.default]; + + age.identityPaths = ["${config.home.homeDirectory}/.ssh/id_ed25519"]; + age.secrets.gpg-keys.file = ../../nixos/secrets/gpg-keys.age; + age.secrets.gpg-passphrase.file = ../../nixos/secrets/gpg-passphrase.age; home.file = dotfilesLinks; home.activation.linkEmacsDotdir = lib.hm.dag.entryAfter ["writeBoundary"] '' @@ -96,6 +149,21 @@ in { ''; }; + launchd.agents.import-gpg-key = { + enable = true; + config = { + ProgramArguments = ["${importGpgKeyScript}"]; + KeepAlive = { + Crashed = false; + SuccessfulExit = false; + }; + ProcessType = "Background"; + RunAtLoad = true; + StandardOutPath = "${config.home.homeDirectory}/Library/Logs/import-gpg-key.log"; + StandardErrorPath = "${config.home.homeDirectory}/Library/Logs/import-gpg-key.err.log"; + }; + }; + programs.starship = { enable = true; };