CSS-Plus
CSS-Plus
Play with web technologies

Using agenix on a non-NixOS Linux Home Manager Nix Flake

December 30, 2024

Adding encryption to your Nix flake is important. I used to use a private Git repository to keep my secrets, but I was looking for something that integrated directly into Nix for reproducability.

In my experience, Nix Darwin is typically more mature than Nix for non-nix Linux distributions and therefore instructions are a bit more lacking. I have recently been creating a Nix Home Manager flake to manage my environment. I was having several issues getting agenix to work correctly and this article is both to help get agenix setup on a non-NixOS Linux distribution (Ubuntu, Pop!_OS, Debian, etc) as well as helping anyone who got stuck along the way like I did 😅

What is agenix?

agenix is a tool for managing encrypted secrets declaratively within the Nix ecosystem, enabling secure, reproducible secret management.

It is a CLI tool that is installed and configured upon installation. After it has been installed, it is set to run through a systemctl service.

Steps

The steps in this article assume:

  • Your Nix flake at /path/to/flake/flake.nix
  • Secrets directory at /path/to/flake/secrets/
  • Home Manager .nix file at /path/to/flake/home-manager/home.nix
  • Your username is username, change this to your username (echo $USER)
  • Your public SSH key at ~/.ssh/key.pub and private key at ~/.ssh/key. NOTE: Your key must not contain a passphrase. agenix does not deal well with keys behind a passphrase and this is what caused me to be stuck figuring this out for many hours
  1. Add agenix flake to your flake:

      inputs = {
        nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
        home-manager = {
          url = "github:nix-community/home-manager";
          inputs.nixpkgs.follows = "nixpkgs";
        };
        agenix = {
          url = "github:ryantm/agenix";
          inputs.nixpkgs.follows = "nixpkgs";
        };
      };
  2. Trigger a home-manager switch to install the agenix binary: home-manager switch --flake /path/to/flake#username.

  3. Create /path/to/flake/secrets/secrets.nix

    let
      pcName = "ssh-ed25519 AAAAC3...";
      users = [ pcName ];
    in
    {
      "secret1.age".publicKeys = users;
    }

    Note: pcName value is your SSH public key ~/.ssh/key.pub. Again, make sure ~/.ssh/key does not require a passphrase. I would suggest creating a new key for agenix specifically.

  4. Change your current working directory to /path/to/flake/secrets and create a secret1.age file with agenix:

    Run agenix -e secret1.age, this will cause an empty file to popup using your $EDITOR, paste your secret in there and save and close the file.

    cd /path/to/flake/secrets
    agenix -e secret1.age

    You should now see an encrypted file at /path/to/flake/secrets/secret1.age.

  5. Add the following to your /path/to/flake/flake.nix:

    homeConfigurations."username" = home-manager.lib.homeManagerConfiguration {
      inherit pkgs;
    
      modules = [
        agenix.homeManagerModules.default
    
        {
          age = {
            secrets = {
              "secret1" = {
                file = ./secrets/secret1.age;
              };
            };
            identityPaths = [ "/home/username/.ssh/key" ];
            secretsDir = "/home/username/.local/share/agenix/agenix";
            secretsMountPoint = "/home/username/.local/share/agenix/agenix.d";
          };
        }
    
       ./home-manager/home.nix
      ];
    };

    Have a look at the agenix README.md for more information about the agenix secrets, identityPaths, secretsDir and secretsMountPoint properties above.

  6. You can now use the agenix secret keys in your /path/to/flake/home-manager/home.nix file using config.age.secrets.secret1.path, an example of using this value and setting it to a session variable could look like this:

    {
      config,
      ...
    }:
    {
      home.sessionVariables = {
        SECRET1 = "$(cat ${config.age.secrets.workDirName.path})";
      };
    }

Debugging

  • Ensure all your paths are correct and don't contain typos.

  • Ensure your ~/.ssh/key is not protected by a passphrase.

  • If home-manager is building correctly but the secrets aren't being decrypted as expected, make sure the agenix service is loaded correctly: systemctl --user status agenix.service. You should see some information about the service, if the service is missing then something is wrong with the agenix installation.

  • journalctl --user -u agenix.service for more detailed agenix service logs.

  • If the service is there, try restarting it and then proceeding to check to see that the decrypted files are in the correct location (~/.local/share/agenix/agenix/secret1).

Conclusion

Hopefully this helps someone. Good luck!