diff --git a/modules/home-manager/sops.nix b/modules/home-manager/sops.nix index 575c5fc4..ad6fe64f 100644 --- a/modules/home-manager/sops.nix +++ b/modules/home-manager/sops.nix @@ -294,51 +294,34 @@ in }; config = lib.mkIf (cfg.secrets != { }) { - assertions = - [ - { - assertion = - cfg.gnupg.home != null - || cfg.gnupg.sshKeyPaths != [ ] - || cfg.gnupg.qubes-split-gpg.enable == true - || cfg.age.keyFile != null - || cfg.age.sshKeyPaths != [ ]; - message = "No key source configured for sops. Either set services.openssh.enable or set sops.age.keyFile or sops.gnupg.home or sops.gnupg.qubes-split-gpg.enable"; - } - { - assertion = - !(cfg.gnupg.home != null && cfg.gnupg.sshKeyPaths != [ ]) - && !(cfg.gnupg.home != null && cfg.gnupg.qubes-split-gpg.enable == true) - && !(cfg.gnupg.sshKeyPaths != [ ] && cfg.gnupg.qubes-split-gpg.enable == true); - message = "Exactly one of sops.gnupg.home, sops.gnupg.qubes-split-gpg.enable and sops.gnupg.sshKeyPaths must be set"; - } - { - assertion = - cfg.gnupg.qubes-split-gpg.enable == false - || ( - cfg.gnupg.qubes-split-gpg.enable == true - && cfg.gnupg.qubes-split-gpg.domain != null - && cfg.gnupg.qubes-split-gpg.domain != "" - ); - message = "sops.gnupg.qubes-split-gpg.domain is required when sops.gnupg.qubes-split-gpg.enable is set to true"; - } - ] - ++ lib.optionals cfg.validateSopsFiles ( - lib.concatLists ( - lib.mapAttrsToList (name: secret: [ - { - assertion = builtins.pathExists secret.sopsFile; - message = "Cannot find path '${secret.sopsFile}' set in sops.secrets.${lib.strings.escapeNixIdentifier name}.sopsFile"; - } - { - assertion = - builtins.isPath secret.sopsFile - || (builtins.isString secret.sopsFile && lib.hasPrefix builtins.storeDir secret.sopsFile); - message = "'${secret.sopsFile}' is not in the Nix store. Either add it to the Nix store or set sops.validateSopsFiles to false"; - } - ]) cfg.secrets - ) - ); + assertions = [ + { + assertion = + cfg.gnupg.home != null + || cfg.gnupg.sshKeyPaths != [ ] + || cfg.gnupg.qubes-split-gpg.enable == true + || cfg.age.keyFile != null + || cfg.age.sshKeyPaths != [ ]; + message = "No key source configured for sops. Either set services.openssh.enable or set sops.age.keyFile or sops.gnupg.home or sops.gnupg.qubes-split-gpg.enable"; + } + { + assertion = + !(cfg.gnupg.home != null && cfg.gnupg.sshKeyPaths != [ ]) + && !(cfg.gnupg.home != null && cfg.gnupg.qubes-split-gpg.enable == true) + && !(cfg.gnupg.sshKeyPaths != [ ] && cfg.gnupg.qubes-split-gpg.enable == true); + message = "Exactly one of sops.gnupg.home, sops.gnupg.qubes-split-gpg.enable and sops.gnupg.sshKeyPaths must be set"; + } + { + assertion = + cfg.gnupg.qubes-split-gpg.enable == false + || ( + cfg.gnupg.qubes-split-gpg.enable == true + && cfg.gnupg.qubes-split-gpg.domain != null + && cfg.gnupg.qubes-split-gpg.domain != "" + ); + message = "sops.gnupg.qubes-split-gpg.domain is required when sops.gnupg.qubes-split-gpg.enable is set to true"; + } + ]; home.sessionVariables = lib.mkIf cfg.gnupg.qubes-split-gpg.enable { # TODO: Add this package to nixpkgs and use it from the store diff --git a/modules/nix-darwin/default.nix b/modules/nix-darwin/default.nix index c886683d..f169a30a 100644 --- a/modules/nix-darwin/default.nix +++ b/modules/nix-darwin/default.nix @@ -356,16 +356,6 @@ in ++ lib.optionals cfg.validateSopsFiles ( lib.concatLists ( lib.mapAttrsToList (name: secret: [ - { - assertion = builtins.pathExists secret.sopsFile; - message = "Cannot find path '${secret.sopsFile}' set in sops.secrets.${lib.strings.escapeNixIdentifier name}.sopsFile"; - } - { - assertion = - builtins.isPath secret.sopsFile - || (builtins.isString secret.sopsFile && lib.hasPrefix builtins.storeDir secret.sopsFile); - message = "'${secret.sopsFile}' is not in the Nix store. Either add it to the Nix store or set sops.validateSopsFiles to false"; - } { assertion = secret.uid != null && secret.uid != 0 -> secret.owner == null; message = "In ${secret.name} exactly one of sops.owner and sops.uid must be set"; diff --git a/modules/sops/default.nix b/modules/sops/default.nix index 860a9a95..c0e949e4 100644 --- a/modules/sops/default.nix +++ b/modules/sops/default.nix @@ -406,16 +406,6 @@ in ++ lib.optionals cfg.validateSopsFiles ( lib.concatLists ( lib.mapAttrsToList (name: secret: [ - { - assertion = builtins.pathExists secret.sopsFile; - message = "Cannot find path '${secret.sopsFile}' set in sops.secrets.${lib.strings.escapeNixIdentifier name}.sopsFile"; - } - { - assertion = - builtins.isPath secret.sopsFile - || (builtins.isString secret.sopsFile && lib.hasPrefix builtins.storeDir secret.sopsFile); - message = "'${secret.sopsFile}' is not in the Nix store. Either add it to the Nix store or set sops.validateSopsFiles to false"; - } { assertion = secret.uid != null && secret.uid != 0 -> secret.owner == null; message = "In ${secret.name} exactly one of sops.owner and sops.uid must be set"; diff --git a/modules/sops/manifest-for.nix b/modules/sops/manifest-for.nix index c4ecea42..18246688 100644 --- a/modules/sops/manifest-for.nix +++ b/modules/sops/manifest-for.nix @@ -1,34 +1,59 @@ -{ writeTextFile, cfg }: +{ + writeTextFile, + cfg, + lib, +}: suffix: secrets: templates: extraJson: -writeTextFile { - name = "manifest${suffix}.json"; - text = builtins.toJSON ( - { - secrets = builtins.attrValues secrets; - templates = builtins.attrValues templates; - # Does this need to be configurable? - secretsMountPoint = "/run/secrets.d"; - symlinkPath = "/run/secrets"; - keepGenerations = cfg.keepGenerations; - gnupgHome = cfg.gnupg.home; - sshKeyPaths = cfg.gnupg.sshKeyPaths; - ageKeyFile = cfg.age.keyFile; - ageSshKeyPaths = cfg.age.sshKeyPaths; - useTmpfs = cfg.useTmpfs; - placeholderBySecretName = cfg.placeholder; - userMode = false; - logging = { - keyImport = builtins.elem "keyImport" cfg.log; - secretChanges = builtins.elem "secretChanges" cfg.log; - }; - } - // extraJson - ); - checkPhase = '' - ${cfg.validationPackage}/bin/sops-install-secrets -check-mode=${ - if cfg.validateSopsFiles then "sopsfile" else "manifest" - } "$out" - ''; -} +let + + failedAssertions = builtins.foldl' ( + acc: secret: + acc + ++ (lib.optional (!builtins.pathExists secret.sopsFile) + "Cannot find path '${secret.sopsFile}' set in sops.secrets.${lib.strings.escapeNixIdentifier secret.name}.sopsFile\n" + ) + ++ + lib.optional + ( + !builtins.isPath secret.sopsFile + && !(builtins.isString secret.sopsFile && lib.hasPrefix builtins.storeDir secret.sopsFile) + ) + "'${secret.sopsFile}' is not in the Nix store. Either add it to the Nix store or set sops.validateSopsFiles to false" + ) [ ] (builtins.attrValues secrets); + +in +if cfg.validateSopsFiles && failedAssertions != [ ] then + throw "\nFailed assertions:\n${lib.concatStringsSep "\n" (map (x: "- ${x}") failedAssertions)}" +else + writeTextFile { + name = "manifest${suffix}.json"; + text = builtins.toJSON ( + { + secrets = builtins.attrValues secrets; + templates = builtins.attrValues templates; + # Does this need to be configurable? + secretsMountPoint = "/run/secrets.d"; + symlinkPath = "/run/secrets"; + keepGenerations = cfg.keepGenerations; + gnupgHome = cfg.gnupg.home; + sshKeyPaths = cfg.gnupg.sshKeyPaths; + ageKeyFile = cfg.age.keyFile; + ageSshKeyPaths = cfg.age.sshKeyPaths; + useTmpfs = cfg.useTmpfs; + placeholderBySecretName = cfg.placeholder; + userMode = false; + logging = { + keyImport = builtins.elem "keyImport" cfg.log; + secretChanges = builtins.elem "secretChanges" cfg.log; + }; + } + // extraJson + ); + checkPhase = '' + ${cfg.validationPackage}/bin/sops-install-secrets -check-mode=${ + if cfg.validateSopsFiles then "sopsfile" else "manifest" + } "$out" + ''; + }