This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
ADR-001: Cloudflare Tunnel für Webhook-Infrastruktur
Status: Vorgeschlagen → Genehmigt (2026-07-15) — revidiert Datum: 2026-07-15 (revidiert) Autor: Hermes Agent + frank Kontext: #65, #66
Kontext
Streamertool ist eine lokale Tauri 2 Desktop-App für Streamer. Für die Integration von Drittanbieter-Diensten (Ko-fi, Patreon, PayPal, Stripe) müssen Webhooks empfangen werden — HTTP-POST-Requests von externen Servern an die App.
Da die App lokal auf dem Rechner des Streamers läuft (ohne öffentliche IP, hinter NAT/Firewall), muss ein Tunnel eine öffentlich erreichbare HTTPS-URL auf den lokalen Server bereitstellen.
Anforderungsänderung (Revision)
Die ursprüngliche Spezifikation ging von einem manuellen cloudflared-Setup mit LaunchAgent aus. Nach erneuter Analyse wurde klar:
| Kriterium | Alt (LaunchAgent) | Neu (In-App-Integration) |
|---|---|---|
| Setup | Manuell (brew install, Terminal) |
Setup-Assistent im Dashboard |
| Autostart | System-Daemon (LaunchAgent) | App-Lifecycle (mit der App) |
| Dependencies | Externes cloudflared |
Gebundeltes Binary im Installer |
| Plattform-Fokus | macOS | Windows (AMD64) — primär |
| Dashboard | Externes Log-Monitoring | Integrierter Status + Log-Viewer |
| Sicherheit | Klartext-Files | OS-Keychain (SecretStore) |
Ziel: Der Tunnel ist ein vollständig integriertes Feature — kein Terminal, kein manuelles cloudflared, keine externen Abhängigkeiten.
Entscheidung
Cloudflare Tunnel (cloudflared) wird als Tunnel-Lösung eingesetzt, vollständig integriert in die Streamertool-App.
Architektur
┌─────────────────────────────────────────────────────┐
│ Streamertool (Tauri 2 Desktop-App) │
│ │
│ ┌──────────────────┐ ┌─────────────────────────┐ │
│ │ TunnelManager │ │ Webhook-Server (:3443) │ │
│ │ (Lifecycle-Task) │──▶│ (Rust Axum Server) │ │
│ │ │ │ │ │
│ │ cloudflared │ │ POST /webhooks/kofi │ │
│ │ Subprocess │ │ POST /webhooks/patreon │ │
│ └────────┬─────────┘ │ POST /webhooks/paypal │ │
│ │ └───────────┬─────────────┘ │
│ │ │ │
│ ┌────────▼─────────────────────────▼──────────┐ │
│ │ AppState │ │
│ │ • db (SQLite Settings) │ │
│ │ • secrets (OS-Keychain) │ │
│ │ • event_bus (EventBus) │ │
│ └────────────────────────────────────────────┘ │
└──────────────────────┬──────────────────────────────┘
│
┌──────────▼──────────┐
│ Cloudflare Tunnel │
│ (cloudflared) │
│ HTTPS → localhost │
└─────────────────────┘
▲
Ko-fi ──────┘
Patreon ────┐
PayPal ─────┤
Stripe ─────┘
Komponenten
| Komponente | Beschreibung | Datei |
|---|---|---|
| TunnelManager | State Machine (Unconfigured → Configured → Running → Stopped) | src-tauri/src/tunnel/mod.rs |
| BinaryManager | Findet/gibt/verifiziert cloudflared Binary |
src-tauri/src/tunnel/binary.rs |
| ConfigManager | Generiert config.yml, verwaltet Credential-Files |
src-tauri/src/tunnel/config.rs |
| Wizard | OAuth-Login-Flow, Tunnel-Erstellung | src-tauri/src/tunnel/wizard.rs |
| Platform | Plattform-Pfade, Prozess-Start | src-tauri/src/tunnel/platform.rs |
| API | Status-Endpunkte | src-tauri/src/server/api/tunnel.rs |
| Frontend | Dashboard + Setup-Wizard | src/pages/Tunnel.tsx |
Lifecycle
App-Start
│
├── bootstrap()
│ ├── DB-Migrationen
│ ├── SecretStore laden
│ ├── TunnelManager::load() — Config aus DB + Secrets
│ └── Wenn tunnel.enabled → lifecycle.spawn("tunnel", ...)
│
├── Tunnel-Prozess (Background)
│ ├── cloudflared tunnel run --config ...
│ ├── Log-Pufferung (letzte 100 Zeilen)
│ └── Event-Bus-Publikation bei Status-Wechseln
│
└── shutdown()
├── TunnelManager::stop()
│ ├── SIGTERM → cloudflared
│ ├── 5s Timeout → SIGKILL
│ └── Log-Eintrag
└── cleanup()
Bundling-Strategie
Primär: Windows AMD64 (NSIS-Installer) Sekundär: macOS ARM64/AMD64 (DMG)
| Plattform | Quelle | Pfad |
|---|---|---|
| Windows | cloudflared-windows-amd64.exe vom GitHub Release |
<AppData>\bin\cloudflared.exe |
| macOS | cloudflared-darwin-amd64 / cloudflared-darwin-arm64 |
<AppSupport>/bin/cloudflared |
Fallback bei fehlender Binary: Auto-Download von Cloudflare GitHub Releases mit SHA-256-Verifikation.
Warum kein systemnaher Daemon?
- LaunchAgent/systemd/user-Service wäre getrennt von der App → kein Dashboard, kein Lifecycle
- App-Lifecycle ist einfacher — Tunnel läuft nur wenn die App läuft
- Bei App-Neustart: Webhook-Registrierung muss ohnehin erneuert werden
- Windows Nutzer sind systemd/LaunchAgent nicht gewohnt → App-Integration ist nutzerfreundlicher
Konsequenzen
Positiv
- ✅ Keine manuelle Installation — Binary ist gebundelt oder wird automatisch geladen
- ✅ Setup-Assistent — auch technisch nicht versierte Streamer können einrichten
- ✅ Dashboard-Integration — Status, URL, Logs, Start/Stopp aus einer Hand
- ✅ Lifecycle-gesteuert — Tunnel startet/stoppt mit der App, kein zusätzlicher Service
- ✅ Sicher — Tokens in OS-Keychain (via
SecretStore), nicht in Klartext-Konfig - ✅ Windows-first — optimiert für die Hauptzielgruppe
Negativ
− ⚠️ Binary-Größe — cloudflared.exe ~15 MB zusätzlich im Bundle
− ⚠️ Cloudflare-Account nötig — aber kostenlos, einmalige Anmeldung
− ⚠️ Browser-OAuth — Ersteinrichtung erfordert Browser-Öffnen
− ⚠️ Nicht ohne GUI — Tunnel-Start nur über Dashboard möglich (kein Headless-Betrieb)
Risiken & Mitigation
| Risiko | Wahrscheinlichkeit | Mitigation |
|---|---|---|
| Cloudflare-Ausfall | Sehr selten | Webhook-Anbieter retryen automatisch |
cloudflared-Update bricht API |
Selten | Pinning auf getestete Version, SHA-256-Check |
| Token läuft ab | Selten (Jahre) | Wizard erneuert Token bei Bedarf |
| Binary fehlt nach Update | Mittel | SHA-256-Check + Auto-Download-Fallback |
| Windows Defender blockiert | Niedrig | Signierte Binary, MSI/NSIS-Installer |
Implementierung
Phase 1 — Grundstruktur (Rust Backend)
src-tauri/src/tunnel/mod.rs— TunnelManager + State Machinesrc-tauri/src/tunnel/binary.rs— Binary-Managementsrc-tauri/src/tunnel/config.rs— Config-Generierungsrc-tauri/src/tunnel/platform.rs— Plattform-Pfade
Phase 2 — Lifecycle & API
- Integration in
AppState,lib.rs - Tauri-Commands:
get_tunnel_status,start_tunnel,stop_tunnel - API:
GET /api/tunnel,POST /api/tunnel/start,POST /api/tunnel/stop
Phase 3 — Setup-Wizard
src-tauri/src/tunnel/wizard.rs— OAuth-Flow- Frontend: 4-Schritt-Wizard-Dialog
Phase 4 — Dashboard
- Frontend: Tunnel-Seite in Settings
- Dashboard-Status-Karte
- Log-Viewer
Phase 5 — Bundling & Build
- Download-Script für CI
- Tauri-Resource-Integration
- Windows NSIS + macOS DMG
Verwandte ADRs
(noch keine — dies ist der erste ADR)
Quellen
Dieser ADR wurde revidiert am 2026-07-15. Die ursprüngliche Version spezifizierte ein manuelles LaunchAgent-Setup. Die Revision definiert eine vollständige In-App-Integration mit Windows-Fokus und gebundeltem Binary.