|
1 | 1 | # Secrets |
2 | | -Secrets are managed using [git-crypt][git-crypt] so you can keep your flake in |
3 | | -a public repository like GitHub without exposing your password or other |
4 | | -sensitive data. |
| 2 | +Secrets are managed using [git-crypt][git-crypt] and [agenix][agenix] |
| 3 | +so you can keep your flake in a public repository like GitHub without |
| 4 | +exposing your password or other sensitive data. |
5 | 5 |
|
6 | 6 | By default, everything in the secrets folder is automatically encrypted. Just |
7 | 7 | be sure to run `git-crypt init` before putting anything in here. |
8 | 8 |
|
| 9 | +## Agenix |
| 10 | +Currently, there is [no mechanism][secrets-issue] in nix itself to deploy secrets |
| 11 | +within the nix store because it is world-readable. |
| 12 | + |
| 13 | +Most NixOS modules have the ability to set options to files in the system, outside |
| 14 | +the nix store, that contain sensitive information. You can use [agenix][agenix] |
| 15 | +to easily setup those secret files declaratively. |
| 16 | + |
| 17 | +[agenix][agenix] encrypts secrets and stores them as .age files in your repository. |
| 18 | +Age files are encrypted with multiple ssh public keys, so any host or user with a |
| 19 | +matching ssh private key can read the data. The [age module][age module] will add those |
| 20 | +encrypted files to the nix store and decrypt them on activation to `/run/secrets`. |
| 21 | + |
| 22 | +### Setup |
| 23 | +All hosts must have openssh enabled, this is done by default in the core profile. |
| 24 | + |
| 25 | +You need to populate your `secrets/secrets.nix` with the proper ssh public keys. |
| 26 | +Be extra careful to make sure you only add public keys, you should never share a |
| 27 | +private key!! |
| 28 | + |
| 29 | +secrets/secrets.nix: |
| 30 | +```nix |
| 31 | +let |
| 32 | + system = "<system ssh key>"; |
| 33 | + user = "<user ssh key>"; |
| 34 | + allKeys = [ system user ]; |
| 35 | +in |
| 36 | +``` |
| 37 | + |
| 38 | +On most systems, you can get your systems ssh public key from `/etc/ssh/ssh_host_ed25519_key.pub`. If |
| 39 | +this file doesn't exist you likely need to enable openssh and rebuild your system. |
| 40 | + |
| 41 | +Your users ssh public key is probably stored in `~/.ssh/id_ed25519.pub` or |
| 42 | +`~/.ssh/id_rsa.pub`. If you haven't generated a ssh key yet, be sure do so: |
| 43 | +```sh |
| 44 | +ssh-keygen -t ed25519 |
| 45 | +``` |
| 46 | + |
| 47 | +> ##### _Note:_ |
| 48 | +> The underlying tool used by agenix, rage, doesn't work well with password protected |
| 49 | +> ssh keys. So if you have lots of secrets you might have to type in your password many |
| 50 | +> times. |
| 51 | +
|
| 52 | + |
| 53 | +### Secrets |
| 54 | +You will need the `agenix` command to create secrets. DevOS conveniently provides that |
| 55 | +in the devShell, so just run `nix develop` whenever you want to edit secrets. Make sure |
| 56 | +to always run `agenix` while in the `secrets/` folder, so it can pick up your `secrets.nix`. |
| 57 | + |
| 58 | +To create secrets, simply add lines to your `secrets/secrets.nix`: |
| 59 | +``` |
| 60 | +let |
| 61 | + ... |
| 62 | + allKeys = [ system user ]; |
| 63 | +in |
| 64 | +{ |
| 65 | + "secret.age".publicKeys = allKeys; |
| 66 | +} |
| 67 | +``` |
| 68 | +That would tell agenix to create a `secret.age` file that is encrypted with the `system` |
| 69 | +and `user` ssh public key. |
| 70 | + |
| 71 | +Then go into the `secrets` folder and run: |
| 72 | +```sh |
| 73 | +agenix -e secret.age |
| 74 | +``` |
| 75 | +This will create the `secret.age`, if it doesn't already exist, and allow you to edit it. |
| 76 | + |
| 77 | +If you ever change the `publicKeys` entry of any secret make sure to rekey the secrets: |
| 78 | +```sh |
| 79 | +agenix --rekey |
| 80 | +``` |
| 81 | + |
| 82 | +### Usage |
| 83 | +Once you have your secret file encrypted and ready to use, you can utilize the [age module][age module] |
| 84 | +to ensure that your secrets end up in `/run/secrets`. |
| 85 | + |
| 86 | +In any profile that uses a NixOS module that requires a secret you can enable a particular secret like so: |
| 87 | + |
| 88 | +```nix |
| 89 | +{ self, ... }: |
| 90 | +{ |
| 91 | + age.secrets.mysecret.file = "${self}/secrets/mysecret.age"; |
| 92 | +} |
| 93 | +``` |
| 94 | + |
| 95 | + |
| 96 | +Then you can just pass the path `/run/secrets/mysecret` to the module. |
| 97 | + |
| 98 | +You can make use of the many options provided by the age module to customize where and how |
| 99 | +secrets get decrypted. You can learn about them by looking at the |
| 100 | +[age module][age module]. |
| 101 | + |
| 102 | + |
9 | 103 | > ##### _Note:_ |
10 | | -> Currently, there is [no mechanism][secrets-issue] in nix to deploy secrets |
11 | | -> within the nix/store so, if they end up in the nix/store after deployment, they |
12 | | -> will be world readable on that machine. |
13 | | -> |
14 | | -> The author of devos intends to implement a workaround for this situation in |
15 | | -> the near future, but for the time being, simple be aware of this. |
| 104 | +> You can take a look at the [agenix repository][agenix] for more information |
| 105 | +> about the tool. |
16 | 106 |
|
17 | 107 | [git-crypt]: https://github.com/AGWA/git-crypt |
| 108 | +[agenix]: https://github.com/ryantm/agenix |
| 109 | +[age module]: https://github.com/ryantm/agenix/blob/master/modules/age.nix |
18 | 110 | [secrets-issue]: https://github.com/NixOS/nix/issues/8 |
0 commit comments