2026-08-16 12:00:00 +00:00
|
|
|
---
|
|
|
|
|
type: issue
|
|
|
|
|
id: "0055"
|
2026-08-18 12:00:00 +00:00
|
|
|
status: done
|
2026-08-16 12:00:00 +00:00
|
|
|
created: 2026-08-16
|
|
|
|
|
milestone: M2
|
|
|
|
|
priority: medium
|
|
|
|
|
area: security
|
|
|
|
|
related:
|
|
|
|
|
- "docs/issues/0054-ki-geraeuschunterdrueckung-element-call.md"
|
|
|
|
|
- "docs/adr/0018-ki-geraeuschunterdrueckung-clientseitig-opt-in.md"
|
|
|
|
|
- "docs/adr/0001-gitlab-kanonisch-push-mirror.md"
|
2026-08-18 12:00:00 +00:00
|
|
|
gitlab_iid: "39"
|
2026-08-16 12:00:00 +00:00
|
|
|
---
|
|
|
|
|
|
|
|
|
|
# Issue-0055: `@sorb`-Scope in ThreadNet-Web ist nirgends auf rohana festgelegt
|
|
|
|
|
|
|
|
|
|
## Problem / Motivation
|
|
|
|
|
|
|
|
|
|
`ThreadNet-Web` bezieht `@sorb/threadnet-call-embedded` aus der Gitea-npm-Registry auf rohana,
|
|
|
|
|
aber **im Repo steht nirgends, dass der Scope `@sorb` dorthin zeigt**. Es gibt weder eine
|
|
|
|
|
`.npmrc` im Wurzelverzeichnis noch in `apps/web`, und die CI setzt auch keine.
|
|
|
|
|
|
|
|
|
|
Dass es trotzdem funktioniert, liegt allein am Lockfile: `pnpm-lock.yaml` pinnt die vollständige
|
|
|
|
|
Tarball-URL
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
tarball: https://rohana.axion1337.de/api/packages/sorb/npm/%40sorb%2F…tgz
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
und die CI installiert mit `--frozen-lockfile`. Solange niemand die Version anhebt, wird der
|
|
|
|
|
Scope nie aufgelöst — und der fehlende Eintrag fällt nicht auf.
|
|
|
|
|
|
|
|
|
|
Aufgefallen beim Anheben auf `0.19.2-threadnet.8` (#0054): `pnpm install` griff nach
|
|
|
|
|
`registry.npmjs.org` und brach ab.
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
ERR_PNPM_FETCH_404 GET https://registry.npmjs.org/@sorb%2Fthreadnet-call-embedded: Not Found
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Die Anhebung ging nur durch, weil der Scope für diesen einen Aufruf von Hand gesetzt wurde:
|
|
|
|
|
|
|
|
|
|
```sh
|
|
|
|
|
env 'npm_config_@sorb:registry=https://rohana.axion1337.de/api/packages/sorb/npm/' pnpm install
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Das steht in keiner Doku. Der nächste, der die Abhängigkeit anhebt, läuft in dieselbe Wand.
|
|
|
|
|
|
|
|
|
|
## Warum das mehr ist als eine Unbequemlichkeit
|
|
|
|
|
|
|
|
|
|
Der heutige Fehlschlag ist **laut** — 404, Abbruch, niemand baut versehentlich etwas Falsches.
|
|
|
|
|
Laut ist gut. Der Punkt ist, dass die Lautstärke von einer Bedingung abhängt, die uns nicht
|
|
|
|
|
gehört: `@sorb/threadnet-call-embedded` existiert auf `registry.npmjs.org` **derzeit nicht**.
|
|
|
|
|
|
|
|
|
|
Registriert dort jemand diesen Namen, löst genau derselbe Befehl nicht mehr mit 404 auf, sondern
|
|
|
|
|
**erfolgreich — gegen ein fremdes Paket**. Das ist das Muster, das als *dependency confusion*
|
|
|
|
|
bekannt ist, und die Bedingung dafür ist nicht „ein Angriff auf uns", sondern „jemand legt einen
|
|
|
|
|
Scope-Namen an". Der Schutz besteht heute ausschließlich darin, dass ein Name auf einer fremden
|
|
|
|
|
Registry noch frei ist.
|
|
|
|
|
|
|
|
|
|
Verschärfend: Der Fehler träfe genau den Moment, in dem jemand eine Version anhebt — also den
|
|
|
|
|
Moment, in dem eine neue Abhängigkeit ohnehin erwartet wird und ein Download nicht auffällt.
|
|
|
|
|
|
|
|
|
|
Das ist dieselbe Klasse wie die Befunde aus #0054 und der Backup-Reihe: **die Absicherung besteht
|
|
|
|
|
nicht, sie ergibt sich nur zufällig aus dem aktuellen Zustand.** Sie „meldet" auch nichts — sie
|
|
|
|
|
funktioniert stillschweigend, bis sie es nicht mehr tut.
|
|
|
|
|
|
|
|
|
|
## Acceptance
|
|
|
|
|
|
|
|
|
|
- Eine **eingecheckte** `.npmrc` in `ThreadNet-Web` bindet den Scope fest:
|
|
|
|
|
`@sorb:registry=https://rohana.axion1337.de/api/packages/sorb/npm/`
|
|
|
|
|
- Ein Anheben der Version funktioniert im **frischen Klon ohne Zusatzschritte** — das ist der
|
|
|
|
|
eigentliche Nachweis, nicht das Vorhandensein der Datei.
|
|
|
|
|
- Gegenprobe: Ein Lauf mit absichtlich unerreichbarer rohana **scheitert**, statt auf
|
|
|
|
|
`registry.npmjs.org` auszuweichen.
|
|
|
|
|
- Die anderen Repos der Gruppe sind auf denselben Befund geprüft: Wer sonst noch `@sorb`-Pakete
|
|
|
|
|
zieht, hat dieselbe Lücke (`threadnet-call` selbst publisht nur, konsumiert aber ggf. auch).
|
|
|
|
|
- Der Auslieferungsweg in `ThreadNet-Web:docs/axion1337-fork.md` nennt den Befehl zum Anheben.
|
|
|
|
|
|
|
|
|
|
## Notes
|
|
|
|
|
|
|
|
|
|
**Kein Token nötig.** Der Lesezugriff auf die Registry ist anonym möglich (nachgeprüft: der
|
|
|
|
|
Paket-Index antwortet ohne Authentifizierung). Die `.npmrc` enthält damit **nur eine URL und kein
|
|
|
|
|
Geheimnis** und kann bedenkenlos eingecheckt werden — das ist der Grund, warum hier kein
|
|
|
|
|
Secrets-Handling dranhängt.
|
|
|
|
|
|
|
|
|
|
**Warum nicht einfach dokumentieren:** Ein Satz in der Fork-Doku würde den 404 erklären, aber die
|
|
|
|
|
`registry.npmjs.org`-Auflösung nicht verhindern. Nach der Lehre aus #0053 und dem Bindmount-Fall
|
|
|
|
|
ist Aufschreiben hier ausdrücklich **nicht** die Maßnahme: die Regel war beide Male vorhanden und
|
|
|
|
|
hat den Fehler nicht verhindert. Wirksam ist die eingecheckte Datei, weil sie den falschen Weg
|
|
|
|
|
gar nicht erst offen lässt.
|
|
|
|
|
|
|
|
|
|
**Verwandt, aber getrennt:** Bei der Gelegenheit ist aufgefallen, dass der Job `publish_npm` in
|
|
|
|
|
`threadnet-call` `allow_failure: true` trägt — ein *scheiternder* Publish färbt die Pipeline
|
|
|
|
|
nicht rot. Das ist ein eigener Befund und gehört nicht in dieses Issue; hier nur notiert, damit
|
|
|
|
|
er nicht verloren geht.
|
2026-08-18 12:00:00 +00:00
|
|
|
|
|
|
|
|
## Erledigt 2026-08-18 — `.npmrc` eingecheckt, Auflösung nachgewiesen
|
|
|
|
|
|
|
|
|
|
Umgesetzt in `ThreadNet-Web` (`be323ed`): `.npmrc` im Wurzelverzeichnis bindet
|
|
|
|
|
`@sorb` an die Registry auf rohana.
|
|
|
|
|
|
|
|
|
|
**Ein Fund beim Umsetzen, der den naiven Fix stillschweigend zunichtegemacht hätte:**
|
|
|
|
|
Upstreams `.gitignore` enthält `/.npmrc` (Zeile 7) — sinnvoll, wo die Datei Tokens trägt.
|
|
|
|
|
Die Datei wäre also lokal geblieben, ohne dass irgendetwas gemeldet hätte; CI und frischer
|
|
|
|
|
Klon hätten weiter gegen npmjs aufgelöst. Die Ausnahme steht jetzt ausdrücklich mit
|
|
|
|
|
Begründung im `.gitignore` (`!/.npmrc`), damit der nächste Upstream-Merge die Lücke nicht
|
|
|
|
|
wieder aufmacht. Dieselbe Klasse wie die Befunde aus #0054: gemeldeter Erfolg ohne Wirkung.
|
|
|
|
|
|
|
|
|
|
**Abnahme — in einem isolierten Baum gemessen, nicht angenommen:**
|
|
|
|
|
|
|
|
|
|
| Prüfung | Ergebnis |
|
|
|
|
|
|---|---|
|
|
|
|
|
| ohne `.npmrc` (heutiger Zustand) | löst gegen `registry.npmjs.org` auf, bricht ab |
|
|
|
|
|
| mit `.npmrc`, frische Auflösung ohne Zusatzschritt | Tarball von `rohana.axion1337.de`, Integrity identisch mit dem Repo-Lockfile |
|
|
|
|
|
| Gegenprobe rohana unerreichbar | `ERR_PNPM_META_FETCH_FAIL`, **kein** Ausweichen auf npmjs, kein Lockfile |
|
|
|
|
|
| `pnpm install --frozen-lockfile` (CI-Weg) | grün, Lockfile unverändert |
|
|
|
|
|
|
|
|
|
|
**Andere Repos geprüft:** `threadnet-call` *publisht* das Paket nur und schreibt die
|
|
|
|
|
Scope-Zeile in seiner CI bereits selbst (`.gitlab-ci.yml`); es konsumiert keine
|
|
|
|
|
`@sorb`-Pakete. In `gitops` kommt der Scope nicht vor. `ThreadNet-Web` war der einzige
|
|
|
|
|
Konsument — die Lücke ist damit vollständig geschlossen, nicht nur an einer Stelle.
|
|
|
|
|
|
|
|
|
|
**Dokumentiert:** `ThreadNet-Web:docs/axion1337-fork.md` hat jetzt einen Abschnitt
|
|
|
|
|
„Element Call anheben" mit dem Weg ohne Umgebungsvariable, dem `--dir`-statt-`--filter`
|
|
|
|
|
Fallstrick und der Prüfung, dass die Tarball-URL auf rohana zeigt.
|
|
|
|
|
|
|
|
|
|
**Nicht angefasst:** `allow_failure: true` auf `publish_npm` — eigener Befund, liegt
|
|
|
|
|
weiterhin bei sorb.
|