docs(secrets): agenix owner workflow
This commit is contained in:
@@ -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 = <the sssd-bind service-account password>
|
||||
```
|
||||
|
||||
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 .#<host>
|
||||
```
|
||||
|
||||
Verify with `getent passwd <ldap-user>` and `id <ldap-user>`.
|
||||
Reference in New Issue
Block a user