oignon: nftables: open 8776 for radicle-node
[julm/julm-nix.git] / nixos / modules / security / systemd-creds.nix
index 60e6fd06452e4437257113ad0f3f76db771239ed..d1d0d50163f5c9ec84efccb27ad07cc28f7056a6 100644 (file)
@@ -1,5 +1,4 @@
 { pkgs, lib, config, ... }:
-with builtins;
 with lib;
 let cfg = config.security.systemd-creds; in
 {
@@ -19,7 +18,7 @@ let cfg = config.security.systemd-creds; in
       description = mdDoc ''
         Command to get the cleartext of a credential.
         `credBase` is derived from the path of the credential in `LoadCredentialEncrypted=`,
-        by removing the `storeDir` prefix and then one directory level.
+        by removing the `builtins.storeDir` prefix and then one directory level.
       '';
       apply = concatStringsSep " ";
       default = [ "gpg" "--batch" "--decrypt" "\${credBase%.cred}.gpg" ];
@@ -75,13 +74,15 @@ let cfg = config.security.systemd-creds; in
       '';
       default = [ "install" "-D" "-m" "640" "/dev/stdin" "\"$credBase\"" ];
     };
-    script = mkOption {
+    reencrypt = mkOption {
       type = types.lines;
       apply = pkgs.writeShellScriptBin "systemd-creds-encrypt-${replaceStrings ["@"] ["-"] cfg.target}";
       description = mdDoc ''
         Encrypt credentials referenced in the `LoadCredentialEncrypted=`
         of enabled systemd services, by running `systemd-creds` on the {option}`security.systemd-creds.target` host.
-        Only *non-existing* credential files are considered.
+        Only *non-existing* credential files are considered,
+        unless the `SYSTEMD_CREDS_FORCE_REENCRYPT` envvar is set to a non-empty value.
+        Credential directories are not supported.
 
         Example of use:
         ```console
@@ -90,19 +91,31 @@ let cfg = config.security.systemd-creds; in
         ```
 
         ```nix
+        { config, pkgs, lib, inputs, ... }:
+        {
         systemd.services."wireguard-wg-intra".serviceConfig.LoadCredentialEncrypted =
           [ "privateKey:''${inputs.self}/wireguard/wg-intra/privateKey.cred" ];
+        }
         ```
 
         ```console
-        $ nix run .#nixosConfigurations.''${hostName}.config.security.systemd-creds.script
+        $ nix run .#nixosConfigurations.''${hostName}.config.security.systemd-creds.reencrypt
         $ git add wireguard/wg-intra/privateKey.cred
         ```
+
+        ::: {.warning}
+        To be able to access the relative path of the `.cred` file,
+        `inputs.self` has to be used in `LoadCredentialEncrypted=`.
+        Note that `inputs` is a `config._module.args` or `specialArgs`
+        usually set in your `flake.nix`.
+        In other words, using `''${wireguard/wg-intra/privatekey}` here,
+        would not work, because it drops the `wireguard/wg-intra/` part.
+        :::
       '';
     };
   };
   config = {
-    security.systemd-creds.script = ''
+    security.systemd-creds.reencrypt = ''
       shopt -s extglob globstar nullglob
       set -o pipefail
       set -eux
@@ -118,15 +131,17 @@ let cfg = config.security.systemd-creds; in
             ''
               credID=${escapeShellArg credID}
               credPath=${escapeShellArg credPath}
-              credBase=''${credPath#${storeDir}/*/}
-              if test ! -e "$credBase"; then
+              credBase=''${credPath#${builtins.storeDir}/*/}
+              if test "''${SYSTEMD_CREDS_FORCE_REENCRYPT:+set}" \
+                      -o ! -s "$credBase" \
+                      -o -e "''${credBase%.cred}.gpg" -a "$credBase" -ot "''${credBase%.cred}.gpg"; then
                 { ${cfg.decrypt}; } |
                 { ${cfg.shell} -- ${cfg.encrypt} - -; } |
                 { ${cfg.install}; }
               fi
             ''
           )
-          service.serviceConfig.LoadCredentialEncrypted)
+          (toList service.serviceConfig.LoadCredentialEncrypted))
       (attrValues
         (filterAttrs
           (_serviceName: service: