Files
management/docs/adr/0011-enrollment-localpart-kollision-verweigern.md
T
Thore CimbalandClaude Fable 5 70e81e2ff1 feat: slice 2 - all eleven decisions ported to docs/adr
Gate 4, slice 2: decisions/0001-0011 moved via git mv with schema
frontmatter prepended (status and date taken from each body's own
Status line - 0007 stays proposed, its decision is open in #20; bodies
unchanged except relative links gaining one directory level). The old
scheme's README and template retire - their rules already live in
AGENTS.md section 6 and the neckbeard ADR template. Every reference to
decisions/ across the tree retargeted (root files, not-yet-moved
verfahren/hosts/shared files, design doc and session ADR frontmatter).

Verified: validate 0 errors (11 ported + 2 session ADRs + duplicate-id
guard), gen_status --check current with all 13 ADRs listed, drift
check 0 findings, negative test shows a cloned id 0012 firing the
duplicate check.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 12:00:00 +00:00

3.5 KiB

type, id, status, date, supersedes, superseded_by, related
type id status date supersedes superseded_by related
adr 0011 accepted 2026-08-11 null null

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).

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.