--- type: issue id: "0044" status: done created: 2026-08-11 milestone: M5 priority: low area: infrastructure related: [docs/adr/0011-enrollment-localpart-kollision-verweigern.md] --- # SOPS-Values-Secret-Änderung startet den konsumierenden Dienst nicht neu ## Problem / Motivation Beim Ausrollen des `on_conflict: fail`-Fixes (ADR-0011) trat ein Footgun zutage: Flux aktualisierte das SOPS-verwaltete Secret `ess-mas-values-secret`, aber der laufende MAS-Pod war älter als die Änderung und behielt die alte Config im Speicher — MAS liest seine Config nur beim Start. Der Sicherheits-Fix stand auf der Platte, war im Prozess aber **nicht aktiv**, bis ein manueller `kubectl rollout restart` folgte. „committet ≠ deployed ≠ aktiv." Das betrifft nicht nur MAS: jeder Dienst, der ein von Flux/SOPS gepflegtes Values-Secret nur beim Start liest, hat dieselbe stille Lücke. Aktuell ist die einzige Absicherung die in ADR-0011 festgeschriebene **manuelle** Restart-und- Verifikations-Regel — leicht zu vergessen. ## Acceptance - Änderungen an einem konsumierten Values-Secret lösen automatisch einen Rollout des abhängigen Deployments aus (z. B. Checksum-/Hash-Annotation auf dem Pod-Template, ein Reloader wie stakater/Reloader, oder ein `configMapGenerator`/`secretGenerator`-Namenshash in kustomize). - Verifiziert an MAS: Änderung am Secret → neuer Pod ohne Handeingriff, jünger als die Änderung. - Mindestens MAS abgedeckt; idealerweise als wiederverwendbares Muster für weitere von SOPS-Secrets gespeiste Dienste. ## Notes Automatisiert nur den bereits in ADR-0011 vorgeschriebenen manuellen Schritt — daher `priority: low`. M5, weil die Fähigkeit (Auto-Reload) neu ist, nicht kaputt. ## Untersuchung 2026-08-15 — die Abdeckung ist deutlich besser als angenommen Vor dem Einbau eines Reloaders geprüft, wo die Lücke **tatsächlich** klafft. Ergebnis: der im Issue beschriebene Fall (MAS) ist bereits abgedeckt, und zwar von der Chart selbst. **MAS ist abgedeckt — verifiziert am laufenden Deployment.** Die ESS-Chart hängt Prüfsummen als **Labels** ans Pod-Template (`templates/matrix-authentication-service/deployment.yaml`): ``` k8s.element.io/matrix-authentication-service-config-hash: sha1sum(configmap-data) k8s.element.io/matrix-authentication-service-secret-hash: sha1sum(secret-data) ``` Ein geändertes Label ändert das Pod-Template — Kubernetes rollt also von selbst aus. Live vorhanden (drei Hash-Labels am MAS-Deployment). Und der HelmRelease steht auf `interval: 1m`, Flux liest `valuesFrom` also jede Minute neu ein und rendert bei Änderung neu. **Damit ist die Ursachenannahme des Issues zu korrigieren:** Der Mechanismus fehlte nicht. Wahrscheinlicher ist, dass beim ADR-0011-Vorfall innerhalb des ersten Reconcile-Fensters geprüft wurde — „committet ≠ deployed" stimmt, aber die Lücke war **zeitlich**, nicht strukturell. Das ändert nichts an der Richtigkeit der ADR-0011-Regel (nach einem Sicherheits-Fix aktiv verifizieren), wohl aber an der Diagnose. **Abdeckung im Überblick** (Hash-Labels am Pod-Template gezählt): | Abgedeckt | wodurch | |---|---| | MAS (3), element-web (2), haproxy (3), matrix-rtc (1–2) | ESS-Chart-Hash-Labels | | coturn + Synapse (TURN-Secret) | eigener Mechanismus: der Rotations-CronJob hebt `rotated-at`/Checksum-Annotationen, der Merge startet beide Verbraucher neu (#38) | | Nicht abgedeckt | konsumiertes Secret | |---|---| | `draupnir` | `draupnir-config` | | `wikijs` | `wikijs-postgres-secret` | | `concierge-bot` | `concierge-credentials` | **Bewertung.** Übrig bleiben drei Dienste mit Secrets, die sich **selten und stets absichtlich** ändern — anders als das monatlich rotierende TURN-Secret, das genau deshalb bereits einen eigenen Trigger hat. Ein zusätzlicher Controller (stakater/Reloader) bräuchte Rechte, Deployments zu patchen, und würde eine Dauerkomponente für ein Risiko einführen, das bei den wirklich bewegten Secrets bereits gelöst ist. **Empfehlung: nicht einbauen**, sondern diese Abdeckungskarte als Ergebnis festhalten und die ADR-0011-Regel (aktiv verifizieren) für die drei Nachzügler gelten lassen. Wer anderer Meinung ist, hat mit Reloader einen sauberen Weg — die Chart erlaubt Annotationen je Komponente (`matrixAuthenticationService.annotations`, schema-geprüft), sie landen am Deployment **und** am Pod-Template. ## Geschlossen 2026-08-15 — Entscheidung sorb: kein Reloader Die Abdeckungskarte oben ist das Ergebnis; ein zusätzlicher Controller wird **bewusst nicht** eingebaut. **Begründung.** Das Ziel des Issues — „Änderungen an einem konsumierten Values-Secret lösen automatisch einen Rollout aus" — ist für die Dienste, bei denen sich Secrets real bewegen, **bereits erfüllt**, nur anders als vermutet: - **MAS und die übrigen ESS-Komponenten** über die Hash-Labels der Chart am Pod-Template (live verifiziert), zusammen mit `interval: 1m` am HelmRelease. - **coturn und Synapse** über den `rotated-at`-Bump des Rotations-CronJobs — der einzige Fall mit regelmäßiger, unbeaufsichtigter Secret-Änderung, und genau deshalb schon gelöst (#38). Übrig bleiben `draupnir`, `wikijs` und `concierge-bot`: Secrets, die sich **selten und stets durch bewusstes Handeln** ändern — also in dem Moment, in dem ohnehin jemand hinschaut und die ADR-0011-Regel (aktiv verifizieren) greift. Dafür einen Dauer-Controller mit Rechten, beliebige Deployments zu patchen, in die Produktion zu stellen, ist der schlechtere Tausch: bleibende Angriffsfläche und Wartungslast gegen ein Restrisiko, das genau dort klein ist, wo es zählt. **Das eigentliche Ergebnis dieses Issues ist die Karte, nicht der Einbau.** Vorher wusste niemand, dass MAS abgedeckt ist — die Annahme war das Gegenteil, und ein Reloader wäre auf ein bereits gelöstes Problem gesetzt worden. **Falls die Entscheidung später kippt** (etwa wenn ein Dienst dazukommt, dessen Secret automatisiert rotiert): Der Weg ist vorbereitet — die ESS-Chart erlaubt Annotationen je Komponente (`matrixAuthenticationService.annotations`, schema-geprüft), und sie landen sowohl am Deployment als auch am Pod-Template, also genau dort, wo stakater/Reloader sie liest.