agenix: age-encrypted secrets for NixOS and Home Manager
age-encrypted secrets for NixOS and Home manager
At a glance
- What is it?
- agenix is a small Nix library and CLI that encrypts secrets with age and SSH keys, then decrypts them on the target machine during system activation. It fits teams already running NixOS with SSH host keys, and it is a poor fit for anyone who needs secrets rotated without rebuilding.
- Who is it for?
- Adopt agenix if your machines already have SSH host keys and you want secrets to ride along with nixos-rebuild instead of a separate distribution channel. Do not adopt it if you need per-service secrets that rotate without a rebuild, or if your SSH keys are password-protected and you rekey often.
- Can I use it commercially?
- Yes. CC0-1.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Nix, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 2, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem agenix solves: secrets in a world-readable Nix store
Every file in the Nix store is readable by any system user. That single property rules out putting cleartext passwords or tokens there, and it is the constraint agenix is built around. The README frames the alternative it rejects: tools such as NixOps deployment.keys deploy secrets separately from nixos-rebuild, which the project says makes deployment, caching and auditing harder and less reproducible.
agenix takes the opposite route. It encrypts secrets into .age files, copies those ciphertext files into the Nix store like any other package, and decrypts them on the target machine using the SSH host private key during NixOS system activation. The audience is narrow and specific: people running NixOS or Home Manager who already have SSH key infrastructure and want secrets to travel through the same rebuild path as the rest of their configuration. If you are not on Nix, nothing here applies to you.
How agenix works: SSH keys, age, and activation-time decryption
The project has two parts, and the split explains most of its behaviour. The first is an agenix command line app that encrypts secrets into .age files. The second is a NixOS module (and a Home Manager module) that adds those encrypted files to the Nix store, decrypts them on the target machine, and mounts the plaintext at a well known path such as /run/agenix/.
The key material is not new. agenix encrypts with age using common public-private SSH key pairs. Public keys can come from ssh-keyscan against system hosts, or from a GitHub user's published keys, which the README illustrates with https://github.com/ryantm.keys. Decryption needs the corresponding private SSH key on the target machine, so the trust boundary is the one you already have.
That design has a cost the README states plainly: age does not support ssh-agent, so password-protected SSH keys do not work well. The example given is rekeying 20 secrets, which means entering your password 20 times. The project also lists what it deliberately avoids: no GPG, and very little code, which it presents as something you can audit yourself. The encrypted files land in the Nix store, so no separate distribution mechanism is needed.
Installing agenix with flakes and encrypting a first secret
The README documents four installation routes: niv, nix-channel, fetchTarball, and flakes. The flake path is the one most current setups will use. Adding the input and the module to a nixosConfiguration looks like this, with the hostname and system values replaced by your own:
{
inputs.agenix.url = "github:ryantm/agenix";
outputs = { self, nixpkgs, agenix }: {
nixosConfigurations.yourhostname = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
./configuration.nix
agenix.nixosModules.default
];
};
};
}For a Home Manager configuration the README uses agenix.homeManagerModules.default in the modules list instead. You do not have to install the CLI to try it. The README gives this ad-hoc invocation, which prints the tool's help text:
nix run github:ryantm/agenix -- --helpThe repository ships an example directory containing example/secret1.age, example/secret2.age, example/armored-secret.age, example/passwordfile-user1.age, example/-leading-hyphen-filename.age and example/secrets.nix. That secrets.nix file is the one to read first: it is the rule set that maps secret names to the public keys allowed to decrypt them, and the .age files next to it show what the encrypted output looks like. The README's tutorial section is where the full sequence from editing secrets.nix to rebuilding is written out; the reference sections for the age module, the age-home module and the CLI sit under it.
Where agenix gets in your way
The password-protected key limitation is the most concrete failure mode, and it is structural rather than a bug. Because age has no ssh-agent support, a key that prompts for a passphrase prompts once per operation. Rekeying a set of secrets becomes a typing exercise. If your host keys are passphrase-protected and you rotate secrets regularly, agenix will feel worse than the alternative on every rotation.
The second limitation follows from decryption happening at activation. Secrets are decrypted on the target machine at that moment, which means the plaintext exists on that machine under /run/agenix/. Anyone who can read that path during the machine's lifetime can read the secret. agenix moves secrets out of the world-readable Nix store; it does not make them unreadable to a user who already has root or equivalent access on the host.
The third is scope. agenix is a Nix library plus a small CLI. It is not a secret server, it has no rotation scheduler, and it has no audit log. If your requirement is dynamic credentials handed out per service at runtime, this is the wrong tool and no amount of module configuration will change that.
agenix vs sops-nix: two ways to answer the same question
The comparison people ask about is agenix against sops-nix, and the difference is in the encryption format rather than the Nix integration. agenix encrypts each secret as its own age file, keyed to SSH public keys, and the README's threat model section is where the project sets out what that protects against. sops-nix works through Mozilla SOPS, where a single encrypted document can hold many values and the file's structure stays visible while the values are encrypted.
That distinction changes daily work. With agenix, adding one secret means adding one .age file and one entry in secrets.nix. With sops-nix, adding one secret means editing a document that already contains the others, which can be easier to review as a diff and harder to split per machine. Neither approach is strictly better; they optimise for different review habits.
A second practical difference is the key source. agenix leans on SSH keys you already have, including keys fetched from GitHub for users. That is why the README can promise no GPG. If your organisation's key material lives in GPG or in a cloud KMS, agenix's model will not meet you where you are.
Maintenance, licensing, and what a rebuild costs you
The repository is not archived, and the last push was on 2026-09-28. The release history shows 0.18.0 on 2026-09-27, 0.17.0 on 2026-09-26 and 0.16.0 on 2026-09-26, so the project has been shipping. That tells you the code moves; it does not tell you the interface is frozen, and the README's reference sections are the place to check attribute names against the version you pin.
Upgrade cost is mostly the cost of Nix itself. The module is imported into your configuration, so a version bump arrives with your next flake update or channel update, and any change to the age module reference surfaces at evaluation or rebuild time rather than at deploy time. The README's fetchTarball example shows the pinning pattern the project expects, with a commit id and a sha256 that the README says to update from nix build output.
The licence is CC0-1.0. That is a public domain dedication rather than a permissive software licence in the usual sense, and it is worth reading the LICENSE file in the repository rather than assuming it behaves like MIT. This is a description of what the file says, not legal advice; if the distinction matters to your organisation, have someone who can give that advice look at it.
Editorial conclusion
Adopt agenix if your machines already have SSH host keys and you want secrets to ride along with nixos-rebuild instead of a separate distribution channel. Do not adopt it if you need per-service secrets that rotate without a rebuild, or if your SSH keys are password-protected and you rekey often. Before committing, verify how the age module reference names the secrets attribute and the decrypted path under /run/agenix, and check whether your workflow can tolerate the password prompt behaviour the README describes.
Frequently asked questions
How do you use agenix?
You encrypt secrets with the agenix CLI into .age files, add those files to the Nix store through the age module, and the target machine decrypts them during NixOS system activation using its SSH host private key. The plaintext is mounted at a path such as /run/agenix/ for services to read.
What is the difference between agenix and sops-nix?
agenix encrypts each secret as its own age file keyed to SSH public keys, while sops-nix works through Mozilla SOPS, where one encrypted document can hold many values with its structure still visible. agenix deliberately avoids GPG and leans on the SSH keys you already have.
Does agenix work with password-protected SSH keys?
Not well. The README states that age does not support ssh-agent, so password-protected SSH keys cause repeated prompts; its example is rekeying 20 secrets, which requires entering the password 20 times.
Where do decrypted agenix secrets end up on the target machine?
The age module automatically mounts the decrypted secrets on a well known path such as /run/agenix/ so that other services can consume them.
Which public keys can agenix encrypt a secret to?
System public keys gathered with ssh-keyscan, or public keys published on GitHub for users, such as the keys at https://github.com/ryantm.keys. The corresponding private SSH key must be present on the target machine.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/ryantm-agenix)