From 08878fa90feed27803c1e27ffed41f097cc8f2df Mon Sep 17 00:00:00 2001 From: The Dogfather <20+gb_dogfather@noreply.git.farh.net> Date: Thu, 25 Jun 2026 11:57:12 +0000 Subject: [PATCH] docs(adr): ADR-0001 prod authentik-credentials source of truth (GRO-2537) --- ...authentik-credentials source of truth.-.md | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 ADR-0001 prod authentik-credentials source of truth.-.md diff --git a/ADR-0001 prod authentik-credentials source of truth.-.md b/ADR-0001 prod authentik-credentials source of truth.-.md new file mode 100644 index 0000000..b2b62d8 --- /dev/null +++ b/ADR-0001 prod authentik-credentials source of truth.-.md @@ -0,0 +1,34 @@ +# ADR-0001 — Prod `authentik-credentials` source of truth + +- **Status:** Accepted (2026-06-25) +- **Decider:** The Dogfather (CTO) +- **Context issue:** [GRO-2537](https://git.farh.net/groombook/infra) (Paperclip GRO-2537) + +## Context + +`groombook/authentik-credentials` (prod namespace) is consumed by the Flux tf-controller (`Terraform/authentik-prod`, `varsFrom`) to authenticate to `auth.farh.net`. Two writers were competing for the same Secret name: + +1. **Live owner — Emberstack Reflector auto-mirror** from `flux-system/authentik-credentials` (`reflector.v1.k8s.emberstack.com/auto-reflects: "True"`). Healthy; this is what the tf-controller actually reads. Its *source* lives in the externally-managed cluster/bootstrap repo (`flux-system`), not in `groombook/infra`. +2. **In-repo SealedSecret** `apps/overlays/prod/ss-authentik-credentials.yaml`. Decrypts fine after the GRO-2459 namespace-wide re-seal, but **cannot write** the Secret because the name is already owned by the Reflector mirror → perpetual `ErrUnsealFailed` events. + +Prod auth was never down — the events were noise from the redundant second writer. + +## Decision + +**The platform (cluster repo / `flux-system`) is the authoritative distributor of the Authentik token via Reflector** (same pattern used for `groombook-backups`). The in-repo prod SealedSecret duplicates a platform-owned Secret and is **removed** from `groombook/infra`. We do **not** make the in-repo SealedSecret authoritative, because that would require killing the Reflector source in the externally-managed cluster repo. + +Rejected alternatives: +- **`kubectl delete secret`** — Reflector re-creates within seconds; flaps against a healthy prod secret. (Cancelled GRO-2466.) +- **Add `sealedsecrets.bitnami.com/managed: "true"`** — would still fight the Reflector mirror for ownership; dual-source persists. +- **Cluster-repo PR to kill the Reflector source** — valid but out of scope; only pursued via the escape hatch if the Reflector source proves non-durable. + +## Consequences + +- `ErrUnsealFailed` noise stops; single source of truth (platform Reflector) for the prod token. +- `groombook/infra` no longer carries a prod Authentik SealedSecret; future rotations are a platform concern. +- Dependency on the platform keeping `flux-system/authentik-credentials` durable. If that ever changes, revisit (cluster-repo PR to re-home the source). + +## Related + +- Implemented via GRO-2465 (groombook/infra PR removing `ss-authentik-credentials.yaml`). +- Supersedes/closes: GRO-2457 (triage), GRO-2459 (re-seal), GRO-2466 (cancelled manual delete).