diff --git a/README.md b/README.md
index e6175ef..e3091bd 100644
--- a/README.md
+++ b/README.md
@@ -678,9 +678,9 @@ If you uploaded it to `/var/lib/sops` than your sops configuration will look lik
```nix
{
# Make sure that `/var/lib/sops` is owned by root and is not world-readable/writable
- sops.gnupgHome = "/var/lib/sops";
+ sops.gnupg.home = "/var/lib/sops";
# disable import host ssh keys
- sops.sshKeyPaths = [];
+ sops.gnupg.sshKeyPaths = [];
}
```
diff --git a/modules/sops/default.nix b/modules/sops/default.nix
index be2f835..650fc92 100644
--- a/modules/sops/default.nix
+++ b/modules/sops/default.nix
@@ -85,7 +85,9 @@ let
# Does this need to be configurable?
secretsMountPoint = "/run/secrets.d";
symlinkPath = "/run/secrets";
- inherit (cfg) gnupgHome sshKeyPaths ageKeyFile;
+ gnupgHome = cfg.gnupg.home;
+ sshKeyPaths = cfg.gnupg.sshKeyPaths;
+ ageKeyFile = cfg.age.keyFile;
});
checkedManifest = let
@@ -130,52 +132,61 @@ in {
'';
};
- ageKeyFile = mkOption {
- type = types.nullOr types.path;
- default = null;
- example = "/var/lib/sops-nix/key.txt";
- description = ''
- Path to age key file used for sops decryption.
- '';
+ age = {
+ keyFile = mkOption {
+ type = types.nullOr types.path;
+ default = null;
+ example = "/var/lib/sops-nix/key.txt";
+ description = ''
+ Path to age key file used for sops decryption.
+ Setting this to a non-null value causes age to be used instead of gnupg.
+ '';
+ };
+
+ generateKey = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether or not to generate the age key. If this
+ option is set to false, the key must already be
+ present at the specified location.
+ '';
+ };
};
- generateAgeKey = mkOption {
- type = types.bool;
- default = false;
- description = ''
- Whether or not to generate the age key. If this
- option is set to false, the key must already be
- present at the specified location.
- '';
- };
+ gnupg = {
+ home = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ example = "/root/.gnupg";
+ description = ''
+ Path to gnupg database directory containing the key for decrypting the sops file.
+ '';
+ };
- gnupgHome = mkOption {
- type = types.nullOr types.str;
- default = null;
- example = "/root/.gnupg";
- description = ''
- Path to gnupg database directory containing the key for decrypting sops file.
- '';
- };
-
- sshKeyPaths = mkOption {
- type = types.listOf types.path;
- default = if config.services.openssh.enable then
- map (e: e.path) (lib.filter (e: e.type == "rsa") config.services.openssh.hostKeys)
- else [];
- description = ''
- Path to ssh keys added as GPG keys during sops description.
- This option must be explicitly unset if config.sops.sshKeyPaths.
- '';
+ sshKeyPaths = mkOption {
+ type = types.listOf types.path;
+ default = if config.services.openssh.enable then
+ map (e: e.path) (lib.filter (e: e.type == "rsa") config.services.openssh.hostKeys)
+ else [];
+ description = ''
+ Path to ssh keys added as GPG keys during sops description.
+ This option must be explicitly unset if config.sops.gnupg.sshKeyPaths is set.
+ '';
+ };
};
};
+ imports = [
+ (mkRenamedOptionModule [ "sops" "gnupgHome" ] [ "sops" "gnupg" "home" ])
+ (mkRenamedOptionModule [ "sops" "sshKeyPaths" ] [ "sops" "gnupg" "sshKeyPaths" ])
+ ];
config = mkIf (cfg.secrets != {}) {
assertions = [{
- assertion = cfg.ageKeyFile == null -> (cfg.gnupgHome == null) != (cfg.sshKeyPaths == []);
- message = "Exactly one of sops.gnupgHome and sops.sshKeyPaths must be set";
+ assertion = cfg.age.keyFile == null -> (cfg.gnupg.home == null) != (cfg.gnupg.sshKeyPaths == []);
+ message = "Exactly one of sops.gnupg.home and sops.gnupg.sshKeyPaths must be set for gnupg mode";
} {
- assertion = (cfg.sshKeyPaths != [] || cfg.gnupgHome != null) != (cfg.ageKeyFile != null);
- message = "sops.ageKeyFile is mutually exclusive with sops.gnupgHome and sops.sshKeyPaths";
+ assertion = cfg.age.keyFile != null -> (cfg.age.sshKeyPaths != []) != (cfg.age.keyFile != null);
+ message = "sops.age.keyFile is mutually exclusive with sops.age.sshKeyPaths";
}] ++ optionals cfg.validateSopsFiles (
concatLists (mapAttrsToList (name: secret: [{
assertion = builtins.pathExists secret.sopsFile;
@@ -190,17 +201,17 @@ in {
system.activationScripts.setup-secrets = let
sops-install-secrets = (pkgs.callPackage ../.. {}).sops-install-secrets;
- in stringAfter ([ "specialfs" "users" "groups" ] ++ optional cfg.generateAgeKey "generate-age-key") ''
+ in stringAfter ([ "specialfs" "users" "groups" ] ++ optional cfg.age.generateKey "generate-age-key") ''
echo setting up secrets...
- ${optionalString (cfg.gnupgHome != null) "SOPS_GPG_EXEC=${pkgs.gnupg}/bin/gpg"} ${sops-install-secrets}/bin/sops-install-secrets ${checkedManifest}
+ ${optionalString (cfg.gnupg.home != null) "SOPS_GPG_EXEC=${pkgs.gnupg}/bin/gpg"} ${sops-install-secrets}/bin/sops-install-secrets ${checkedManifest}
'';
- system.activationScripts.generate-age-key = (mkIf cfg.generateAgeKey) (stringAfter [] ''
- if [[ ! -f "${cfg.ageKeyFile}" ]]; then;
+ system.activationScripts.generate-age-key = (mkIf cfg.age.generateKey) (stringAfter [] ''
+ if [[ ! -f "${cfg.age.keyFile}" ]]; then;
echo generating machine-specific age key...
- mkdir -p $(dirname ${cfg.ageKeyFile})
+ mkdir -p $(dirname ${cfg.age.keyFile})
# age-keygen sets 0600 by default, no need to chmod.
- ${pkgs.age}/bin/age-keygen -o ${cfg.ageKeyFile}
+ ${pkgs.age}/bin/age-keygen -o ${cfg.age.keyFile}
fi
'');
};
diff --git a/pkgs/sops-install-secrets/nixos-test.nix b/pkgs/sops-install-secrets/nixos-test.nix
index a12539a..147e9cd 100644
--- a/pkgs/sops-install-secrets/nixos-test.nix
+++ b/pkgs/sops-install-secrets/nixos-test.nix
@@ -28,7 +28,7 @@
machine = {
imports = [ ../../modules/sops ];
sops = {
- ageKeyFile = ./test-assets/age-keys.txt;
+ age.keyFile = ./test-assets/age-keys.txt;
defaultSopsFile = ./test-assets/secrets.yaml;
secrets.test_key = {};
};
@@ -55,7 +55,7 @@
group = "nogroup";
};
- sops.gnupgHome = "/run/gpghome";
+ sops.gnupg.home = "/run/gpghome";
sops.defaultSopsFile = ./test-assets/secrets.yaml;
sops.secrets.test_key.owner = config.users.users.someuser.name;
sops.secrets.existing-file = {