--- type: adr id: "0011" status: accepted date: 2026-08-11 supersedes: null superseded_by: null related: [] --- # 0011 — Provisionierung verweigert Localpart-Kollisionen, statt an bestehende Konten zu verknüpfen **Status:** akzeptiert · **Datum:** 2026-08-11 · **Entscheider:** sorb ## Kontext Der MAS-Upstream-Provider für Authentik stand auf `claims_imports.localpart.on_conflict: add`. MAS-Semantik: Kollidiert der aus dem Authentik-Claim abgeleitete Localpart mit einem **bestehenden** Matrix-Konto, verknüpft MAS die neue Upstream-Identität mit diesem Konto — ohne Abbruch, ohne Warnung. Authentiks eigene Benutzernamen-Eindeutigkeit fängt das nicht ab: sie gilt nur innerhalb von Authentik und ist case-sensitive (`boje` neben `Boje` ging live durch). Folge: Ein Inhaber eines Einladungstokens konnte einen (auch nur in der Schreibweise abweichenden) Namen eines bestehenden Kontos registrieren und würde beim ersten Login in dessen Konto verknüpft — inklusive Dienstkonten ohne Upstream-Link (`draupnir`, `alerts`, `maintenance-notify`). Das ist ein Kontoübernahme-Vektor, entdeckt am 2026-08-11 beim Anlegen eines Testkontos ([gitops#61](https://git.lab/axion1337.chat/axion1337.chat-gitops/-/issues/61)). ## Entscheidung **Identitäts-Provisionierung verknüpft eine neue Upstream-Identität niemals mit einem bereits bestehenden lokalen Konto.** Konkret: `on_conflict: fail` im `claims_imports.localpart`-Block des MAS-Upstream-Providers (`gitops/apps/production/custom-configs/mas-secret.yaml`). Ein kollidierender Localpart bricht die Provisionierung ab. Dies ist ab jetzt stehende Regel, nicht nur der aktuelle Wert — jede künftige Änderung an diesem Verhalten braucht ein ablösendes ADR. ## Konsequenzen - **Besser:** Der Übernahme-Weg ist geschlossen. Bestehende Konten (besonders die ohne Upstream-Link) können nicht mehr durch eine kollidierende Neuregistrierung gekapert werden. Bestehende, korrekte Verknüpfungen bleiben unberührt. - **In Kauf genommen:** Ein Nutzer, der einen bereits vergebenen Namen wählt, erhält die Fehlermeldung erst **beim Login** (wenn MAS provisioniert), nicht schon bei der Registrierung in Authentik. Das ist eine schlechtere UX, aber kein Sicherheitsproblem. - **Jetzt Pflicht:** - Als offene Härtung eine **case-insensitive Eindeutigkeitsprüfung im `matrix-invitation`-Prompt-Stage**, damit die Kollision schon bei der Registrierung sichtbar wird (verfolgt in gitops#61). - **Nach jeder Änderung an einem SOPS-verwalteten Values-Secret den konsumierenden Dienst per `rollout restart` neu ausrollen und verifizieren**, dass der Pod jünger als die Änderung ist. Beim Ausrollen dieses Fixes lief MAS noch mit der alten Config im Speicher, obwohl das Secret bereits `fail` zeigte — „committet" ≠ „deployed" ≠ „aktiv" (MAS liest Config nur beim Start). ## Verworfene Alternativen - **`on_conflict: add` belassen und allein auf Authentiks Eindeutigkeit vertrauen** — verworfen: die greift nur innerhalb Authentiks und case-sensitive, deckt Kollisionen mit vorbestehenden Matrix-Konten also nicht ab. - **Nur den Prompt-Stage-Check bauen, MAS auf `add` lassen** — verworfen: der Client-seitige Check ist umgehbar (direkter Flow-Aufruf), der MAS-seitige Abbruch ist die eigentliche Sicherheitsgrenze. Der Prompt-Check ist die UX-Ergänzung, nicht der Schutz. - **Betroffene Dienstkonten einfach mit Upstream-Links versehen** — verworfen: behandelt nur das Symptom für heute bekannte Konten, nicht den Mechanismus.