Tutorial
-
The system you want to deploy secrets to should already exist and have
sshdrunning on it so that it has generated SSH host keys in/etc/ssh/. -
Make a directory to store secrets and
agenix-rules.nixfile for listing secrets and their public keys (This file is not imported into your NixOS configuration. It is only used for theagenixCLI.):$ mkdir secrets $ cd secrets $ touch agenix-rules.nix -
Add public keys to
agenix-rules.nixfile (hint: usessh-keyscanor GitHub (for example, https://github.com/ryantm.keys)):let user1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL0idNvgGiucWgup/mP78zyC23uFjYq0evcWdjGQUaBH"; user2 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILI6jSq53F/3hEmSs+oq9L4TwOo1PrDMAgcA1uo1CCV/"; users = [ user1 user2 ]; system1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPJDyIr/FSz1cJdcoW69R+NrWzwGK/+3gJpqD1t8L2zE"; system2 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKzxQgondgEYcLpcPdJLrTdNgZ2gznOHCAxMdaceTUT1"; systems = [ system1 system2 ]; in { "secret1.age".publicKeys = [ user1 system1 ]; "secret2.age".publicKeys = users ++ systems; "armored-secret.age" = { publicKeys = [ user1 ]; armor = true; }; }The keys can come from
~/.ssh/id_ed25519.pub, from a running target machine withssh-keyscan -t ed25519 <hostname-or-ip-address>, or from a user's GitHub keys page. Each recipient needs the corresponding private key to decrypt the secret. The optionalarmor = truerule produces Base64 text, which can make diffs easier to read. -
Edit secret files (these instructions assume your SSH private key is in ~/.ssh/):
$ agenix -e secret1.ageYou can also pipe complete contents into
agenix -e secret1.ageto create or replace a secret without a decryption key. This overwrites the previous contents rather than editing them.$ printf '%s\n' 'new secret' | agenix -e secret1.ageTo edit an existing secret with a key outside
~/.ssh, pass it explicitly:$ agenix -e secret1.age -i /path/to/id_ed25519 -
Add secret to a NixOS module config:
{ age.secrets.secret1.file = ../secrets/secret1.age; } -
Use the secret in your config:
{ users.users.user1 = { isNormalUser = true; hashedPasswordFile = config.age.secrets.secret1.path; }; } -
NixOS rebuild or use your deployment tool like usual.
The secret will be decrypted to the value of
config.age.secrets.secret1.path(/run/agenix/secret1by default).
Using agenix with Home Manager
The Home Manager module follows the same approach for secrets scoped to one user. Install it using one of the methods above, then declare a secret:
{
age.secrets.example-secret.file = ../secrets/example-secret.age;
}
The module tries your ~/.ssh/id_ed25519 and ~/.ssh/id_rsa keys by default.
Set age.identityPaths to absolute paths if your keys are elsewhere. Use
config.age.secrets.example-secret.path for an application option that accepts
a secret file path.
After home-manager switch, secrets are available under
$XDG_RUNTIME_DIR/agenix on Linux or the Darwin user temporary directory by
default. See the Home Manager module reference
for its options.