{ config, pkgs, lib, ... }: let types = lib.types; cfg = config.localsecrets; keyOpts = {name, ...}: { options = { generator = lib.mkOption { type = types.either types.str types.path; default = ""; }; privateDir = lib.mkOption { type = types.str; default = "/var/lib/${cfg.stateDir}/private/${name}"; }; publicDir = lib.mkOption { type = types.str; default = "/var/lib/${cfg.stateDir}/public/${name}"; }; mode = lib.mkOption { type = types.str; default = "0700"; }; user = lib.mkOption { type = types.str; default = "root"; }; group = lib.mkOption { type = types.str; default = "root"; }; }; }; in { options = { localsecrets = { enable = lib.mkEnableOption "Deploy localsecrets"; stateDir = lib.mkOption { type = types.str; default = "localsecrets"; }; secrets = lib.mkOption { type = types.attrsOf (types.submodule keyOpts); default = []; }; }; }; config = lib.mkIf cfg.enable { systemd.services.localsecrets-generate = { description = "Generate local secrets"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; serviceConfig = { StateDirectory = cfg.stateDir; }; script = '' umask 0022 mkdir -p $STATE_DIRECTORY/private mkdir -p $STATE_DIRECTORY/public '' + (lib.concatStringsSep "\n" (lib.mapAttrsToList (name: secret: let runtimeDirectory="secret-${name}"; in '' systemd-run \ --wait \ -p DynamicUser=true \ -p RuntimeDirectory=${runtimeDirectory} \ -p RuntimeDirectoryMode=${secret.mode} \ -p RuntimeDirectoryPreserve=true \ -p WorkingDirectory=/run/${runtimeDirectory} \ -p PrivateTmp=true \ ${pkgs.bash}/bin/bash -c '${secret.generator}' rm -rf "${secret.privateDir}" || true chown "${secret.user}:${secret.group}" "/run/${runtimeDirectory}/private" chmod "${secret.mode}" "/run/${runtimeDirectory}/private" mv "/run/${runtimeDirectory}/private" "${secret.privateDir}" rm -rf "${secret.publicDir}" || true mv "/run/${runtimeDirectory}/public" "${secret.publicDir}" '') cfg.secrets)); }; }; }