# Secrets

Secrets are handled using [Agenix](https://github.com/ryantm/agenix).

## Cheat sheet

### Adding a secret

As an example, let us add a secret in a file “cheeses” whose content should be
“best ones come unpasteurised”.

1. Edit [`secrets.nix`](./secrets.nix), adding a field to the final record with
   the file name mapped to the systems that should be able to decrypt the
   secret, for instance:
   ```nix
   cheeses = [ vm02116 forgejo-ci ];
   ```

2. Run Agenix to add the content of the file. Agenix is provided by the
   development Shell but can also be run directly with `nix run
   github:ryantm/agenix --`. Run `agenix -e cheeses.age` (with the `.age`
   extension); this will open your `$EDITOR` ; enter “best ones come
   unpasteurised”, save and close.

3. If you are doing something flake-related such as NixOps4, do not forget to
   commit or at least stage the secret.

4. In the machine's configuration, load the Agenix NixOS module, declare your
   secret, possibly with owner/group, and use it where necessary, eg.:
   ```nix
   { config, ... }:
   {
     imports = [ inputs.agenix.x86_64-linux.nixosModules.default ];
     age.secrets.cheeses.file = ../secrets/cheeses.age;
     # age.secrets.cheeses.owner = "jeanpierre";
     # age.secrets.cheeses.group = "france";
     # age.secrets.cheeses.mode = "440";
     services.imaginaryCheeseFactory.frenchSecretFile = config.age.secrets.cheeses.path;
   }
   ```

5. Never read the content of the file in Nix, that is never do anything like:
   ```nix
   services.imaginaryCheeseFactory.frenchSecret = readFile config.age.secrets.cheeses.path;
   ```
   This will put the secret as a world-readable file in the Nix store. The
   service that you are using must be able to read from a file at runtime, and
   if the NixOS default module options do not provide that, you must find a way
   around it.