`sops-nix` templates and home manager

Issue

I am trying to place a sops-nix template [1] into a file within my home directory via home-manager option – home.file.source. However, evaluation fails with:

error: access to absolute path '/Users/me/.config/sops-nix/secrets/rendered/example-yaml' is forbidden in pure evaluation mode (use '--impure' to override)

Setup

# ../secrets/default.yaml
service:
  api_key: some-secret-value-here
# default.nix
{
  ...
}:
let
  modules = [
    ./service.nix
  ];
in
{
  imports = modules;
  sops = {
    age = {
      keyFile = "${config.xdg.configHome}/sops/age/keys.txt";
    };
    defaultSopsFile = ../secrets/default.yaml;
    secrets = {
      "service/api_key" = { };
    };
    templates = {
      "example-yaml" = {
        content = ''
          cli:
            api_key: ${config.sops.placeholder."service/api_key"}
        '';
      };
    };
  };
}
# service.nix
{
  config,
  ...
}:
{
  home.file.".config/service/config.yaml = {
    enable = true;
    source = config.sops.templates."service-yaml".path;
  };
}

How do I obscure this secret without using --impure evaluation?

[1] GitHub - Mic92/sops-nix: Atomic secret provisioning for NixOS based on sops · GitHub

What a crazy coincidence that someone else did basically the same thing at the same time lmao.

1 Like

Not sure if it’s the best solution, but I did find some people use lib.file.mkOutOfStoreSymlink on GH. I tried using this with my own configuration, and seems to work:

# services.nix

{
  config,
  ...
}:
{
  home.file.".config/service/config.yaml = {
    enable = true;
    source = config.lib.file.mkOutOfStoreSymlink config.sops.templates."service-yaml".path;
  };
}

I vaguely recall running into some vague issue causing this to fail down the road, so that’s why I am hesitant to use it.

You have several options:

  1. Tell us which service you use so we can help you find a way to get it to read the secret
  2. You try to set the path option of the template (haven’t done that so far but it should work according to the docs) where you want the config file to be.
  3. If your service uses yaml it might be possible to reference a link to the secrets file.

Don’t use system secrets in your HM configuration.

Also please file a bug in the sops-nix repo, or plus one existing issues, to ask for template support in HM.

So strange! I’m working with sops-nix templates tonight, too!

https://simonshine.dk/articles/sops-nix-templates/

I’m not using home-manager, though, but hjem.

Here is a flake-parts module that works for me; the sops-nix template part doesn’t require hjem or home-manager, but I do assume that I’m the only user on the system and define a variable that references this user. I also assume that /home is that user’s home directory.

{ ... }:
{
  flake.nixosModules.dotfiles =
    { config, primaryUser, ... }:
    {
      sops.secrets.irssi_libera_sasl_password.sopsFile = ../secrets/dao/irssi.yaml;

      sops.templates."irssi-config" = {
        path = "/home/${primaryUser}/.irssi/config";
        owner = primaryUser;
        mode = "0600";
        content =
          builtins.replaceStrings
            [ "@LIBERA_SASL_PASSWORD@" ]
            [ config.sops.placeholder.irssi_libera_sasl_password ]
            (builtins.readFile ../dot.irssi/config);
      };
    };
}
1 Like