#0055 is done: ThreadNet-Web be323ed checks in an .npmrc binding @sorb to rohana. The bump that mattered was not the file but what upstream's .gitignore does with it - it ignores /.npmrc, so the naive fix would have stayed local while CI kept resolving against npmjs. Measured in an isolated tree: without the file pnpm goes to npmjs and fails, with it the scope resolves to rohana at the integrity hash the lockfile already carries, and with rohana unreachable the install fails instead of falling back. threadnet-call only publishes and already sets the scope in its own CI; gitops never touches it. ThreadNet-Web was the only consumer. Four issues no longer describe reality, each verified rather than assumed: - #0091 (gitops#61) was fixed when it was written - on_conflict: fail shipped in ef04d86 and the MAS pod has run that config since 2026-08-11T14:08:41Z. Its one deliberate remainder became #0043, which is closed and verified live. - #0079 (gitops#46) asked for the Gitea migration and a central view. The migration ran; the central view was decided the other way round - repo canonical, GitLab mirrored (ADR-0012/0019) - which also answers the reachability trade-off it left open, and better than its three options did. - #0075 (gitops#40) is rejected, not done: it wanted new issues to appear in the Gitea kanban automatically. Issues no longer live in Gitea and the board is script-written. Nothing was accomplished; the question dissolved. - #0098 is a rollout record whose only remainder, the macOS build, is #0022. Three AARs move to harvested - every open item in them is tracked as an issue. Checked and still accurate, so left alone: the wiki branch still exists on both remotes (#0019), docs/TASKS.md and oldwiki/ are still there (#0085), element-web-docs still names live resources (#0086), res/themes/element persists (#0100), only WIKI_CANONIZE_TOKEN is set so TURN rotation still lacks its token (#0084), gameserver still has zero push mirrors (#0032), the broken .6 package is still published (#0101), and options.ts still builds simulcast layers regardless of codec, which is what blocks VP9 (#0057). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
99 lines
4.2 KiB
Markdown
99 lines
4.2 KiB
Markdown
---
|
|
type: issue
|
|
id: "0091"
|
|
status: done
|
|
created: 2026-08-11
|
|
milestone: M1
|
|
priority: high
|
|
area: security
|
|
projekt: gitops
|
|
gitlab_iid: "61"
|
|
related:
|
|
- "docs/adr/0011-enrollment-localpart-kollision-verweigern.md"
|
|
---
|
|
# Enrollment: kollidierender Localpart übernimmt bestehendes Konto (on_conflict: add)
|
|
|
|
> Adoptiert aus [gitops#61](https://git.lab/axion1337.chat/axion1337.chat-gitops/-/issues/61) (2026-08-18, ADR-0019). Kommentare und Verlauf bleiben dort; kanonisch ist ab jetzt diese Datei.
|
|
> Bei der Adoption ergänzt: Meilenstein M1 (fehlte auf GitLab); von den zwei
|
|
> area-Labels trägt das Schema eines — `security` bleibt, `authentik` entfällt.
|
|
|
|
## Befund
|
|
|
|
Der MAS-Upstream-Provider für Authentik verknüpfte eine neu registrierte
|
|
Upstream-Identität mit einem **bestehenden** lokalen Konto, sobald der
|
|
abgeleitete Localpart kollidiert:
|
|
|
|
```yaml
|
|
claims_imports:
|
|
localpart:
|
|
action: force
|
|
template: "{{ user.preferred_username }}"
|
|
on_conflict: add # <-- verknüpft statt abzubrechen
|
|
```
|
|
|
|
Zusammen mit Authentiks Benutzernamen-Eindeutigkeit, die **nur innerhalb von
|
|
Authentik** und **case-sensitive** greift, ergibt sich ein Übernahmeweg:
|
|
|
|
1. Ein Inhaber eines Einladungstokens registriert in Authentik einen Namen, der
|
|
als Matrix-Konto bereits existiert (oder eine Groß-/Kleinschreibungsvariante
|
|
davon — `boje` neben `Boje` ging live durch).
|
|
2. Authentiks Eindeutigkeit meldet keine Kollision, weil das Ziel-Matrix-Konto
|
|
für Authentik unsichtbar ist bzw. sich in der Schreibweise unterscheidet.
|
|
3. Beim ersten Login verknüpft MAS die neue Identität mit dem bestehenden Konto
|
|
— inklusive Räumen und Historie.
|
|
|
|
**Besonders exponiert:** Konten ganz ohne Upstream-Link, weil dort nichts
|
|
vorher da sein muss. Betroffen wären u. a. die Dienstkonten `draupnir`,
|
|
`alerts`, `maintenance-notify` sowie `frank`, `crank`, `shank`, `stank`,
|
|
`bojeledoggo`, `scanner-test`.
|
|
|
|
> Der Übernahmeweg wurde **nicht** aktiv ausprobiert (das wäre eine echte
|
|
> Kontoübernahme gewesen). Die Aussage stützt sich auf MAS' dokumentierte
|
|
> Semantik für `on_conflict` und auf die live reproduzierte case-sensitive
|
|
> Dublette `boje`/`Boje`.
|
|
|
|
## Wie es aufgefallen ist
|
|
|
|
Beim Anlegen eines Testkontos über den Einladungsflow entstand versehentlich
|
|
ein zweites Konto `boje` neben dem bestehenden `Boje` — kein Fehler, keine
|
|
Warnung. Die Nachprüfung der MAS-Claims-Konfiguration legte `on_conflict: add`
|
|
als Ursache offen.
|
|
|
|
## Fix (erledigt)
|
|
|
|
`on_conflict: fail` in `apps/production/custom-configs/mas-secret.yaml` — ein
|
|
kollidierender Localpart bricht die Provisionierung ab, statt zu verknüpfen.
|
|
Bestehende Verknüpfungen bleiben unberührt.
|
|
|
|
Commit `ef04d86`, gepusht nach git.lab. Rollt über Flux aus.
|
|
|
|
## Rest, bewusst offen
|
|
|
|
- **Authentiks case-sensitive Eindeutigkeit** verhindert `boje` neben `Boje`
|
|
weiterhin nicht. Der MAS-Fix fängt die Übernahme ab (Login schlägt fehl statt
|
|
zu verknüpfen), aber der Nutzer bekommt erst beim Login eine Fehlermeldung,
|
|
nicht schon bei der Registrierung. Eine Eindeutigkeitsprüfung (case-insensitive)
|
|
im Prompt-Stage des `matrix-invitation`-Flows wäre die saubere Ergänzung.
|
|
- **Verwaiste Zweitkonten** aus dieser Lücke (`apo2`, das gelöschte `boje`)
|
|
sind Altlasten, keine offene Verwundbarkeit.
|
|
|
|
## Erledigt — nachgetragen beim Relevanz-Durchgang 2026-08-18
|
|
|
|
Das Issue war auf dem Board offen geblieben, obwohl sein Inhalt vollständig
|
|
abgearbeitet ist. Nachgeprüft, nicht erinnert:
|
|
|
|
- **Der Fix ist ausgerollt.** `on_conflict: fail` per Commit `ef04d86`
|
|
(2026-08-11); der MAS-Pod läuft seit `2026-08-11T14:08:41Z` ohne Neustart —
|
|
also mit der geänderten Konfiguration. Das ist wichtig, weil eine
|
|
SOPS-Secret-Änderung den Dienst *nicht* von selbst neu startet (#0044).
|
|
- **Der bewusst offene Rest ist ebenfalls erledigt:** die case-insensitive
|
|
Eindeutigkeitsprüfung im `matrix-invitation`-Prompt-Stage ist als **#0043**
|
|
umgesetzt und am laufenden System verifiziert (Commit `afc4ad3`). Dort ist
|
|
`on_conflict: fail` ausdrücklich als die harte Grenze hinter der Policy
|
|
benannt.
|
|
- **Verwaiste Zweitkonten** (`apo2`, gelöschtes `boje`) waren im Issue selbst
|
|
schon als Altlast eingestuft, nicht als offene Verwundbarkeit.
|
|
|
|
Nichts an diesem Issue ist noch offen. ADR-0011 bleibt die bindende
|
|
Entscheidung dahinter.
|