The state of the art are basically sops-nix and agenix. They’re both conceptually pretty similar, you configure some public keys as being used to encrypt secrets, and run a command to generate a file encrypted with that public key which can be decrypted with the corresponding private key. agenix only supports age, which uses SSH keys (the public key in your config, the private key put on the nixos system by some other mechanism), while sops-nix supports age or gpg.
My question now is where and how do I securely store secrets?
It depends on what are your goals.
For example, are you happy with just filesystem permissions protecting the secrets or you’d rather use some form of encryption?
In the former you can just put them in so location like /var/my-secrets with appropriate permissions, say 600 and owned by the user that needs them. In the latter you need some software to encrypt/decrypt the secrets on demand, which is a lot more complicated but probably safer.
Also, do you want to configure machine remotely? If so, should the secret be ephemeral (reprovision on every boot) or persistent? etc.
Here’s a(n incomplete) comparison of some solutions.
Been using agenix together with pass for a while now. sops-nix is neat, but since it only supports age and gpg, I haven’t found it to be much more useful than agenix. When bootstrapping a new machine, I just boot up nixos, let it create a host ssh key, encrypt all the necessary secrets using age, add it to my dotfiles flake repo, and run
It works OK. It wouldn’t work on a too massive scale, I’m managing about 10 machines using this approach, and it’s fine for that. Updating passwords is a make rule which looks something like
pass path/to/secret | head -1 | age --encrypt --armor -R path/to/host_key.pub -o path/to/encrypted/secret.age
I use a yubikey to encrypt passwords in pass, so in the end, you either need root access on the target machine, or you need the yubikey.
It’s not perfect, nothing in security is, it’s a bit fiddly, and rotating secrets is not the easiest, but I’m pretty happy with it. It works on both my ec2 servers and my laptops, which hashicorp vault doesnt, and it works for keys needed at boot on servers, which yubikey gpg encrypted stuff doesnt.
May I just say, that nix definitely needs a batteries-included, easy, built-in way to mange secrets? It’s so important, I don’t know how it’s not one of the top priorities. Security needs to be easy, usable and as readily available as can be, because people are lazy and this question comes up way too often.
Secrets paths have been discussed for a very long time. The problem is that encryption or ACLs are pretty much incompatible with the current model of world-readable Nix store and reproducibility, so they’re far from easy to implement.