Do not render templates when decrypting neededForUsers secrets

This fixes https://github.com/Mic92/sops-nix/issues/659

In https://github.com/Mic92/sops-nix/pull/649, we started rendering
templates twice:

1. When rendering `neededForUsers` secrets (if there are any
   `neededForUsers` secrets).
2. When decrypting "regular" secrets.

This alone was weird and wrong, but didn't cause issues
for people until https://github.com/Mic92/sops-nix/pull/655, which
triggered https://github.com/Mic92/sops-nix/issues/659. The cause is not
super obvious:

1. When rendering `neededForUsers` secrets, we'd generate templates in
   `/run/secrets-for-users/rendered`.
2. However, the `path` for these templates is in
   `/run/secrets/rendered`, which is not inside of the
   `/run/secrets-for-users` directory we're dealing with, so we'd
   generate a symlink from `/run/secrets/rendered/<foo>` to
   `/run/secrets-for-users/rendered/<foo>`, which required making
   the parent directory of the symlink (`/run/secrets/rendered/`).
3. This breaks sops-nix's assumption that `/run/secrets` either doesn't
   exist, or is a symlink, and you get the symptoms described in
   <https://github.com/Mic92/sops-nix/issues/659>.

Reproducing this in a test was straightforward: just expand our existing
template test to also have a `neededForUsers` secret.

Fixing this was also straightforward: don't render templates during the
`neededForUsers` phase (if we want to add support for `neededForUsers`
templates in the future, that would be straightforward to do, but I
opted not do that here).
This commit is contained in:
Jeremy Fleischman 2024-11-11 00:18:56 -06:00 committed by mergify[bot]
parent 47fc1d8c72
commit eee831aadb
6 changed files with 32 additions and 21 deletions

View file

@ -8,7 +8,7 @@ let
inherit cfg;
inherit (pkgs) writeTextFile;
};
manifest = manifestFor "" regularSecrets {};
manifest = manifestFor "" regularSecrets regularTemplates {};
pathNotInStore = lib.mkOptionType {
name = "pathNotInStore";
@ -20,6 +20,9 @@ let
regularSecrets = lib.filterAttrs (_: v: !v.neededForUsers) cfg.secrets;
# Currently, all templates are "regular" (there's no support for `neededForUsers` for templates.)
regularTemplates = cfg.templates;
useSystemdActivation = (options.systemd ? sysusers && config.systemd.sysusers.enable) ||
(options.services ? userborn && config.services.userborn.enable);
@ -354,7 +357,7 @@ in {
sops.environment.SOPS_GPG_EXEC = lib.mkIf (cfg.gnupg.home != null || cfg.gnupg.sshKeyPaths != []) (lib.mkDefault "${pkgs.gnupg}/bin/gpg");
# When using sysusers we no longer be started as an activation script because those are started in initrd while sysusers is started later.
# When using sysusers we no longer are started as an activation script because those are started in initrd while sysusers is started later.
systemd.services.sops-install-secrets = lib.mkIf (regularSecrets != { } && useSystemdActivation) {
wantedBy = [ "sysinit.target" ];
after = [ "systemd-sysusers.service" ];

View file

@ -1,11 +1,12 @@
{ writeTextFile, cfg }:
suffix: secrets: extraJson:
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";
@ -15,7 +16,6 @@ writeTextFile {
ageKeyFile = cfg.age.keyFile;
ageSshKeyPaths = cfg.age.sshKeyPaths;
useTmpfs = cfg.useTmpfs;
templates = cfg.templates;
placeholderBySecretName = cfg.placeholder;
userMode = false;
logging = {

View file

@ -2,6 +2,7 @@
let
cfg = config.sops;
secretsForUsers = lib.filterAttrs (_: v: v.neededForUsers) cfg.secrets;
templatesForUsers = {}; # We do not currently support `neededForUsers` for templates.
manifestFor = pkgs.callPackage ../manifest-for.nix {
inherit cfg;
inherit (pkgs) writeTextFile;
@ -9,7 +10,7 @@ let
withEnvironment = import ../with-environment.nix {
inherit cfg lib;
};
manifestForUsers = manifestFor "-for-users" secretsForUsers {
manifestForUsers = manifestFor "-for-users" secretsForUsers templatesForUsers {
secretsMountPoint = "/run/secrets-for-users.d";
symlinkPath = "/run/secrets-for-users";
};