From 5fd42fbdcdc5bb18976b940d8b8ba85bdecc64e2 Mon Sep 17 00:00:00 2001 From: lyrathorpe Date: Mon, 6 Jul 2026 13:57:30 +0100 Subject: [PATCH] docs(secrets): agenix owner workflow --- secrets/README.md | 92 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 secrets/README.md diff --git a/secrets/README.md b/secrets/README.md new file mode 100644 index 0000000..2bfccb5 --- /dev/null +++ b/secrets/README.md @@ -0,0 +1,92 @@ +# Secrets (agenix) + +Encrypted secrets for the fleet, managed with [agenix](https://github.com/ryantm/agenix). + +Each secret is an age-encrypted file (`*.age`) encrypted to a set of recipient +public keys declared in [`secrets.nix`](./secrets.nix). A host decrypts its +secrets at activation using its SSH **host** key +(`/etc/ssh/ssh_host_ed25519_key`), so every host that must read a secret has to +be listed as a recipient for it. + +`secrets.nix` is read only by the `agenix` CLI. It is never imported into the +NixOS evaluation. + +## Secrets in this repo + +| File | Purpose | Recipients | +| --------------- | ----------------------------------------------------------------------- | ----------------------------------- | +| `ldap-bind.age` | SSSD → Authentik LDAP bind credential, as an `sssd.conf` drop-in snippet | all SSSD-enabled hosts (not EDaaS) | + +Consumed by [`modules/sssd.nix`](../modules/sssd.nix) via +`age.secrets.ldap-bind.path`, which places the decrypted snippet at +`/etc/sssd/conf.d/01-ldap-authtok.conf`. + +> **`ldap-bind.age` is not committed yet.** Only `ldap-bind.age.PLACEHOLDER` +> ships in this change (real host recipient keys and the real password were not +> available when it was written). Follow the steps below to create the real +> secret, then delete the `.PLACEHOLDER`. + +## Owner setup checklist + +Run these once (per new host or when the bind password rotates): + +### 1. Collect host recipient keys + +On each SSSD-enabled host (all Linux hosts **except** EDaaS): + +```sh +cat /etc/ssh/ssh_host_ed25519_key.pub +``` + +Paste each value into the matching placeholder in `secrets.nix`, replacing the +`AAAA_PLACEHOLDER_REPLACE_ME_*` strings. (Optionally uncomment and set `admin` +to an operator user key so the secret can be edited off-host.) + +### 2. Encrypt the bind password + +The plaintext must be a **full sssd.conf drop-in snippet**, because SSSD cannot +read `ldap_default_authtok` from a separate file — it only merges `conf.d/*.conf`. +The content is exactly: + +```ini +[domain/default] +ldap_default_authtok = +``` + +Use the password of the `sssd-bind` (Terraform: `sssd-bind`) Authentik LDAP +service account. Then, from the repo root: + +```sh +# Requires the agenix CLI: `nix run github:ryantm/agenix -- -e secrets/ldap-bind.age` +cd secrets +agenix -e ldap-bind.age +``` + +An `$EDITOR` opens; paste the two-line snippet above, save, quit. agenix writes +the encrypted `ldap-bind.age`. Commit it and delete `ldap-bind.age.PLACEHOLDER`. + +### 3. Rekey after changing recipients + +If you add/remove hosts in `secrets.nix`, re-encrypt every secret to the new +recipient set: + +```sh +cd secrets +agenix -r +``` + +### 4. DNS + +`ldap.lyrapup.pet` must resolve to the Authentik LDAP outpost and serve LDAPS on +port 636 with a certificate the hosts trust (`ldap_tls_reqcert = demand`). If the +cert is not from a system-trusted CA, add it to the hosts' trust store +(`security.pki.certificateFiles`) or relax `ldap_tls_reqcert` in +`modules/sssd.nix`. + +### 5. Rebuild + +```sh +sudo nixos-rebuild switch --flake .# +``` + +Verify with `getent passwd ` and `id `.