1
0
Fork 0
mirror of https://github.com/Mic92/sops-nix.git synced 2025-03-05 08:07:16 +00:00

Group gnupg and age in the module

This commit is contained in:
Janne Heß 2021-08-27 13:35:53 +02:00
parent f5a2ba217b
commit b21c0ce3a8
No known key found for this signature in database
GPG key ID: 69165158F05265DF
3 changed files with 60 additions and 49 deletions

View file

@ -678,9 +678,9 @@ If you uploaded it to `/var/lib/sops` than your sops configuration will look lik
```nix ```nix
{ {
# Make sure that `/var/lib/sops` is owned by root and is not world-readable/writable # 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 # disable import host ssh keys
sops.sshKeyPaths = []; sops.gnupg.sshKeyPaths = [];
} }
``` ```

View file

@ -85,7 +85,9 @@ let
# Does this need to be configurable? # Does this need to be configurable?
secretsMountPoint = "/run/secrets.d"; secretsMountPoint = "/run/secrets.d";
symlinkPath = "/run/secrets"; symlinkPath = "/run/secrets";
inherit (cfg) gnupgHome sshKeyPaths ageKeyFile; gnupgHome = cfg.gnupg.home;
sshKeyPaths = cfg.gnupg.sshKeyPaths;
ageKeyFile = cfg.age.keyFile;
}); });
checkedManifest = let checkedManifest = let
@ -130,52 +132,61 @@ in {
''; '';
}; };
ageKeyFile = mkOption { age = {
type = types.nullOr types.path; keyFile = mkOption {
default = null; type = types.nullOr types.path;
example = "/var/lib/sops-nix/key.txt"; default = null;
description = '' example = "/var/lib/sops-nix/key.txt";
Path to age key file used for sops decryption. 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 { gnupg = {
type = types.bool; home = mkOption {
default = false; type = types.nullOr types.str;
description = '' default = null;
Whether or not to generate the age key. If this example = "/root/.gnupg";
option is set to false, the key must already be description = ''
present at the specified location. Path to gnupg database directory containing the key for decrypting the sops file.
''; '';
}; };
gnupgHome = mkOption { sshKeyPaths = mkOption {
type = types.nullOr types.str; type = types.listOf types.path;
default = null; default = if config.services.openssh.enable then
example = "/root/.gnupg"; map (e: e.path) (lib.filter (e: e.type == "rsa") config.services.openssh.hostKeys)
description = '' else [];
Path to gnupg database directory containing the key for decrypting sops file. description = ''
''; Path to ssh keys added as GPG keys during sops description.
}; This option must be explicitly unset if <literal>config.sops.gnupg.sshKeyPaths</literal> is set.
'';
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 <literal>config.sops.sshKeyPaths</literal>.
'';
}; };
}; };
imports = [
(mkRenamedOptionModule [ "sops" "gnupgHome" ] [ "sops" "gnupg" "home" ])
(mkRenamedOptionModule [ "sops" "sshKeyPaths" ] [ "sops" "gnupg" "sshKeyPaths" ])
];
config = mkIf (cfg.secrets != {}) { config = mkIf (cfg.secrets != {}) {
assertions = [{ assertions = [{
assertion = cfg.ageKeyFile == null -> (cfg.gnupgHome == null) != (cfg.sshKeyPaths == []); assertion = cfg.age.keyFile == null -> (cfg.gnupg.home == null) != (cfg.gnupg.sshKeyPaths == []);
message = "Exactly one of sops.gnupgHome and sops.sshKeyPaths must be set"; 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); assertion = cfg.age.keyFile != null -> (cfg.age.sshKeyPaths != []) != (cfg.age.keyFile != null);
message = "sops.ageKeyFile is mutually exclusive with sops.gnupgHome and sops.sshKeyPaths"; message = "sops.age.keyFile is mutually exclusive with sops.age.sshKeyPaths";
}] ++ optionals cfg.validateSopsFiles ( }] ++ optionals cfg.validateSopsFiles (
concatLists (mapAttrsToList (name: secret: [{ concatLists (mapAttrsToList (name: secret: [{
assertion = builtins.pathExists secret.sopsFile; assertion = builtins.pathExists secret.sopsFile;
@ -190,17 +201,17 @@ in {
system.activationScripts.setup-secrets = let system.activationScripts.setup-secrets = let
sops-install-secrets = (pkgs.callPackage ../.. {}).sops-install-secrets; 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... 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 [] '' system.activationScripts.generate-age-key = (mkIf cfg.age.generateKey) (stringAfter [] ''
if [[ ! -f "${cfg.ageKeyFile}" ]]; then; if [[ ! -f "${cfg.age.keyFile}" ]]; then;
echo generating machine-specific age key... 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. # 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 fi
''); '');
}; };

View file

@ -28,7 +28,7 @@
machine = { machine = {
imports = [ ../../modules/sops ]; imports = [ ../../modules/sops ];
sops = { sops = {
ageKeyFile = ./test-assets/age-keys.txt; age.keyFile = ./test-assets/age-keys.txt;
defaultSopsFile = ./test-assets/secrets.yaml; defaultSopsFile = ./test-assets/secrets.yaml;
secrets.test_key = {}; secrets.test_key = {};
}; };
@ -55,7 +55,7 @@
group = "nogroup"; group = "nogroup";
}; };
sops.gnupgHome = "/run/gpghome"; sops.gnupg.home = "/run/gpghome";
sops.defaultSopsFile = ./test-assets/secrets.yaml; sops.defaultSopsFile = ./test-assets/secrets.yaml;
sops.secrets.test_key.owner = config.users.users.someuser.name; sops.secrets.test_key.owner = config.users.users.someuser.name;
sops.secrets.existing-file = { sops.secrets.existing-file = {