{ config , lib , pkgs , ... }: let cfg = config.services.openbao; settingsFormat = pkgs.formats.json { }; autoAuthMethodModule = lib.types.submodule { freeformType = lib.types.attrsOf lib.types.unspecified; options = { type = lib.mkOption { type = lib.types.str; }; config = lib.mkOption { type = lib.types.attrsOf lib.types.unspecified; }; }; }; autoAuthModule = lib.types.submodule { freeformType = lib.types.attrsOf lib.types.unspecified; options = { method = lib.mkOption { type = lib.types.listOf autoAuthMethodModule; default = [ ]; }; }; }; templateConfigModule = lib.types.submodule { freeformType = lib.types.attrsOf lib.types.unspecified; options = { exit_on_retry_failure = lib.mkOption { type = lib.types.bool; default = true; }; }; }; agentConfigType = lib.types.submodule { freeformType = lib.types.attrsOf lib.types.unspecified; options = { auto_auth = lib.mkOption { type = autoAuthModule; default = { }; }; template_config = lib.mkOption { type = templateConfigModule; default = { }; }; }; }; in { options.services.openbao.agents = lib.mkOption { default = { }; description = "Instances of openbao agent"; type = lib.types.attrsOf (lib.types.submodule { options = { settings = lib.mkOption { description = "agent configuration"; type = agentConfigType; }; }; }); }; config = { systemd.services = lib.mapAttrs' (name: instanceCfg: lib.nameValuePair "openbao-agent-${name}" { after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; # Services that also have `stopIfChanged = false` might wait for secrets # while `vault-agent` is still stopped. This for example happens with nginx.service. stopIfChanged = false; # Needs getent and systemctl in PATH path = [ pkgs.getent pkgs.systemd ]; serviceConfig = { Restart = "on-failure"; # TODO: cfg.package ExecStart = "${lib.getExe pkgs.openbao} agent -config=${settingsFormat.generate "agent.json" instanceCfg.settings}"; }; }) cfg.agents; }; }