Der Spickzettel zur zweiten Hälfte des Seminars Open WebUI im Unternehmen: welcher Weg ein Werkzeug anbindet, wo eine Freigabe wirklich greift, welche Standardwerte man ändert, was eine Abnahme prüft, was Open WebUI zu Logs und Kosten liefert und was nicht, und wie Mehrinstanzbetrieb, Sicherung und Upgrade zusammenhängen. Einordnung, Governance, Installation, Identitäten, Modelle und RAG stehen auf dem ersten Blatt: Open WebUI: Plattform aufbauen.
Maßgeblich für Variablen, Standardwerte und Versionsstände ist die Originaldoku unter docs.openwebui.com. Dieses Blatt trifft eine Auswahl, Stand Open WebUI v0.11.4 (Oktober 2026). Das Projekt veröffentlicht in kurzen Abständen — Standardwerte vor dem Einsatz gegen die Doku prüfen.
Werkzeuge anbinden: OpenAPI, MCP oder mcpo
| Weg | Läuft wo | Passt für |
|---|---|---|
| Workspace Tool | als Python im Open-WebUI-Prozess | kleine Logik, Geheimnisse bleiben serverseitig |
| OpenAPI Tool Server | eigener Dienst, per HTTP angebunden | bestehende REST-Dienste, Unternehmensintegration |
| MCP (Streamable HTTP) | eigener MCP-Server | vorhandene MCP-Server und -Clients |
| mcpo | Proxy vor einem stdio- oder SSE-Server | MCP-Server ohne HTTP-Transport |
Die Doku nennt OpenAPI für die meisten Installationen den bevorzugten Weg: Er passt zu SSO, API-Gateways, Audit und Quoten, und die Endpunkte lassen sich ohne Modell testen. MCP bindet Open WebUI nur über Streamable HTTP an; mcpo übersetzt stdio- oder SSE-Server in OpenAPI-Endpunkte.
| OpenAPI Tool Server | MCP (Streamable HTTP) | |
|---|---|---|
| Wer legt an | auch Nutzer mit Direct Tool Servers | nur Administratoren |
| Zustand | zustandslos, feste Endpunkte | zustandsbehaftet, mit Sitzungen |
| Werkzeuge drumherum | etabliert für Doku, Test, Sicherheit | ein Protokoll für viele Clients |
| Streaming | keine gestreamte Ausgabe | auf Transportebene |
Das Integrationsmuster bestimmt den Aufwand, nicht die Technik: Ein Dokumentimport riskiert veraltete Kopien, eine Live-Abfrage Datenabfluss, ein schreibendes Werkzeug Wirkung im Zielsystem und Doppelausführung.
Modul: Integration über APIs und MCP
Identität beim Werkzeug und MCP-Authentifizierung
| Mechanismus | Was beim Werkzeug ankommt | Vertrauen |
|---|---|---|
ENABLE_FORWARD_USER_INFO_HEADERS | X-OpenWebUI-User-Id, -Email, -Role, -Name | nur im geschützten Netz |
FORWARD_USER_INFO_HEADER_JWT_SECRET | ein signiertes JWT statt der Einzelheader | prüfbar mit gemeinsamem Geheimnis |
MCP-Auth None | kein Token | nur im internen Netz |
MCP-Auth Bearer | fester Schlüssel aus dem Feld Key | technisches Konto, keine Person |
MCP-Auth Session | das Open-WebUI-Sitzungstoken des Nutzers | so gut wie der Transportweg |
MCP-Auth OAuth | Zugriffstoken aus der SSO-Anmeldung | vom Zielsystem prüfbar |
MCP-Auth OAuth 2.1 / (Static) | Nutzer verbindet sein Konto selbst, Client per DCR oder fest hinterlegt | vom Zielsystem prüfbar |
Unsignierte Header kann jeder setzen, der den Tool-Server erreicht — für
Rechteprüfungen das JWT nehmen. Berechtigungen gehören ins Zielsystem: Eine
Modellanweisung wie „Ändere nur eigene Tickets” ist keine Kontrolle. Eingaben
begrenzt die OpenAPI-Spezifikation (eine operationId je Endpunkt, pattern
im Schema); geprüft wird im Server, nicht im Modell.
Modul: Integration über APIs und MCP
Freigaben für schreibende Aktionen
| Ort | Wie | Grenze |
|---|---|---|
| Tool Permissions | „Ask for approval” stoppt vor jedem Aufruf mit Allow/Deny | experimentell, aus per Standard (ENABLE_TOOL_PERMISSIONS) |
| Python-Werkzeug | Bestätigungsdialog über __event_call__ mit type: "confirmation" | gilt nur für dieses Werkzeug |
| Action Function | Knopf an der Nachricht, vom Menschen ausgelöst | kein Aufruf durch das Modell |
| Zielsystem | Werkzeug legt nur einen Vorschlag an, Mensch bestätigt dort | eigener Freigabeweg nötig |
Automationen und Channels laufen immer ohne Rückfrage. Jede Schreibaktion
bekommt einen eigenen Endpunkt — lesen und schreiben nie in einer Operation.
Ohne WEBSOCKET_EVENT_CALLER_TIMEOUT wartet eine Rückfrage unbegrenzt.
Module: Integration über APIs und MCP · Erweiterungen und agentische Abläufe
Erweiterungen: Tools, Functions und was Pipelines ersetzt
| Typ | Aufgabe | Wer verwaltet |
|---|---|---|
| Tool | Fähigkeit, die das Modell aufruft | Workspace > Tools |
| Pipe | erscheint als eigenes Modell und beantwortet selbst | nur Admins |
| Filter | verändert Anfragen und Antworten (inlet, stream, outlet) | nur Admins |
| Action | Knopf an einer Nachricht, vom Menschen ausgelöst | nur Admins |
| Event | reagiert auf Systemereignisse, neu ab 0.10.0 | nur Admins |
| In Pipelines (Legacy) | Heute stattdessen |
|---|---|
| Pipeline vom Typ pipe | Pipe Function |
| Pipeline vom Typ filter | Filter Function |
| externer HTTP-Dienst | OpenAPI Tool Server oder MCP-Server |
| Worker-Container auf Port 9099 | entfällt |
Valves setzt der Admin für alle, UserValves jede Person selbst. Ein
Passwort-Feld maskiert nur die Anzeige; verschlüsselt wird erst mit
ENABLE_VALVE_ENCRYPTION, abhängig von WEBUI_SECRET_KEY. Das Recht, Werkzeuge
anzulegen, gilt laut Security Policy als root-gleich.
Modul: Erweiterungen und agentische Abläufe
Agentische Läufe und Codeausführung begrenzen
| Stellschraube | Standard | Wirkung |
|---|---|---|
CHAT_RESPONSE_MAX_TOOL_CALL_ITERATIONS | 256 | Werkzeugrunden je Antwort, dann Abbruch |
AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER | wie AIOHTTP_CLIENT_TIMEOUT | Wartezeit auf einen Tool-Server |
WEBSOCKET_EVENT_CALLER_TIMEOUT | ohne | Wartezeit auf eine Rückfrage im Browser |
| Function Name Filter List | alle | sichtbare Werkzeuge eines MCP-Servers |
| Builtin Tools je Modell | an | eingebaute Werkzeugkategorien |
| Codeausführung | Isolation | Einsatz |
|---|---|---|
| Code Interpreter (pyodide) | im Browser | Legacy, nur Bestand |
| Open Terminal | ein Container je Verbindung | frei, eine Person oder ein Team |
| Open Terminal, Multi-User | Arbeitsbereiche in einem Container — keine Sicherheitsgrenze | nur gleich vertraute Nutzer |
| Terminals (Orchestrator) | ein Container je Nutzer und Richtlinie | Enterprise-Lizenz für Produktion |
Modul: Erweiterungen und agentische Abläufe
Härtung: Standardwerte, Netzwerk und Secrets
| Einstellung | Standard | Warum ändern |
|---|---|---|
ENABLE_SIGNUP | ConfigVar | nach dem ersten Start gewinnt der Datenbankwert |
ENABLE_ADMIN_CHAT_ACCESS | true | Admins sehen alle Chats — mit Betriebsrat regeln |
BYPASS_ADMIN_ACCESS_CONTROL | true | Admins umgehen Freigaben von Wissen und Modellen |
ENABLE_COMMUNITY_SHARING | true | für interne Inhalte unnötig |
ENABLE_ADMIN_EXPORT | true | Massenexport nur, wenn ein Prozess ihn braucht |
ENABLE_OPENAI_API_PASSTHROUGH | false | bleibt aus: sonst Admin-Schlüssel ohne Modellrechte |
JWT_EXPIRES_IN | 4 Wochen | kürzer, solange Redis Tokens nicht widerrufen kann |
FORWARDED_ALLOW_IPS | * | nur der Proxy, sonst fälschen Clients ihre Adresse |
ENABLE_LOCAL_WEB_FETCH | — | aus lassen: SSRF-Sperre für interne Dienste |
Ohne explizite Werte gelten CORS und Proxyheader offen für alle, das Cookie ohne
Secure und keine Sicherheitsheader (HSTS, XFRAME_OPTIONS).
| Secret | Folge der Rotation |
|---|---|
WEBUI_SECRET_KEY | alle Sitzungen enden, MCP-Tokens neu verbinden |
OAUTH_SESSION_TOKEN_ENCRYPTION_KEY | gespeicherte OAuth-Tokens werden unlesbar |
OAUTH_CLIENT_SECRET | gleichzeitig beim Identitätsanbieter und in Open WebUI tauschen |
| Datenbankpasswort | Neustart aller Instanzen |
Sicherheitskorrekturen erhält nur der aktuelle Stand; GitHub Security Advisories beobachten, erst auf dem Testsystem einspielen.
Modul: Plattform absichern
Bedrohungsmodell nach OWASP LLM Top 10 (2026)
| Risiko | Prüffrage |
|---|---|
| LLM01 Prompt Injection | Was passiert, wenn ein Dokument der Wissensbasis Anweisungen enthält? |
| LLM02 Sensitive Information Disclosure | Sieht eine Gruppe Inhalte einer anderen? |
| LLM03 Excessive Agency | Kann ein Modell ohne Freigabe im Zielsystem schreiben? |
| LLM04 Supply Chain | Woher stammen Image, Modelle, Tools und Functions? |
| LLM06 Unbounded Consumption | Was begrenzt Tokens, Werkzeugschleifen und Uploads? |
| LLM07 Misinformation | Erkennt der Assistent widersprüchliche Fassungen? |
| LLM08 Hidden Context Exposure | Stehen Geheimnisse im Systemprompt oder in Werkzeugantworten? |
| LLM09 Vector and Embedding Weaknesses | Greift die Gruppenfreigabe auch bei der Vektorsuche? |
| LLM10 Improper Output Handling | Werden Links und Code aus Antworten ungeprüft weiterverarbeitet? |
Abflusswege mit eigener technischer Grenze: Antworten, Werkzeuge, Suchdienste, Links und Bilder, Logs. Ein Restrisiko ohne Namen und Prüftermin ist nicht akzeptiert, sondern vergessen.
Modul: Plattform absichern
Abnahme: Tests und Kriterien
| Prüfung | Bestanden, wenn |
|---|---|
| Person ohne Gruppenrecht fragt nach fremder Wissensbasis | weder Inhalt noch Dateiname erscheinen |
| Konto ohne Freigabe ruft Assistenten über die API | Anfrage abgelehnt |
Konto mit Rolle pending | kein Zugriff bis zur Freischaltung |
| Deaktiviertes Konto nutzt altes Token oder API-Schlüssel | Anfrage abgelehnt |
| Dokument mit versteckter Anweisung | Antwort folgt ihr nicht, Quelle sichtbar |
| Werkzeugschleife | Obergrenze beendet die Antwort |
| Änderung | Erneut testen |
|---|---|
| Modell oder Parameter | alle Referenzfragen und Injection-Tests |
| Systemprompt | Referenzfragen des Assistenten, direkte Injection |
| Dokumente | Retrieval-Fragen, besonders Widersprüche |
| Embedding-Modell | erst neu indexieren, dann alle Retrieval-Fragen |
| Release von Open WebUI | Zugriff, Login, Streaming, Werkzeuge |
Zugriffstests laufen mit einem Testkonto je Gruppe, nie als Admin. Lasttests
mit owb run chat-api aus open-webui/benchmark; Uploads und parallele
Werkzeugaufrufe deckt es nicht ab. Ein einziger gescheiterter Zugriffstest oder
eine Schreibaktion ohne Freigabe ist ein Ausschlusskriterium.
Module: Qualität und Abnahme · Abschlussprojekt
Auditlog, Telemetrie und Betriebskennzahlen
Stufe AUDIT_LOG_LEVEL | Zeichnet auf | Folge |
|---|---|---|
NONE | nichts — Standard | keine Nachvollziehbarkeit |
METADATA | Grundangaben zur Anfrage | Empfehlung der Härtungsseite |
REQUEST | zusätzlich den Request-Body | Prompts im Log |
REQUEST_RESPONSE | zusätzlich die Antwort | Chatinhalte doppelt gespeichert |
Mit ENABLE_AUDIT_STDOUT=true geht das Auditlog an den Log-Collector.
OpenTelemetry schalten ENABLE_OTEL, _TRACES, _METRICS und _LOGS ein —
alle standardmäßig false. Traces enthalten db.statement und redis.args,
brauchen also eine Datenschutzprüfung; Metriken liefern Anfragen und Dauer,
keine Tokens.
| Kennzahl | Quelle |
|---|---|
| Verfügbarkeit | /health ohne Anmeldung |
| Modelle erreichbar | /api/models mit eingeschränktem Monitoring-Konto |
| Ende zu Ende, Zeit bis zum ersten Token | Testanfrage an /api/chat/completions |
| Fehlerquote, Latenz | http.server.requests, http.server.duration |
Modul: Monitoring, Kosten und Fehlerdiagnose
Kosten: was Open WebUI zählt und was ein Gateway regelt
| Open WebUI | Gateway, z. B. LiteLLM | |
|---|---|---|
| Zählen | Tokens je Modell und Gruppe (Analytics) | Kosten je Schlüssel, Team, Nutzer |
| Budget | keins, keine Sperre | max_budget mit budget_duration |
| Alarm | keiner | soft_budget |
| Ratenlimit | keins für Modelle | rpm_limit, tpm_limit |
Fehlende Tokenangaben erscheinen als 0; beim Streaming zählt nur, wer am Modell die Fähigkeit Usage gesetzt hat. Kosten = Eingabetokens × Eingabepreis + Ausgabetokens × Ausgabepreis — Preise pflegt man selbst. Hintergrundaufgaben des Task-Modells (Titel, Tags, Folgefragen) werden oft übersehen.
Modul: Monitoring, Kosten und Fehlerdiagnose
Fehlerbilder und Ursachen
| Symptom | Wahrscheinliche Ursache |
|---|---|
Login: mismatching_state | Cookie oder Sitzung, SameSite, Proxy-Cache |
| Login: 404 auf den Callback | Redirect-URI passt nicht zu WEBUI_URL |
| Login-Schleife oder 401, nur mit mehreren Instanzen | Secret Key oder Redis nicht gemeinsam |
| Wissensbasis wird ignoriert | Kontextfenster zu klein, etwa num_ctx in Ollama |
| Schlechte Treffer nach Modellwechsel | Embedding-Modell geändert, nicht neu indexiert |
| Modellauswahl lädt endlos | eine Verbindung nicht erreichbar (AIOHTTP_CLIENT_TIMEOUT_MODEL_LIST) |
| 502, Connect call failed auf 127.0.0.1 | localhost im Container statt Dienstname |
| Markdown-Zeichen sichtbar, Text zerstückelt | Proxy puffert: proxy_buffering off fehlt |
| Chat hängt, WebSocket 403 | Upgrade- und Connection-Header fehlen |
Von außen nach innen prüfen: /health, dann /api/models, dann eine
Testanfrage. Erst die Ursache sichern, dann neu starten.
Modul: Monitoring, Kosten und Fehlerdiagnose
Mehrinstanzbetrieb: Pflichtvariablen
| Variable | Wozu |
|---|---|
DATABASE_URL | PostgreSQL statt SQLite — Pflicht |
VECTOR_DB | z. B. pgvector; das eingebaute ChromaDB ist nicht mehrprozessfähig |
REDIS_URL | gemeinsamer Anwendungszustand |
WEBSOCKET_MANAGER | redis, sonst WebSocket-Fehler 403 |
ENABLE_WEBSOCKET_SUPPORT | true |
WEBUI_SECRET_KEY | auf allen Instanzen identisch |
OAUTH_SESSION_TOKEN_ENCRYPTION_KEY | ebenfalls identisch |
ENABLE_DB_MIGRATIONS | false auf allen Instanzen außer einer |
Dazu ein gemeinsamer Dateispeicher. PGVECTOR_DB_URL fällt ohne eigene Angabe
auf DATABASE_URL zurück. Pool mal Instanzen muss unter max_connections von
PostgreSQL bleiben.
Modul: Hochverfügbarkeit, Backup und Releases
Sicherung, Wiederherstellung und Upgrade
| Bestandteil | Sicherung |
|---|---|
| Datenbank (Benutzer, Chats, Rechte, Einstellungen) | pg_dump |
| Vektoren | mit der Datenbank, wenn pgvector |
| Datenverzeichnis (Uploads, Bilder, Caches) | Dateisicherung |
| Konfiguration | Repository mit Compose, Proxy, Variablen |
| Schlüssel | Tresor, getrennt vom Backup |
| Image-Tag | im Repository festgehalten |
Ein automatisch erzeugter WEBUI_SECRET_KEY liegt in
/app/backend/.webui_secret_key, nicht im Datenverzeichnis — wer nur das Volume
sichert, stellt Daten ohne passenden Schlüssel wieder her. Die Datenbank-
Schaltfläche im Admin-Bereich ist laut Doku nicht der empfohlene Sicherungsweg.
| Umgebung | Update-Strategie |
|---|---|
| eigene Spielwiese | Tag main, manuell ziehen |
| Teaminstanz | Version pinnen, Benachrichtigung über Diun |
| Produktion | Version pinnen, Release Notes lesen, erst Staging |
| nächstes Release testen | Tag dev auf eigener Instanz mit eigenem Volume |
Beim Start migriert Alembic das Schema automatisch; ohne kurzen Komplettausfall
geht das laut Doku nicht. Alle Instanzen stoppen, eine allein migrieren lassen
(UVICORN_WORKERS=1), dann die übrigen starten. Nach einer Migration bringt das
alte Image das alte Schema nicht zurück — Rollback heißt Restore.
Modul: Hochverfügbarkeit, Backup und Releases
Pilot messen, übergeben und aussteigen können
| Nutzung | Wirkung |
|---|---|
| kommt aus Analytics | kommt aus dem Fachbereich |
| Antworten, Tokens, aktive Nutzer | Zeit oder Rückfragen pro Vorgang |
| zeigt Annahme und Kostenverlauf | zeigt Arbeitsverbesserung |
| Daten | Exportweg | Grenze |
|---|---|---|
| eigene Chats | Settings > Data Controls > Export Chats | JSON, je Person |
| alle Chats | Admin-Export (ENABLE_ADMIN_EXPORT) | abschaltbar |
| Assistenten | Export der Workspace-Modelle | Format von Open WebUI |
| Wissensbasen | Export als ZIP | extrahierter Text, nicht die Originale |
| Gesamtbestand | pg_dump | Schema von Open WebUI, Abbildung nötig |
Analytics zählt Antworten des Assistenten, nicht Nachrichten der Nutzer; personenbezogene Auswertungen sind mitbestimmungspflichtig. Art. 4 der KI-Verordnung verlangt seit dem Digital Omnibus (Juli 2026) Maßnahmen zur Förderung der KI-Kompetenz — Trainingsteilnahme dokumentieren. Übergeben ist erst, wenn der Regelbetrieb eine Störung ohne das Projektteam behoben hat.
Modul: Pilot, Rollout und Übergabe
Typische Fallen
- MCP-Server mit Typ OpenAPI angelegt. Die Oberfläche hängt in einer Endlos-Ladeanzeige.
WEBUI_SECRET_KEYnicht fest gesetzt. Nach dem Neustart sind OAuth-Tokens unlesbar, bei mehreren Instanzen fliegen Nutzer beim Wechsel heraus.- Freigabe nur im Systemprompt verlangt. Das Modell kann den Aufruf trotzdem absetzen.
- Ask for approval als Vorgabe angenommen. Jede Person wählt den Modus selbst; in temporären Chats und Automationen greift er nicht.
- Workspace-Tools-Rechte an normale Nutzer. Das erlaubt eigenen Python-Code auf dem Server.
- Function scheitert beim Laden und wird still inaktiv — die Ursache steht nur im Serverlog.
- 256 Werkzeugrunden unverändert gelassen. Ein Lauf kann lange und teuer werden.
- Multi-User-Modus für eine Sicherheitsgrenze gehalten. Für Fremde braucht es Terminals mit eigenem Container je Nutzer.
- Signup in der
.envabgeschaltet, aber den Datenbankwert übersehen, der ihn überschreibt. ENABLE_LOGIN_FORM=falsesperrt auch das lokale Notfallkonto aus.- Zugriffstests als Admin. Das Konto umgeht Freigaben standardmäßig.
- Einen Injection-Test nach einem Lauf für bestanden erklärt. Modelle antworten nicht deterministisch.
REQUEST_RESPONSEvorsorglich eingeschaltet. Chatinhalte liegen dann dort, wo keine Löschung greift.LOGURU_DIAGNOSEzur Fehlersuche eingeschaltet und vergessen. Tokens und Prompts landen in den Tracebacks.- Nur
/healthüberwacht. Es meldet gesund, während kein Modell antwortet. - Ein Budget in Open WebUI gesucht. Es gibt Zählung, keine Ausgabegrenze.
- Zweite Instanz neben SQLite. Folge:
database is lockedund beschädigte Daten. - Instanzen einzeln nacheinander aktualisiert. Zwei Versionen an einer Datenbank sind nicht sicher.
- Wiederherstellung behauptet statt erprobt — und nie mit gemessener Dauer.
- Bei der Außerbetriebnahme die Sicherungen vergessen. Die Daten leben dort weiter.
Dieses Thema als Schulung für Ihr Team
Dieser Beitrag erklärt das Thema. Damit Ihr Team es danach auch anwendet, gibt es Open WebUI im Unternehmen als Schulung — an Ihrem eigenen Code, mit den Fragen, die ein Text nicht beantwortet. Sie wählen die Module, wir bauen daraus ein Programm.
6 Tage·ab 900 EUR netto pro Tag (bis 3 Teilnehmende) ·Termin nach Vereinbarung
Als Team-Schulung anfragenZum Seminar Open WebUI im Unternehmen →