tvl-depot/ops/modules/irccat.nix
Vincent Ambo b8267c261c fix(ops/irccat): Avoid permissions issue with LoadCredentials=
The DynamicUser + Group configuration does not work as planned, thus
the systemd LoadCredentials feature is used instead which makes the
file (which itself is only readable by root) available in a
memory-backed location only readable by the service.

The secret is only available to `ExecStart` commands, so units using
this feature can not be used with pre/post units and the like if those
commands need secrets.

To accommodate this, the merge of configuration files has been moved
into the service launch script, which is now the ExecStart= process.

For details take a look at https://www.freedesktop.org/software/systemd/man/systemd.exec.html#LoadCredential=ID:PATH

Change-Id: I693fe5677cc0d63c7aa485c2c7472457c5262166
2021-12-10 15:09:09 +00:00

57 lines
1.7 KiB
Nix

{ depot, config, lib, pkgs, ... }:
let
cfg = config.services.depot.irccat;
description = "irccat - forward messages to IRC";
# irccat expects to read its configuration from the *current
# directory*, and its configuration contains secrets.
#
# To make this work we construct the JSON configuration file and
# then recursively merge it with an on-disk secret using jq on
# service launch.
configJson = pkgs.writeText "irccat.json" (builtins.toJSON cfg.config);
mergeAndLaunch = pkgs.writeShellScript "merge-irccat-config" ''
if [ ! -f "$CREDENTIALS_DIRECTORY/secrets" ]; then
echo "irccat secrets file is missing"
exit 1
fi
# jq's * is the recursive merge operator
${pkgs.jq}/bin/jq -s '.[0] * .[1]' ${configJson} "$CREDENTIALS_DIRECTORY/secrets" \
> /var/lib/irccat/irccat.json
exec ${depot.third_party.irccat}/bin/irccat
'';
in {
options.services.depot.irccat = {
enable = lib.mkEnableOption description;
config = lib.mkOption {
type = lib.types.attrs; # varying value types
description = "Configuration structure (unchecked!)";
};
secretsFile = lib.mkOption {
type = lib.types.str;
description = "Path to the secrets file to be merged";
default = "/run/agenix/irccat";
};
};
config = lib.mkIf cfg.enable {
systemd.services.irccat = {
inherit description;
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = "${mergeAndLaunch}";
DynamicUser = true;
StateDirectory = "irccat";
WorkingDirectory = "/var/lib/irccat";
LoadCredential = "secrets:${cfg.secretsFile}";
Restart = "always";
};
};
};
}