Folds the good parts of #1412 into this PR and addresses both review-bot reviews (#1412 review 1789, #1414 review 1791): - Everything after the OpenBao store is best-effort. Decode, reconnect, listing and revokes run in reap_superseded(); reap_summary() turns any error into "reap skipped" plus a warning, so rotate_ha_token returns Ok. A failed run would start a second pod (backoffLimit: 1) that keeps the token just stored and its successor and reaps the token consumers still hold until ESO syncs, i.e. the #1081 outage. Two unit tests cover it. - Warn when the replaced token is not named "<client_name> [<6 hex>]": no later run reaps it, so it needs a manual revoke (from #1412). - Staged image rollout (from #1412): only the three HA CronJobs carry the flux-system:secret-rotator marker; the other 17 rotators stay on 2026-07-30 until a manual HA run validates the new binary, then a follow-up adds the marker to them. rotation/kustomization.yaml records the exception. - Merged current main (a6f37e2b,1691a0ac): the Reloader annotations for zone-configurator and speech-to-phrase are already there via #1409.
75 lines
3.6 KiB
YAML
75 lines
3.6 KiB
YAML
apiVersion: kustomize.config.k8s.io/v1beta1
|
|
kind: Kustomization
|
|
# Secret-rotation CronJobs + their ServiceAccounts, all in the openbao namespace
|
|
# (intra-namespace OpenBao access → no NetworkPolicy needed). One file per rotated
|
|
# secret. The matching OpenBao policy/role for each lives in ../policies/ and is
|
|
# bootstrapped manually (not GitOps-managed).
|
|
#
|
|
# IMAGE PINNING: dated tags (`:YYYY-MM-DD`), never a digest and never
|
|
# `:latest`. Do NOT switch to digests — untagged manifests in this registry are
|
|
# garbage-collected once the tags move past them, so a pinned digest silently
|
|
# stops resolving after a few unrelated rebuilds of build-ci-images.yml. These
|
|
# jobs are quarterly, so the resulting ImagePullBackOff looks like nothing
|
|
# happening rather than like a failure (#458).
|
|
#
|
|
# Keep every rotator on the same tag: it is one binary containing all modes, so
|
|
# splitting only makes the next bump partial.
|
|
# Exception while staged: only home-assistant.yaml carries the image marker.
|
|
#
|
|
# ADDING A ROTATOR: copy an existing file, and check you did not inherit a
|
|
# digest pin from an older example — nothing enforces this automatically, so it
|
|
# is easy to reintroduce silently and the failure only shows up months later on
|
|
# the first scheduled run:
|
|
#
|
|
# grep -l 'image:.*@sha256' \
|
|
# kubernetes/infrastructure/openbao/rotation/*.yaml | grep -v kustomization.yaml
|
|
#
|
|
# (want: no output. The trailing filter is not padding — this file documents the
|
|
# pattern, so it necessarily matches its own grep. Verified both directions:
|
|
# silent across this directory as it stands, and it still reports a file that
|
|
# actually carries an `image: …@sha256:` pin.)
|
|
#
|
|
# BUMPING the tag: Flux image automation (image-automation/secret-rotator.yaml)
|
|
# moves every `flux-system:secret-rotator` marker to the newest dated tag the
|
|
# registry lists, so only tags that were actually built are ever written. Lines
|
|
# without the marker are bumped by hand; verify the tag exists first:
|
|
#
|
|
# kubectl run tagcheck --rm -i --restart=Never \
|
|
# --image=gitea.renner.uno/gitea_admin/secret-rotator:<DATE> \
|
|
# --command -- /secret-rotator # prints the usage/mode list if the tag resolves
|
|
resources:
|
|
- paperless.yaml
|
|
- woodpecker.yaml
|
|
- shelly-manager.yaml
|
|
- authentik.yaml
|
|
- crowdsec-bouncer-key.yaml
|
|
- netbird-ingress.yaml
|
|
- cloudflare.yaml
|
|
- external-dns.yaml
|
|
- flux-git.yaml
|
|
- home-assistant.yaml
|
|
- ha-config-sync.yaml
|
|
- registry-bot.yaml
|
|
- review-bot.yaml
|
|
- claude-oauth.yaml
|
|
- mosquitto-health.yaml
|
|
# NOT ROTATED, deliberately — recorded here because the whole point of this
|
|
# directory is that unrotated credentials should be a visible choice:
|
|
#
|
|
# homelab/apps/trmnl/renderer → BYOS_ACCESS_TOKEN / BYOS_REFRESH_TOKEN
|
|
# Terminus API JWTs used by the e-ink renderer to push screens. Terminus
|
|
# is configured with API_ACCESS_TOKEN_PERIOD = 10 years
|
|
# (kubernetes/apps/trmnl/terminus.yaml), so nothing will ever expire
|
|
# these or prompt a rotation. That is deliberate: the alternative was
|
|
# holding the Terminus account password in-cluster to mint short-lived
|
|
# tokens per pod start. There is no rotator because minting requires the
|
|
# account password, which is exactly what we declined to store.
|
|
# Rotate BY HAND whenever the Terminus account password changes, by
|
|
# re-running POST /login and re-seeding both keys.
|
|
#
|
|
# HA_ACCESS_TOKEN in the same path is a dedicated Home Assistant
|
|
# long-lived token. `ha-token` mode in secret-rotator already handles
|
|
# this class (see home-assistant.yaml) — enrolling it is a genuine
|
|
# follow-up, not a limitation, and would leave only the BYOS pair
|
|
# unrotated.
|