PSA: NixOS secrets handling antipatterns

TL;DR: Don’t readFile your secrets. No, not even with Agenix. Especially not with Agenix.

This is more of a rant than a PSA. Oh well…

NixOS secrets are handled out-of-band because using secrets directly would put them into the Nix store, readable for anyone on the machine. This special handling of secrets leads to some antipatterns.

readFile-ing secrets

Sometimes, people are tempted to simply call builtins.readFile on the secret path. Pure evaluation makes it very clear that this is a bad idea. Calling readFile on the secret path will put its contents into a string during evaluation, using this string anywhere puts it into the Nix store in unencrypted form. The following two code snippets are equivalent in their output:

# Assume the file /secrets/very-secure-password.txt contains your password "a3FJeJZxgG7h"
{
  password = builtins.readFile "/secrets/very-secure-password.txt";
}
{
  password = "a3FJeJZxgG7h";
}

readFile-ing secrets provisioned by NixOS tools (agenix, sops-nix)

This is the cardinal sin of NixOS secrets management. The security issue is the same as above, except it’s more subtle because NixOS is supposed to put the secrets in place. The problem with that assumption is that it doesn’t consider when the provisioning takes place. The following graph shows the order of operatings taken when running nixos-rebuild switch (or an equivalent):

stateDiagram
direction LR
Activation: NixOS Activation
Secrets: Secrets provisioning
Services: Services are (re-)started
state Evaluation {
  direction LR
  readFile-->Evaluate
}
Evaluation-->Build
Build-->Activation
state Activation {
  direction LR
  Secrets-->Services
}

Secrets are provisioned as part of the NixOS activation, but readFile happens during evaluation. This has 2 important consequences:

  • If no activation has taken place, the secret might not exist at all, thus evaluation will fail at seemingly random times.
  • If the actual secret has changed since the last activation, the OUTDATED SECRET will be loaded during evaluation.

In conclusion, just don’t readFile your secrets, ever.

Honorable mention: git-crypt

Once again, same issues but with a twist. This one has the added benefit of being super annoying when other people want to build your NixOS configuration.

#psa #nix

#psa #nix