Zugangsdaten kommen jetzt aus der App statt aus einer .env: ein Einrichtungs-Assistent auf http://localhost:4792/setup nimmt Client-ID, Secret und OBS-Passwort entgegen, der OAuth-Rueckruf laeuft auf denselben Server. Gespeichert wird verschlueselt (AES-256-GCM) in einem Volume, bewusst nicht in der Datenbank - die wird auf die Windows-Seite gesichert. Siehe ADR-0005. Technikbasis vereinfacht: Node 24 bringt node:sqlite, WebSocket, fetch und die Ausfuehrung von TypeScript mit. Das Projekt hat damit null Laufzeitabhaengigkeiten und keinen Build-Schritt; pnpm-Workspaces und die Paketmanifeste sind entfallen, Importe laufen ueber die imports-Map der Wurzel-package.json. erasableSyntaxOnly verhindert Syntax, die das Type Stripping stillschweigend entfernen wuerde. Siehe Nachtrag 2 in ADR-0001. Enthalten: - packages/core: Config, Layout, Logger mit Secret-Maskierung, Retry, YAML - packages/db: Migrationen, Repositories, alle SQL-Anweisungen an einem Ort - packages/twitch: Secret-Speicher, OAuth, Helix mit Token-Bucket, IRC - apps/ingest: Daemon, Einrichtungsseite, Spike-Erkennung - 20 Tests (IRC-Parser, Spike-Detektor, Datenbankschicht) Der Chat verbindet sich anonym, solange nichts hinterlegt ist - damit laesst sich die Datenaufnahme pruefen, bevor die Twitch-Apps existieren. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013VTGjd92LsDDWF3frd9FTB
4.0 KiB
ADR-0005: Zugangsdaten kommen aus der App, nicht aus der .env
Status: akzeptiert · Datum: 2026-09-09
Kontext
Das Toolkit braucht Client-ID und Client-Secret zweier Twitch-Apps, ein
obs-websocket-Passwort und später Discord-/Bluesky-Zugänge. Der erste Entwurf
sah dafür eine .env-Datei vor, die von Hand befüllt wird.
Das passt nicht zum Nutzer. Abdu ist Streamer, kein Entwickler. „Kopiere
.env.example nach .env und trage sieben Werte ein" ist die Stelle, an der
ein Werkzeug liegen bleibt. Und es kommt ein zweites Problem dazu, das für
diesen Anwendungsfall besonders zählt: Wer eine Klartextdatei mit
Zugangsdaten öffnet, während er sendet, hat sie live gezeigt.
Entscheidung
Zugangsdaten werden über einen Einrichtungs-Assistenten im Browser
eingegeben, unter http://localhost:4792/setup. Gespeichert werden sie
verschlüsselt in /db/secrets.json im Docker-Volume.
Die .env bleibt bestehen, enthält aber nur noch optionale Werte
(Log-Level, Pfad zum Wiedergabepuffer). Ohne .env startet alles.
Damit fällt auch Port 4780 weg: Einrichtung, OAuth-Rücksprung und später
Sichtungsseite und Dashboard laufen über einen Server auf Port 4792. Die
Redirect-URI in der Twitch-App lautet entsprechend
http://localhost:4792/callback.
Speicherung
| Ort | /db/secrets.json, benanntes Volume abdulive-db |
| Verfahren | AES-256-GCM, Schlüssel in /db/.secret-key (Modus 0600) |
| Schlüssel | wird beim ersten Start erzeugt, nie ausgegeben, nie geloggt |
| Nicht in SQLite | damit das Backup-Skript sie nie mitkopiert |
Die Secrets liegen bewusst außerhalb der Datenbank. scripts/backup.ps1
zieht die .db aus dem Volume nach data/db/backup/ — also auf die
Windows-Seite, wo sie in einer Cloud-Synchronisation landen kann. Was dort
nichts zu suchen hat, darf gar nicht erst in der Datenbank stehen.
Was diese Verschlüsselung leistet — und was nicht
Der Schlüssel liegt im selben Volume wie die verschlüsselten Daten. Gegen jemanden, der Zugriff auf das Volume hat, schützt das nicht, und es wird hier auch nicht so getan.
Wogegen es schützt, und das ist der eigentliche Zweck:
- Versehentliche Anzeige im Stream.
cat secrets.jsonzeigt Kauderwelsch, keine Client-Secrets. - Verirrte Kopien. Ein Volume-Export oder ein weitergegebener Ordner enthält ohne die Schlüsseldatei nichts Verwertbares.
- Grep-Unfälle. Secrets tauchen in keiner Volltextsuche und in keinem versehentlich geteilten Log auf.
Gegen eine Kompromittierung der Maschine schützt es nicht. Das ist bei einem lokalen Einzelplatzwerkzeug auch nicht das Bedrohungsmodell — wer dort Zugriff hat, hat auch Zugriff auf OBS, den Browser und die gespeicherten Twitch-Cookies.
Konsequenzen für die Oberfläche
- Der Einrichtungs-Assistent zeigt gespeicherte Secrets nie wieder an.
Nach dem Speichern steht dort
•••••• gespeichertund ein Knopf Ersetzen. - Über der Seite steht ein Hinweis: „Diese Seite zeigt Zugangsdaten — nicht im Stream öffnen."
- Der Server ist nur lokal erreichbar. Nicht dadurch, dass er im Container
auf
127.0.0.1bindet — das wäre dort die Container-Loopback, die Dockers Portweiterleitung nie erreicht, der Dienst wäre schlicht tot. Die Abschottung kommt aus zwei Teilen: der Container bindet auf0.0.0.0innerhalb seines eigenen Netzwerk-Namensraums, und Compose veröffentlicht den Port ausschließlich als127.0.0.1:4792. Außerhalb von Docker bindet der Server weiterhin auf die Loopback-Adresse; gesteuert überBIND_HOST, das nur das Image auf0.0.0.0setzt. - Secrets werden nie geloggt, auch nicht bei Fehlern. Der Logger maskiert bekannte Schlüsselnamen.
check-envmeldet, ob Zugangsdaten hinterlegt sind, nie welche.
Preis
Der Einrichtungs-Assistent kostet in S1 ungefähr einen zusätzlichen Tag —
kleiner HTTP-Server, eine Seite, der Secret-Speicher. Dafür entfällt der
gesamte .env-Schritt aus der Inbetriebnahme, und das Werkzeug lässt sich
später ohne Texteditor umkonfigurieren.