I’ve had a lot of luck with agenix in conjunction with agenix-rekey.
In essence, secrets are encrypted using SSH keys, and those keys target a
particular host. agenix-rekey specifically has some kind of chained or nested
encryption going on such that a secret can be encrypted for a specific host
automatically. agenix-rekey can also generate secrets on the fly, which helps
keep everything very declarative.
Since SSH traffic is considered to be safe enough to go all the way across the Internet, the community (and also myself, I suppose) has deemed it worthy of placing these encrypted values into our public repositories. I suspect part of this is because there are challenges with getting a good Nix configuration going with a mixed public and private setup. If the SSH encryption methods are cracked somehow, then these secrets will become public knowledge.
I did some reading a while back and saw claims that an SSH datagram could be broken with a brute force attack that would take several billion years at our current computing level. Hopefully I’ll have a better system by then.
One of the challenges that comes up with this setup is the bootstrapping problem. I’ve run into this a few times and I haven’t come up with an idiot-proof solution yet. This document hopes to capture my learnings on the topic.
Be sure to check for the initial error if secrets seem to be missing. You may find this:
age: error: no identity matched any of the recipients
This means the destination identity is missing. If this is a new host, this is likely because the identity was never copied over in plain text.
This comes back to Bootstrapping secrets. Without a host key present, we have
no identity with which to supply to age to decrypt the remaining secrets.
We do provide the host key via agenix, but it’s encrypted via its own value.
oddlama, the author of agenix-rekey, has a nix-config repository whose README
shows some instructions for adding a new machine and the manual steps involved
(there are plenty). I think if they are having to do these steps, I might be
out of luck on doing this myself.
It’s probably not a good idea to have a master identity whose password is the only thing protecting itself. Create a new identity, place it on inert storage as a backup, and rekey everything.
Use this form to declare masterIdentities to prevent over prompting.
https://github.com/oddlama/agenix-rekey?tab=readme-ov-file#agerekeymasteridentities
Actually that is only for a mode of agenix-rekey that I’m not using.