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
-
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"; }; };
-
Trigger a home-manager switch to install the
agenix
binary:home-manager switch --flake /path/to/flake#username
. -
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. -
Change your current working directory to
/path/to/flake/secrets
and create asecret1.age
file withagenix
: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
. -
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.
-
You can now use the agenix secret keys in your
/path/to/flake/home-manager/home.nix
file usingconfig.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 theagenix
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!