2021-02-14 02:38:20 +00:00
|
|
|
# Secrets
|
2022-11-20 22:28:23 +00:00
|
|
|
|
2021-10-24 17:36:56 +00:00
|
|
|
Secrets are managed using [agenix][agenix]
|
2021-05-13 17:35:41 +00:00
|
|
|
so you can keep your flake in a public repository like GitHub without
|
|
|
|
exposing your password or other sensitive data.
|
2021-02-14 02:38:20 +00:00
|
|
|
|
2021-05-13 17:35:41 +00:00
|
|
|
## Agenix
|
2022-11-20 22:28:23 +00:00
|
|
|
|
2021-05-13 17:35:41 +00:00
|
|
|
Currently, there is [no mechanism][secrets-issue] in nix itself to deploy secrets
|
|
|
|
within the nix store because it is world-readable.
|
|
|
|
|
|
|
|
Most NixOS modules have the ability to set options to files in the system, outside
|
|
|
|
the nix store, that contain sensitive information. You can use [agenix][agenix]
|
|
|
|
to easily setup those secret files declaratively.
|
|
|
|
|
|
|
|
[agenix][agenix] encrypts secrets and stores them as .age files in your repository.
|
|
|
|
Age files are encrypted with multiple ssh public keys, so any host or user with a
|
|
|
|
matching ssh private key can read the data. The [age module][age module] will add those
|
2022-02-17 16:15:02 +00:00
|
|
|
encrypted files to the nix store and decrypt them on activation to `/run/agenix`.
|
2021-05-13 17:35:41 +00:00
|
|
|
|
|
|
|
### Setup
|
2022-11-20 22:28:23 +00:00
|
|
|
|
2021-05-13 17:35:41 +00:00
|
|
|
All hosts must have openssh enabled, this is done by default in the core profile.
|
|
|
|
|
|
|
|
You need to populate your `secrets/secrets.nix` with the proper ssh public keys.
|
|
|
|
Be extra careful to make sure you only add public keys, you should never share a
|
|
|
|
private key!!
|
|
|
|
|
|
|
|
secrets/secrets.nix:
|
2022-11-20 22:28:23 +00:00
|
|
|
|
2021-05-13 17:35:41 +00:00
|
|
|
```nix
|
|
|
|
let
|
|
|
|
system = "<system ssh key>";
|
|
|
|
user = "<user ssh key>";
|
|
|
|
allKeys = [ system user ];
|
|
|
|
in
|
|
|
|
```
|
|
|
|
|
|
|
|
On most systems, you can get your systems ssh public key from `/etc/ssh/ssh_host_ed25519_key.pub`. If
|
|
|
|
this file doesn't exist you likely need to enable openssh and rebuild your system.
|
|
|
|
|
|
|
|
Your users ssh public key is probably stored in `~/.ssh/id_ed25519.pub` or
|
|
|
|
`~/.ssh/id_rsa.pub`. If you haven't generated a ssh key yet, be sure do so:
|
2022-11-20 22:28:23 +00:00
|
|
|
|
2021-05-13 17:35:41 +00:00
|
|
|
```sh
|
|
|
|
ssh-keygen -t ed25519
|
|
|
|
```
|
|
|
|
|
|
|
|
> ##### _Note:_
|
2022-11-20 22:28:23 +00:00
|
|
|
>
|
2021-05-13 17:35:41 +00:00
|
|
|
> The underlying tool used by agenix, rage, doesn't work well with password protected
|
|
|
|
> ssh keys. So if you have lots of secrets you might have to type in your password many
|
|
|
|
> times.
|
|
|
|
|
|
|
|
### Secrets
|
2022-11-20 22:28:23 +00:00
|
|
|
|
2021-05-13 17:35:41 +00:00
|
|
|
You will need the `agenix` command to create secrets. DevOS conveniently provides that
|
|
|
|
in the devShell, so just run `nix develop` whenever you want to edit secrets. Make sure
|
|
|
|
to always run `agenix` while in the `secrets/` folder, so it can pick up your `secrets.nix`.
|
|
|
|
|
|
|
|
To create secrets, simply add lines to your `secrets/secrets.nix`:
|
2022-11-20 22:28:23 +00:00
|
|
|
|
2021-05-13 17:35:41 +00:00
|
|
|
```
|
|
|
|
let
|
|
|
|
...
|
|
|
|
allKeys = [ system user ];
|
|
|
|
in
|
|
|
|
{
|
|
|
|
"secret.age".publicKeys = allKeys;
|
|
|
|
}
|
|
|
|
```
|
2022-11-20 22:28:23 +00:00
|
|
|
|
2021-05-13 17:35:41 +00:00
|
|
|
That would tell agenix to create a `secret.age` file that is encrypted with the `system`
|
|
|
|
and `user` ssh public key.
|
|
|
|
|
|
|
|
Then go into the `secrets` folder and run:
|
2022-11-20 22:28:23 +00:00
|
|
|
|
2021-05-13 17:35:41 +00:00
|
|
|
```sh
|
|
|
|
agenix -e secret.age
|
|
|
|
```
|
2022-11-20 22:28:23 +00:00
|
|
|
|
2021-05-13 17:35:41 +00:00
|
|
|
This will create the `secret.age`, if it doesn't already exist, and allow you to edit it.
|
|
|
|
|
|
|
|
If you ever change the `publicKeys` entry of any secret make sure to rekey the secrets:
|
2022-11-20 22:28:23 +00:00
|
|
|
|
2021-05-13 17:35:41 +00:00
|
|
|
```sh
|
|
|
|
agenix --rekey
|
|
|
|
```
|
|
|
|
|
|
|
|
### Usage
|
2022-11-20 22:28:23 +00:00
|
|
|
|
2021-05-13 17:35:41 +00:00
|
|
|
Once you have your secret file encrypted and ready to use, you can utilize the [age module][age module]
|
|
|
|
to ensure that your secrets end up in `/run/secrets`.
|
|
|
|
|
|
|
|
In any profile that uses a NixOS module that requires a secret you can enable a particular secret like so:
|
|
|
|
|
|
|
|
```nix
|
|
|
|
{ self, ... }:
|
|
|
|
{
|
|
|
|
age.secrets.mysecret.file = "${self}/secrets/mysecret.age";
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2022-01-09 08:14:24 +00:00
|
|
|
Then you can just pass the path `/run/agenix/mysecret` to the module.
|
2021-05-13 17:35:41 +00:00
|
|
|
|
|
|
|
You can make use of the many options provided by the age module to customize where and how
|
|
|
|
secrets get decrypted. You can learn about them by looking at the
|
|
|
|
[age module][age module].
|
|
|
|
|
2021-02-14 02:38:20 +00:00
|
|
|
> ##### _Note:_
|
2022-11-20 22:28:23 +00:00
|
|
|
>
|
2021-05-13 17:35:41 +00:00
|
|
|
> You can take a look at the [agenix repository][agenix] for more information
|
|
|
|
> about the tool.
|
2021-02-14 02:38:20 +00:00
|
|
|
|
2021-05-13 17:35:41 +00:00
|
|
|
[agenix]: https://github.com/ryantm/agenix
|
|
|
|
[age module]: https://github.com/ryantm/agenix/blob/master/modules/age.nix
|
2021-02-14 02:38:20 +00:00
|
|
|
[secrets-issue]: https://github.com/NixOS/nix/issues/8
|