Sops-nix not rendering templates on macOS at all

Im 90% convinced that this is me not using the tool correctly, but Im having a hard time seeing where it is going wrong. The following is the relevant snippet of my home.nix

{ pkgs
, inputs
, config
, ...
}:
let
  secretspath = builtins.toString inputs.nix-secrets;
  user = "test";
in
{
  imports = [
    inputs.sops-nix.homeManagerModules.sops
    ./git.nix
  ];

  sops = {
    defaultSopsFile = "${secretspath}/secrets/shared.yaml";
    age = {
      keyFile = "/User/${user}/Library/Application Support/sops/age/keys.txt";
    };
    secrets."git_signing_ssh_key_public" = {
      # There is nothing here since the the key is exactly the name specified above
    };
  };

  home = { ... };
}

where git.nix is

{ config
, ...
}:
{
  sops.templates."github_signing.pub" = {
    content = ''
      ${config.sops.placeholder."git_signing_ssh_key_public"}
    '';
  };

  programs.git =
    {
      enable = true;
      signing = {
        format = "ssh";
        key = "${config.sops.templates."github_signing.pub".path}";
        signByDefault = true;
      };
    };
}

Running darwin switch, which in turn also updates home-manager, leads to the following ~/.config/git/config

[user]
	signingKey = "/Users/test/.config/sops-nix/secrets/rendered/github_signing.pub"

but this directory ~/.config/sops-nix/secrets/rendered does not exist…

Looking in /nix/store/ for github_signing.pub I can find something. The contents of that file are

<SOPS:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:PLACEHOLDER>

but nowhere a decrypted version…

I double checked the logs of the build and it say

Activating sops-nix

and no errors follow, so I assumed that the decrypting of the secrets went fine…

As far as I can tell from the sops-nix documentation, this is how you are supposed to use templates, i.e. define the content with a placeholder, use the path to the template when you want to pass the file.

Any ideas what is going wrong here?

Addendum:

  • Templates are rendered at runtime, not at build time (see here). Even more confusing why it is not there…

After spending my entire Saturday afternoon debugging this…

It was a typo. I accidentally wrote /User instead of /Users…

I hope at least somebody has a laugh…

Why are you using a template when it just contains the secret itself? You could reference the secret file directly.

Hmm, how? Using builtins.readFile?

Replace it with:


programs.git =
    {
      enable = true;
      signing = {
        format = "ssh";
        key = "${config.sops.secrets."git_signing_ssh_key_public".path}";
        signByDefault = true;
      };
    };

1 Like

Hmm, that makes things ofc. easier… Thank you!

Apologies for the many sops-nix questions. Your already helping me a second time… Its taking a while to wrap my head around it.

No problem. My knowledge also comes from pain :wink: happy to help.

You really just need templates if the program expects bespectacled file format (e.g. with user name and password) or if you want to generate environment files for services.

You definitely don’t want to do something like that because that would put secrets in the store that is world readable.

3 Likes