From 5771c14249eb22092cde15388605b958d71b1ebe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20=E2=80=9CNiols=E2=80=9D=20Jeannerod?= Date: Wed, 11 Dec 2024 13:26:38 +0100 Subject: [PATCH] Set up a first secret --- README.md | 3 ++ flake.nix | 1 + secrets/README.md | 49 ++++++++++++++++++++++++++++++++ secrets/forgejo-runner-token.age | 11 +++++++ secrets/secrets.nix | 43 ++++++++++++++++++++++++++++ 5 files changed, 107 insertions(+) create mode 100644 secrets/README.md create mode 100644 secrets/forgejo-runner-token.age create mode 100644 secrets/secrets.nix diff --git a/README.md b/README.md index c87beb5..77e15fe 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,9 @@ details as to what they are for. As an overview: - [`matrix/`](./matrix) contains everything having to do with setting up a fully-featured Matrix server. +- [`secrets/`](./secrets) contains the secrets that need to get injected into + machine configurations. + - [`server/`](./server) contains the configuration of the VM hosting the website. This should be integrated into `infra/` shortly in the future, as tracked in https://git.fediversity.eu/Fediversity/Fediversity/issues/31. diff --git a/flake.nix b/flake.nix index ca28251..4cdf14e 100644 --- a/flake.nix +++ b/flake.nix @@ -48,6 +48,7 @@ optin = [ "deployment" "infra" + "secrets" "services" ]; files = "^((" + concatStringsSep "|" optin + ")/.*\\.nix|[^/]*\\.nix)$"; diff --git a/secrets/README.md b/secrets/README.md new file mode 100644 index 0000000..8c3a4c1 --- /dev/null +++ b/secrets/README.md @@ -0,0 +1,49 @@ +# 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. diff --git a/secrets/forgejo-runner-token.age b/secrets/forgejo-runner-token.age new file mode 100644 index 0000000..a0e126a --- /dev/null +++ b/secrets/forgejo-runner-token.age @@ -0,0 +1,11 @@ +age-encryption.org/v1 +-> ssh-ed25519 1MUEqQ 5Bvi8UvLbifM2vlDOr4NRaZLRfIg6kAPY0oiwiSy50o +TnbS5BHO4hmjs7Ux9rRMzK9ahsIkU9GpmAx59MzIpI0 +-> ssh-ed25519 h0QWFg 4Cu85VZM6zyysIYwMFccXUWUGejkylHiytJA4+2nN1Q +e8XuOUfrOZ6xoWNK4gvVgs0H5pgtqUfrv/DBeh1WIsU +-> ssh-ed25519 pJV4iw JQgQMTxfDZ/26In72UHPU+k0ZGBK1DRQWoOwfxS0xwI +8De1c3d95ySwjqjQn9rHlYDfMDTHct1kbyjVx+8EZyA +--- neht26C0cEHeTGVa+epEwoO+oqXvyO94xwp25zAX6wY +DN+VU8ؼQvҐA~+āLw`EXfV0@qHj +RGOY +.?D9O[%\ \ No newline at end of file diff --git a/secrets/secrets.nix b/secrets/secrets.nix new file mode 100644 index 0000000..3ef18c8 --- /dev/null +++ b/secrets/secrets.nix @@ -0,0 +1,43 @@ +let + pkgs = import { system = builtins.currentSystem; }; + inherit (pkgs.lib.attrsets) concatMapAttrs; + + ############################################################################## + ## Contributor personal keys + ## + ## All the contributors in this list WILL be able to decrypt ALL the encrypted + ## `.age` files. + + contributors = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEElREJN0AC7lbp+5X204pQ5r030IbgCllsIxyU3iiKY niols@wallace" + ]; + + ############################################################################## + ## System host keys + ## + ## Machines in this list MAY be mentioned later on as able to decrypt some of + ## the encrypted `.age` files. + + vm02179 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPAsOCOsJ0vNL9fGj0XC25ir8B+k2NlVJzsiVUx+0eWM"; + vm02186 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII6mnBgEeyYE4tzHeFNHVNBV6KR+hAqh3PYSqlh0QViW"; + + ############################################################################## + +in +concatMapAttrs + (name: keys: { + "${name}.age".publicKeys = contributors ++ keys; + }) + + ############################################################################## + ## File name <-> system host keys mapping + ## + ## This attribute set defines precisely which secrets exist and which systems + ## are able to decrypt them. + + { + forgejo-runner-token = [ + vm02179 + vm02186 + ]; + }