Nereus/deploy/secrets/README.md

66 lines
2.6 KiB
Markdown

# Secrets
`nereus-db` holds two keys, used by `postgres.yaml` and `rollout.yaml`:
- `POSTGRES_PASSWORD`
- `DATABASE_URL``postgres://nereus:<password>@nereus-postgres:5432/nereus?sslmode=disable`
It is not in `base/kustomization.yaml`. Plaintext never lands in the repo, and
gitleaks runs on every push.
## dev (k3d)
Create it directly, before `kubectl apply -k deploy/overlays/dev`:
```fish
set pw (openssl rand -hex 16)
kubectl create secret generic nereus-db -n nereus \
--from-literal=POSTGRES_PASSWORD=$pw \
--from-literal=DATABASE_URL="postgres://nereus:$pw@nereus-postgres:5432/nereus?sslmode=disable"
```
Rotating means deleting the secret, the StatefulSet's PVC, and restarting —
Postgres only reads `POSTGRES_PASSWORD` when it initialises the data directory.
## prod (sealed)
Install the controller through `terraform/platform` first. It is named
`sealed-secrets-controller`, which is the default expected by `kubeseal`.
Create the database Secret locally and pipe it straight into `kubeseal`. The
plaintext exists only in the pipeline and the password variable:
```bash
db_password="$(openssl rand -hex 16)"
kubectl create secret generic nereus-db --namespace nereus \
--from-literal=POSTGRES_PASSWORD="$db_password" \
--from-literal=DATABASE_URL="postgres://nereus:${db_password}@nereus-postgres:5432/nereus?sslmode=disable" \
--dry-run=client -o yaml | \
kubeseal --format yaml >deploy/secrets/nereus-db-sealed.yaml
unset db_password
```
Commit only `nereus-db-sealed.yaml` and add it to the prod overlay. Back up the
controller key outside the repository before relying on sealed secrets for
recovery. Losing that key makes every committed `SealedSecret` undecryptable.
## Discord alert routing
Alertmanager reads its Discord webhook from the `nereus-discord` Secret as a
mounted file. Create the webhook in Discord, keep it in the shell environment,
and seal it without writing plaintext to disk:
```bash
test -n "${DISCORD_WEBHOOK_URL:-}"
printf '%s' "$DISCORD_WEBHOOK_URL" | \
kubectl create secret generic nereus-discord --namespace observability \
--from-file=webhook-url=/dev/stdin --dry-run=client -o yaml | \
kubeseal --format yaml >deploy/secrets/nereus-discord-sealed.yaml
unset DISCORD_WEBHOOK_URL
```
Apply the sealed secret, confirm it produced the `nereus-discord` Secret, then
set `enable_discord = true` in the platform Terraform variables and apply
again. Discord routing defaults off so a missing owner-provided webhook cannot
stop Alertmanager from starting. The committed opt-in values route warning and
critical Nereus alerts to Discord and discard alerts that do not match.