I’m giving a talk today at NixCon 2022: “Let’s manage secrets the systemd way”.

You can find my slides here on Google Slides. I’ll update this post when the recording is available.

Nix is not great with secrets

Nix is a package manager. It has no support for secrets. By this I mean that every source and every product ends up in the world-readable Nix store. Some applications of Nix, like NixOS and home-manager, use Nix to generate config files (in /etc or $HOME, respectively) and often, you need those to contain information you don’t want to make world-readable.

So, secrets are a point of difference between package management and OS management, and currently NixOS has no support for them.

My first foray into NixOS actually almost ended very quickly: only a few minutes after deciding I’d try to write a configuration.nix and configure myself a VM, I was looking at users.users.<name>.password which clearly tells you that (1) you can manager your users’ passwords this way (yay) and (2) it’s a terrible idea because passwords will be world readable (boo). This wasn’t a great first impression.

The state of the art

Since this is a common problem, and there’s no common solution, secret management in Nix is a fertile ground for reinvention. The wiki page on the topic lists 8 entries, and it’s pretty hard to understand which ones do what, despite the many columns trying to make sense of it. This was also not great for beginner me.

All of these entries have at least two things in common:

  • They are all clever and have merit;
  • They all find a way to manage secrets outside of Nix.

Because everyone ends up doing their own thing, there is no convention. This means that NixOS module authors have little guidance on how to structure their modules to handle secrets. This makes it hard for NixOS users to do the right thing, and easy to accidentally leak their secrets to the store.

This is not good: the easy path should be safe, otherwise people will inevitably keep using NixOS in an insecure way.

About systemd-creds

systemd has a set of features to manage what they call “credentials”, which can be secrets. It’s actually remarkably easy to use, and the official documentation has plenty of ready-to-use examples. You’re better off reading that doc than this blog post if you want to learn about systemd-creds.

Notably, systemd’s credential management offers several features that do not exist or are not common in the NixOS secret management landscape today:

  • encryption uses a per-host key, using the host’s TPM if one is available. This makes it really hard to extract the host’s private key to decrypt secrets later, and strongly limits the risk of lateral movement between hosts;
  • it manages secret permissions for you: since it’s integrated with systemd’s unit management, a credential is only made available to the processes running in that unit.

That last point is interesting, as multiple solutions (e.g. agenix) require you to think about secret permissions which can require some trial and error to get right.

systemd-creds in NixOS

This issue investigated the possibility of using systemd-creds in NixOS to solve the secret management problem. It was closed after showing that, indeed, it works, and it’s now used (for unencrypted credentials, i.e. not secrets) by about 15 modules. Unfortunately, it has not gained traction as a secret management system.

I also have a proof-of-concept integrating agenix with systemd-creds at github.com/korfuri/agenix-systemd. This integration demonstrates that LoadCredentialEncrypted= works just fine for NixOS. However, since modules do not make use of it, it’s not easy to use it in practice without patching nixpkgs. That lack of standardization strikes again.

Call to action

So where do we go from there?

Good patterns in nixpkgs emerge, they’re not decided by committee. So in that spirit, I’d love to get some people to hack with me during NixCon’s hackday to try out some Nix patterns, and maybe some tooling approaches alongside them. Let’s try stuff and see what works!

Also, if you are a systemd developer, there’s this TODO entry that could really be useful to us.

Questions and ideas? Reach me at one of these: korfuri at google’s popular email service dot com, @uriel:cilg.org on Matrix, or if you’re reading this during NixCon, probably behind the bar at the back of the main room.