{ lib, pkgs, config, secretsPath, ... }: let inherit (builtins) mapAttrs; inherit (lib) mkMerge mkIf mkDefault; inherit (lib.my) mkOpt'; cfg = config.my.secrets; in { options.my.secrets = with lib.types; { vmKeyPath = mkOpt' str "/tmp/xchg/dev.key" "Path to dev key when in a dev VM."; key = mkOpt' (nullOr str) null "Public key that secrets for this system should be encrypted for."; files = mkOpt' (attrsOf unspecified) { } "Secrets to decrypt with agenix."; }; config = mkMerge [ { age = { secretsDir = mkDefault "/run/secrets"; secrets = mapAttrs (f: opts: { file = "${secretsPath}/${f}.age"; } // opts) cfg.files; # agenix sets this as a default but adding any custom extras will _replace_ the list (different priority) identityPaths = mkIf config.services.openssh.enable (map # Use the persit dir to grab the keys instead, otherwise they might not be ready. We can't really make # agenix depend on impermanence, since users depends on agenix (to decrypt passwords) and impermanence # depends on users (e: let pDir = config.my.tmproot.persistence.dir; in if pDir != null then "${pDir}${e.path}" else e.path) (lib.filter (e: e.type == "rsa" || e.type == "ed25519") config.services.openssh.hostKeys)); }; } (mkIf config.my.build.isDevVM { age.identityPaths = [ cfg.vmKeyPath ]; }) ]; }