{ lib, ... }: let attr = "_secret"; isSecret = v: lib.isAttrs v && v ? _secret && (lib.isString v._secret || builtins.isPath v._secret); in { inherit isSecret; replaceSecrets = unitName: set: let # Sanitize path to create a valid credential tag sanitizePath = path: lib.stringAsChars (c: if builtins.match "[a-zA-Z0-9_.#=!-]" c != null then c else "_") path; credentialTag = path: sanitizePath (lib.concatStringsSep "_" path); credentialPath = path: "/run/credentials/${unitName}/${credentialTag path}"; in { output = lib.mapAttrsRecursiveCond (as: !(isSecret as)) ( path: value: if (builtins.isAttrs value) then (credentialPath path) else value ) set; credentials = lib.filter (elem: elem != null) ( lib.mapAttrsToListRecursiveCond (path: as: !(isSecret as)) ( path: value: if (builtins.isAttrs value) then "${credentialTag path}:${value."${attr}"}" else null ) set ); }; }