opnix icon indicating copy to clipboard operation
opnix copied to clipboard

Best way to reference secrets as strings / variables?

Open dsully opened this issue 1 month ago • 5 comments

What's the best way to reference secrets as variables so they can be used as values or substitutions in other Nix code (in my case, home-manager)?

Here's an example of what I'm trying to do:

home = {
   programs = {
      onepassword-secrets = {
        enable = true;

        # This doesn't work for home-manager opnix
        # pathTemplate = "${config.home.homeDirectory}/.local/state/secrets/{service}/{name}";

        secrets = {
          cachixToken = {
            reference = "op://Services/Cachix/token";
            path = ".local/state/secrets/cachix.token";
            mode = "0600";
          };
        };
      };
    };
};

# Or home.file?
xdg = {
    configFile = {
      "cachix/cachix.dhall".text = lib.generators.toDhall {} {
        authToken = config.programs.onepassword-secrets.secretPaths.cachixToken;
        hostname = "https://cachix.org";
        binaryCaches = []; # : List { name : Text, secretKey : Text };
      };
    };

    mime.enable = false;
  };
}

That just puts the path to the file into the cachix config. If I try to use builtins.readFile - the build fails as that file doesn't exist at evaluation time.

Thanks!

dsully avatar Nov 09 '25 21:11 dsully

Interested in figuring this out, too. I attempted to figure this out in May but was unsuccessful.

It seems, for home-manager at least, that there are issues at evaluation time like you say. I wonder if this is more doable in nixos or nix-darwin?

billimek avatar Nov 10 '25 13:11 billimek

It appears as though reading through the code, there is no way to reference them as strings. You can only reference a path to the file. I would definitely like to see string references as a feature however.

itzTheMeow avatar Nov 17 '25 18:11 itzTheMeow

There is no way of referencing to the secrets' values because every file written during nix evaluation will be written to the Nix store which is world readable and so defeats the purpose of using opnix (or sops-nix or agenix).

You can probably use something like scalpel to replace placeholders on activation. I've also done some hacks using systemd's ExecPreStart (on nixos) or launchd (on macOS).

CarlosZ avatar Nov 22 '25 05:11 CarlosZ

Similar to what @CarlosZ suggested, I succeeded using activation scripts. I simply use a placeholder for the secrets and then in the activation script I read the secret from the file and replace the placeholder with a sed command. Here an example:

Secret definition

security = {
      opnix = {
        secrets = {
          apiKey = {
            path = "secrets/api_key";
            reference = "op://Development/woe3hj5uqm3cog2efpl33h65e4/credential";
            group = "staff";
          };
        };
      };
    };

Activation

home.activation.generateConfig = home-manager.lib.hm.dag.entryAfter [ "writeBoundary" ] ''
        # Substitute secrets
        sed -i \
          -e "s|__API_KEY__|$(<${config.programs.onepassword-secrets.secretPaths.apiKey})|" \
          "$HOME/config.yaml"
      '';

Is this the best way to do that? I am not sure, but at least it works It would be great if it would be possible to simply reference the secret, but I have no enough experience with Nix to know if this is possible without having the reference ending in the nix store.

hackardoX avatar Nov 25 '25 06:11 hackardoX

As another alternative, I opted to use the 1Password CLI to inject secrets into my configs.

I wrote a small utility: https://github.com/itzTheMeow/dotfiles-nix/blob/master/lib/opinject.nix which enables me to simply do:

home.file.".config/immich/auth.yml" = {
  text = ''
      url: https://immich.example.com/api
      key: {{op://Personal/Immich/API Keys/CLI}}
    '';
  force = true;
  opinject = true;
};

to inject a secret into the file

i had to add a workaround to use the /usr/local/bin/op binary if it is installed, since the desktop app won't integrate with the CLI if installed via nix

i published it as a home-manager module: itzTheMeow/opinject

itzTheMeow avatar Nov 29 '25 22:11 itzTheMeow