{ lib, pkgs, config, ... }: let cfg = config.services.docuseal; env = { RAILS_ENV = "production"; NODE_ENV = "production"; WORKDIR = "/var/lib/docuseal"; PORT = toString (cfg.port); HOST = cfg.host; REDIS_URL = "redis://${cfg.redis.host}:${toString cfg.redis.port}"; } // cfg.extraConfig; in { options.services.docuseal = { enable = lib.mkEnableOption "DocuSeal, open source document signing"; package = lib.mkPackageOption pkgs "docuseal" { }; secretKeyBaseFile = lib.mkOption { description = '' Path to file containing the secret key base. A new secret key base can be generated by running: `openssl rand -hex 64` If this file does not exist, it will be created with a new secret key base. ''; default = "/var/lib/docuseal/secrets/secret-key-base"; type = lib.types.path; }; host = lib.mkOption { description = "DocuSeal host."; type = lib.types.str; default = "127.0.0.1"; }; port = lib.mkOption { description = "DocuSeal port."; type = lib.types.port; default = 3000; }; extraConfig = lib.mkOption { type = lib.types.attrs; default = { }; description = '' Extra environment variables to pass to DocuSeal services. ''; }; extraEnvFiles = lib.mkOption { type = with lib.types; listOf path; default = [ ]; description = '' Extra environment files to pass to DocuSeal services. Useful for passing down environmental secrets. e.g. DATABASE_URL ''; example = [ "/etc/docuseal/s3config.env" ]; }; redis = { createLocally = lib.mkOption { type = lib.types.bool; default = true; description = "Whether to create a local redis automatically."; }; name = lib.mkOption { type = lib.types.str; default = "docuseal"; description = '' Name of the redis server. Only used if `createLocally` is set to true. ''; }; host = lib.mkOption { type = lib.types.str; default = "localhost"; description = '' Redis server address. ''; }; port = lib.mkOption { type = lib.types.port; default = 6379; description = "Port of the redis server."; }; }; }; config = lib.mkIf cfg.enable { assertions = [ { assertion = cfg.redis.createLocally -> cfg.redis.host == "localhost"; message = "the redis host must be localhost if services.docuseal.redis.createLocally is set to true"; } ]; systemd.services.docuseal = { description = "DocuSeal server"; wantedBy = [ "multi-user.target" ]; environment = env; serviceConfig = { Type = "simple"; ExecStartPre = pkgs.writeShellScript "docuseal-pre-script" '' cat > /var/lib/docuseal/docuseal.env <= 1024); ProtectClock = true; ProtectHostname = true; ProtectKernelLogs = true; ProtectKernelModules = true; ProtectKernelTunables = true; ProtectControlGroups = true; RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" "AF_NETLINK" ]; RestrictNamespaces = true; LockPersonality = true; MemoryDenyWriteExecute = false; RestrictRealtime = true; RestrictSUIDSGID = true; RemoveIPC = true; PrivateMounts = true; # System Call Filtering SystemCallArchitectures = "native"; } // lib.optionalAttrs (cfg.port < 1024) { AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ]; CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ]; }; }; services.redis = lib.optionalAttrs cfg.redis.createLocally { servers."${cfg.redis.name}" = { enable = true; port = cfg.redis.port; }; }; }; meta.maintainers = with lib.maintainers; [ stunkymonkey ]; }