{ lib, config, hostName, ... }:
with lib;
{
  options = {
    security.initrd = {
      secrets = lib.mkOption {
        type = types.attrsOf types.str;
        default = { };
        description = ''
          Map some secrets for the initrd.
        '';
      };
      install = lib.mkOption {
        type = types.str;
        default = "";
        description = ''
          Script to decrypt and send some secrets for the initrd.
        '';
      };
      stage1Dir = lib.mkOption {
        type = types.str;
        default = "/run/initrd-secrets";
        description = ''
          Where to store the secrets in the stage1
          for `boot.initrd.secrets` to install them in the initrd.
        '';
      };
      # Alas, nixos/modules/system/boot/initrd-ssh.nix
      # forces stage2Dir == stage1Dir
      stage2Dir = lib.mkOption {
        type = types.str;
        default = "/run/initrd-secrets";
        description = ''
          Where to store the secrets in the stage2
          for `boot.initrd.secrets` to retrieve them when rebuilding the system.
        '';
      };
    };
  };
  config = {
    security.initrd.install =
      lib.concatStringsSep "\n" (lib.mapAttrsToList
        (dst: src: ''
          gpg --decrypt "${src}" |
          ssh "${config.install.target}" \
            install -D -m 400 -o root -g root /dev/stdin "${config.security.initrd.stage2Dir}/${dst}"
        '')
        config.security.initrd.secrets
      );
    boot.initrd.secrets = mapAttrs'
      (dst: src:
        nameValuePair
          "${config.security.initrd.stage1Dir}/${dst}"
          "${config.security.initrd.stage2Dir}/${dst}"
      )
      config.security.initrd.secrets;
  };
}