This commit is contained in:
RingOfStorms (Joshua Bell) 2026-01-06 20:39:27 -06:00
commit dea716f862
2 changed files with 97 additions and 47 deletions

View file

@ -428,10 +428,16 @@ in
description = "Field under .Data.data to render.";
};
dependencies = lib.mkOption {
softDepend = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
description = "Systemd service names to restart after this secret is rendered.";
description = "Systemd service names to try-restart when this secret changes (does not block startup).";
};
hardDepend = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
description = "Systemd service names that should only start when this secret exists; started when the secret changes.";
};
configChanges = lib.mkOption {
@ -482,11 +488,56 @@ in
"d /run/secrets 0711 root root - -"
];
systemd.paths = lib.mapAttrs' (
name: secret:
lib.nameValuePair "openbao-secret-${name}" {
description = "Path unit for OpenBao secret ${name}";
wantedBy = [ "multi-user.target" ];
pathConfig = {
PathChanged = secret.path;
PathExists = secret.path;
Unit = "openbao-secret-changed-${name}.service";
};
}
) cfg.secrets;
systemd.services = lib.mkMerge [
(
lib.mkMerge (
lib.concatLists (
lib.mapAttrsToList (
secretName: secret:
map (
svc:
{
systemd.services.${svc} = {
unitConfig.ConditionPathExists = secret.path;
wants = lib.mkAfter [ "openbao-secret-${secretName}.path" ];
after = lib.mkAfter [ "openbao-secret-${secretName}.path" ];
};
}
) secret.hardDepend
) cfg.secrets
)
)
)
{
systemd.timers.zitadel-mint-jwt = {
description = "Refresh Zitadel JWT for OpenBao";
wantedBy = [ "timers.target" ];
timerConfig = {
OnBootSec = "30s";
OnUnitActiveSec = "2m";
Unit = "zitadel-mint-jwt.service";
};
};
zitadel-mint-jwt = {
description = "Mint Zitadel access token (JWT) for OpenBao";
wantedBy = [ "multi-user.target" ];
after = [
"network-online.target"
"nss-lookup.target"
@ -595,7 +646,6 @@ in
wantedBy = [ "multi-user.target" ];
after = [
"network-online.target"
"zitadel-mint-jwt.service"
];
wants = [
"network-online.target"
@ -617,47 +667,47 @@ in
(lib.mapAttrs' (
name: secret:
lib.nameValuePair "openbao-secret-${name}" {
description = "Wait for OpenBao secret ${name}";
lib.nameValuePair "openbao-secret-changed-${name}" {
description = "React to OpenBao secret ${name} changes";
wants = [ "vault-agent.service" ];
after = [ "vault-agent.service" ];
requires = [ "vault-agent.service" ];
wantedBy = map (svc: "${svc}.service") secret.dependencies;
startLimitIntervalSec = 300;
startLimitBurst = 3;
startLimitBurst = 6;
serviceConfig = {
Type = "oneshot";
User = "root";
Group = "root";
UMask = "0077";
ExecStart = pkgs.writeShellScript "openbao-wait-secret-${name}" ''
ExecStart = pkgs.writeShellScript "openbao-secret-changed-${name}" ''
#!/usr/bin/env bash
set -euo pipefail
p=${lib.escapeShellArg secret.path}
for i in {1..60}; do
if [ -s "$p" ]; then
break
fi
sleep 1
done
if [ ! -s "$p" ]; then
echo "Secret file not rendered: $p" >&2
exit 1
echo "Secret not present (skipping): $p" >&2
exit 0
fi
${lib.concatStringsSep "\n" (
map (svc: ''
echo "Restarting ${svc} due to secret ${name}" >&2
echo "Trying restart of ${svc} due to secret ${name}" >&2
systemctl try-restart ${lib.escapeShellArg (svc + ".service")} || true
'') secret.dependencies
'') secret.softDepend
)}
${lib.concatStringsSep "\n" (
map (svc: ''
echo "Starting ${svc} due to secret ${name}" >&2
systemctl start ${lib.escapeShellArg (svc + ".service")} || true
'') secret.hardDepend
)}
'';
};
}
) cfg.secrets)
];
}
]

View file

@ -121,13 +121,14 @@
secrets = {
headscale_auth = {
kvPath = "kv/data/machines/home_roaming/headscale_auth";
dependencies = [ "tailscaled" ];
softDepend = [ "tailscaled" ];
configChanges.services.tailscale.authKeyFile = "$SECRET_PATH";
};
"atuin-key-josh" = {
owner = "josh";
group = "users";
mode = "0400";
hardDepend = [ "atuin-autologin" ];
template = ''{{- with secret "kv/data/machines/home_roaming/atuin-key-josh" -}}{{ printf "%s\n%s\n%s" .Data.data.user .Data.data.password .Data.data.value }}{{- end -}}'';
};
nix2github = {
@ -305,9 +306,8 @@
systemd.services.atuin-autologin = {
description = "Auto-login to Atuin (if logged out)";
wantedBy = [ "multi-user.target" ];
after = [ "network-online.target" "openbao-secret-atuin-key-josh.service" ];
wants = [ "network-online.target" "openbao-secret-atuin-key-josh.service" ];
requires = [ "openbao-secret-atuin-key-josh.service" ];
after = [ "network-online.target" ];
wants = [ "network-online.target" ];
serviceConfig = {
Type = "oneshot";
@ -337,9 +337,9 @@
exit 1
fi
username="$(${pkgs.coreutils}/bin/sed -n '1p' "$secret")"
password="$(${pkgs.coreutils}/bin/sed -n '2p' "$secret")"
key="$(${pkgs.coreutils}/bin/sed -n '3p' "$secret")"
username="$(${pkgs.gnused}/bin/sed -n '1p' "$secret")"
password="$(${pkgs.gnused}/bin/sed -n '2p' "$secret")"
key="$(${pkgs.gnused}/bin/sed -n '3p' "$secret")"
exec ${pkgs.atuin}/bin/atuin login --username "$username" --password "$password" --key "$key"
'';