Open WebUI first-admin signup race condition fixes
Cluster 36121 · acp adapter/bootstrap. Data as of
Nothing open on GitHub. Fix merged in #56178 on 1 Jul 2026. Check it covers your case.
The short answer
- Known?
- Yes. 4 related items grouped here, 1 issue already closed.
- Fix event
- A fix was merged to main in PR #56178. Check it covers your case. No release data is tracked.
- Tracker
- The maintainers' tracker marks this
unresolved. That is separate from the fix event. - Still open
- Nothing open on GitHub.
These items address a race condition in Open WebUI's first-admin bootstrap process when signup is enabled and the service is bound to a LAN-accessible host. Changes include security lockdowns and script modifications to prevent unauthorized account creation during initial setup.
Open issues0
Open PRs0
Fixes on record
-
#56178 chore(scripts): drop Open WebUI local bootstrap script
files:
scripts/setup_open_webui.sh,website/docs/user-guide/messaging/open-webui.md,website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/messaging/open-webui.mdShow the diff
-
/dev/null@@ -1,349 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -# Bootstrap Open WebUI against Hermes Agent's OpenAI-compatible API server. -# -# Idempotent by design: -# - ensures ~/.hermes/.env has API server settings -# - installs Open WebUI into ~/.local/open-webui-venv -# - writes a reusable launcher at ~/.local/bin/start-open-webui-hermes.sh -# - optionally installs a user service (launchd on macOS, systemd --user on Linux) -# -# Usage: -# bash scripts/setup_open_webui.sh -# -# Optional environment overrides: -# OPEN_WEBUI_PORT=8080 -# OPEN_WEBUI_HOST=127.0.0.1 -# OPEN_WEBUI_NAME='Johnny Hermes' -# OPEN_WEBUI_ENABLE_SIGNUP=true -# OPEN_WEBUI_ENABLE_SERVICE=auto # auto|true|false -# OPEN_WEBUI_VENV=~/.local/open-webui-venv -# OPEN_WEBUI_DATA_DIR=~/.local/share/open-webui/data -# HERMES_API_PORT=8642 -# HERMES_API_HOST=127.0.0.1 -# HERMES_API_MODEL_NAME='Hermes Agent' - -OPEN_WEBUI_PORT="${OPEN_WEBUI_PORT:-8080}" -OPEN_WEBUI_HOST="${OPEN_WEBUI_HOST:-127.0.0.1}" -OPEN_WEBUI_NAME="${OPEN_WEBUI_NAME:-Hermes Agent WebUI}" -OPEN_WEBUI_ENABLE_SIGNUP="${OPEN_WEBUI_ENABLE_SIGNUP:-true}" -OPEN_WEBUI_ENABLE_SERVICE="${OPEN_WEBUI_ENABLE_SERVICE:-auto}" -OPEN_WEBUI_VENV="${OPEN_WEBUI_VENV:-$HOME/.local/open-webui-venv}" -OPEN_WEBUI_DATA_DIR="${OPEN_WEBUI_DATA_DIR:-$HOME/.local/share/open-webui/data}" -HERMES_ENV_FILE="${HERMES_ENV_FILE:-$HOME/.hermes/.env}" -HERMES_API_PORT="${HERMES_API_PORT:-8642}" -HERMES_API_HOST="${HERMES_API_HOST:-127.0.0.1}" -HERMES_API_CONNECT_HOST="${HERMES_API_CONNECT_HOST:-127.0.0.1}" -HERMES_API_MODEL_NAME="${HERMES_API_MODEL_NAME:-Hermes Agent}" -HERMES_API_BASE_URL="http://${HERMES_API_CONNECT_HOST}:${HERMES_API_PORT}/v1" -LAUNCHER_PATH="$HOME/.local/bin/start-open-webui-hermes.sh" -LOG_DIR="$HOME/.hermes/logs" - -log() { - printf '[open-webui-bootstrap] %s\n' "$*" -} - -require_cmd() { - if ! command -v "$1" >/dev/null 2>&1; then - echo "Missing required command: $1" >&2 - exit 1 - fi -} - -choose_python() { - if command -v python3.11 >/dev/null 2>&1; then - echo python3.11 - elif command -v python3 >/dev/null 2>&1; then - echo python3 - else - echo "Python 3 is required." >&2 - exit 1 - fi -} - -upsert_env() { - local key="$1" - local value="$2" - local file="$3" - - mkdir -p "$(dirname "$file")" - touch "$file" - - python3 - "$file" "$key" "$value" <<'PY' -from pathlib import Path -import sys -path = Path(sys.argv[1]) -key = sys.argv[2] -value = sys.argv[3] -lines = path.read_text().splitlines() if path.exists() else [] -out = [] -seen = False -for raw in lines: - stripped = raw.strip() - if stripped.startswith(f"{key}="): - if not seen: - out.append(f"{key}={value}") - seen = True - continue - out.append(raw) -if not seen: - if out and out[-1] != "": - out.append("") - out.append(f"{key}={value}") -path.write_text("\n".join(out).rstrip() + "\n") -PY -} - -get_env_value() { - local key="$1" - local file="$2" - python3 - "$file" "$key" <<'PY' -from pathlib import Path -import sys -path = Path(sys.argv[1]) -key = sys.argv[2] -if not path.exists(): - raise SystemExit(0) -for raw in path.read_text().splitlines(): - line = raw.strip() - if line.startswith(f"{key}="): - print(line.split("=", 1)[1]) - raise SystemExit(0) -PY -} - -generate_secret() { - python3 - <<'PY' -import secrets -print(secrets.token_urlsafe(32)) -PY -} - -shell_quote() { - python3 - "$1" <<'PY' -import shlex -import sys -print(shlex.quote(sys.argv[1])) -PY -} - -can_use_systemd_user() { - [[ "$(uname -s)" == "Linux" ]] || return 1 - command -v systemctl >/dev/null 2>&1 || return 1 - - local uid runtime_dir bus_path - uid="$(id -u)" - runtime_dir="${XDG_RUNTIME_DIR:-/run/user/$uid}" - bus_path="$runtime_dir/bus" - - if [[ -z "${XDG_RUNTIME_DIR:-}" && -d "$runtime_dir" ]]; then - export XDG_RUNTIME_DIR="$runtime_dir" - fi - if [[ -z "${DBUS_SESSION_BUS_ADDRESS:-}" && -S "$bus_path" ]]; then - export DBUS_SESSION_BUS_ADDRESS="unix:path=$bus_path" - fi - - systemctl --user show-environment >/dev/null 2>&1 -} - -install_macos_dependencies() { - if [[ "$(uname -s)" == "Darwin" ]] && command -v brew >/dev/null 2>&1; then - if ! command -v pandoc >/dev/null 2>&1; then - log 'Installing pandoc with Homebrew (recommended by Open WebUI docs)...' - brew install pandoc - fi - fi -} - -install_open_webui() { - local py - py="$(choose_python)" - log "Using Python interpreter: $py" - "$py" -m venv "$OPEN_WEBUI_VENV" - # shellcheck disable=SC1090 - source "$OPEN_WEBUI_VENV/bin/activate" - "$py" -m pip install --upgrade pip setuptools wheel - "$py" -m pip install open-webui -} - -write_launcher() { - mkdir -p "$(dirname "$LAUNCHER_PATH")" "$OPEN_WEBUI_DATA_DIR" "$LOG_DIR" - - local quoted_data_dir quoted_name quoted_base_url quoted_host quoted_port quoted_venv - quoted_data_dir="$(shell_quote "$OPEN_WEBUI_DATA_DIR")" - quoted_name="$(shell_quote "$OPEN_WEBUI_NAME")" - quoted_base_url="$(shell_quote "$HERMES_API_BASE_URL")" - quoted_host="$(shell_quote "$OPEN_WEBUI_HOST")" - quoted_port="$(shell_quote "$OPEN_WEBUI_PORT")" - quoted_venv="$(shell_quote "$OPEN_WEBUI_VENV")" - - cat > "$LAUNCHER_PATH" <<EOF -#!/usr/bin/env bash -set -euo pipefail -export PATH="/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin" -API_KEY=[redacted:secret-assignment] - <<'PY' -from pathlib import Path -p = Path.home()/'.hermes'/'.env' -for raw in p.read_text().splitlines(): - line = raw.strip() - if line.startswith('API_SERVER_KEY='): - print(line.split('=', 1)[1]) - break -PY -) -export DATA_DIR=${quoted_data_dir} -export WEBUI_NAME=${quoted_name} -export ENABLE_SIGNUP=${OPEN_WEBUI_ENABLE_SIGNUP} -export ENABLE_PUBLIC_ACTIVE_USERS_COUNT=False -export ENABLE_VERSION_UPDATE_CHECK=False -export OPENAI_API_BASE_URL=${quoted_base_url} -export OPENAI_API_KEY="[redacted:secret-assignment]" -export ENABLE_OPENAI_API=True -export ENABLE_OLLAMA_API=False -export OFFLINE_MODE=True -export BYPASS_EMBEDDING_AND_RETRIEVAL=True -export RAG_EMBEDDING_MODEL_AUTO_UPDATE=False -export RAG_RERANKING_MODEL_AUTO_UPDATE=False -export SCARF_NO_ANALYTICS=true -export DO_NOT_TRACK=true -export ANONYMIZED_TELEMETRY=false -export HOST=${quoted_host} -export PORT=${quoted_port} -source ${quoted_venv}/bin/activate -exec open-webui serve -EOF - - chmod +x "$LAUNCHER_PATH" -} - -ensure_env_permissions() { - chmod 600 "$HERMES_ENV_FILE" 2>/dev/null || true -} - -install_launchd_service() { - local plist="$HOME/Library/LaunchAgents/ai.openwebui.hermes.plist" - mkdir -p "$(dirname "$plist")" - cat > "$plist" <<EOF -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>Label</key> - <string>ai.openwebui.hermes</string> - <key>ProgramArguments</key> - <array> - <string>/bin/bash</string> - <string>${LAUNCHER_PATH}</string> - </array> - <key>RunAtLoad</key> - <true/> - <key>KeepAlive</key> - <true/> - <key>WorkingDirectory</key> - <string>${HOME}</string> - <key>StandardOutPath</key> - <string>${LOG_DIR}/openwebui.log</string> - <key>StandardErrorPath</key> - <string>${LOG_DIR}/openwebui.error.log</string> -</dict> -</plist> -EOF - launchctl bootout "gui/$(id -u)" "$plist" >/dev/null 2>&1 || true - launchctl bootstrap "gui/$(id -u)" "$plist" - launchctl enable "gui/$(id -u)/ai.openwebui.hermes" - launchctl kickstart -k "gui/$(id -u)/ai.openwebui.hermes" -} - -install_systemd_user_service() { - require_cmd systemctl - local unit_dir="$HOME/.config/systemd/user" - local unit="$unit_dir/openwebui-hermes.service" - mkdir -p "$unit_dir" - cat > "$unit" <<EOF -[Unit] -Description=Open WebUI connected to Hermes Agent -After=default.target - -[Service] -Type=simple -ExecStart=/bin/bash %h/.local/bin/start-open-webui-hermes.sh -Restart=always -RestartSec=3 -WorkingDirectory=%h -StandardOutput=append:%h/.hermes/logs/openwebui.log -StandardError=append:%h/.hermes/logs/openwebui.error.log - -[Install] -WantedBy=default.target -EOF - systemctl --user daemon-reload - systemctl --user enable --now openwebui-hermes.service -} - -start_foreground_hint() { - log "Launcher created at: ${LAUNCHER_PATH}" - log "Start Open WebUI manually with: ${LAUNCHER_PATH}" -} - -main() { - require_cmd hermes - require_cmd curl - require_cmd python3 - - install_macos_dependencies - - local api_key - api_key="[redacted:secret-assignment] API_SERVER_KEY "$HERMES_ENV_FILE")" - if [[ -z "$api_key" ]]; then - api_key="[redacted:secret-assignment]" - fi - - log 'Ensuring Hermes API server is configured...' - upsert_env API_SERVER_ENABLED true "$HERMES_ENV_FILE" - upsert_env API_SERVER_HOST "$HERMES_API_HOST" "$HERMES_ENV_FILE" - upsert_env API_SERVER_PORT "$HERMES_API_PORT" "$HERMES_ENV_FILE" - upsert_env API_SERVER_MODEL_NAME "$HERMES_API_MODEL_NAME" "$HERMES_ENV_FILE" - upsert_env API_SERVER_KEY "$api_key" "$HERMES_ENV_FILE" - ensure_env_permissions - - log 'Restarting Hermes gateway so API server settings take effect...' - hermes gateway restart >/dev/null 2>&1 || true - sleep 4 - if ! curl -fsS "http://${HERMES_API_CONNECT_HOST}:${HERMES_API_PORT}/health" >/dev/null; then - log 'Hermes API server did not answer on the first check. Trying to start gateway in the background...' - nohup hermes gateway run >/dev/null 2>&1 & - sleep 6 - fi - curl -fsS "http://${HERMES_API_CONNECT_HOST}:${HERMES_API_PORT}/health" >/dev/null - - log 'Installing Open WebUI into a dedicated virtualenv...' - install_open_webui - write_launcher - - case "$OPEN_WEBUI_ENABLE_SERVICE" in - true|auto) - if [[ "$(uname -s)" == "Darwin" ]]; then - install_launchd_service - elif can_use_systemd_user; then - install_systemd_user_service - else - log 'No usable user service manager detected; falling back to the launcher script.' - start_foreground_hint - fi - ;; - false) - start_foreground_hint - ;; - *) - echo "OPEN_WEBUI_ENABLE_SERVICE must be one of: auto, true, false" >&2 - exit 1 - ;; - esac - - log "Done. Open WebUI should be available at: http://${OPEN_WEBUI_HOST}:${OPEN_WEBUI_PORT}" - log "Hermes API endpoint: ${HERMES_API_BASE_URL}" - log 'Important: Open WebUI persists connection settings after first launch. If you later save a wrong API key in the Admin UI, update/delete that connection there or reset its database.' -} - -main "$@" -
website/docs/user-guide/messaging/open-webui.md@@ -30,44 +30,6 @@ Open WebUI talks to Hermes server-to-server, so you do not need `API_SERVER_CORS ## Quick Setup -### One-command local bootstrap (macOS/Linux, no Docker) - -If you want Hermes + Open WebUI wired together locally with a reusable launcher, run: - -```bash -cd ~/.hermes/hermes-agent -bash scripts/setup_open_webui.sh -``` - -What the script does: - -- ensures `~/.hermes/.env` contains `API_SERVER_ENABLED`, `API_SERVER_HOST`, `API_SERVER_KEY`, `API_SERVER_PORT`, and `API_SERVER_MODEL_NAME` -- restarts the Hermes gateway so the API server comes up -- installs Open WebUI into `~/.local/open-webui-venv` -- writes a launcher at `~/.local/bin/start-open-webui-hermes.sh` -- on macOS, installs a `launchd` user service; on Linux with `systemd --user`, installs a user service there - -Defaults: - -- Hermes API: `http://127.0.0.1:8642/v1` -- Open WebUI: `http://127.0.0.1:8080` -- model name advertised to Open WebUI: `Hermes Agent` - -Useful overrides: - -```bash -OPEN_WEBUI_NAME='My Hermes UI' \ -OPEN_WEBUI_ENABLE_SIGNUP=true \ -HERMES_API_MODEL_NAME='My Hermes Agent' \ -bash scripts/setup_open_webui.sh -``` - -On Linux, automatic background service setup requires a working `systemd --user` session. If you are on a headless SSH box and want to skip service installation, run: - -```bash -OPEN_WEBUI_ENABLE_SERVICE=false bash scripts/setup_open_webui.sh -``` - ### 1. Enable the API server ```bash -
website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/messaging/open-webui.md@@ -30,44 +30,6 @@ Open WebUI 与 Hermes 之间是服务器到服务器的通信,因此此集成 ## 快速设置 -### 本地一键引导(macOS/Linux,无需 Docker) - -如果你希望在本地将 Hermes 与 Open WebUI 连接并使用可复用的启动器,请运行: - -```bash -cd ~/.hermes/hermes-agent -bash scripts/setup_open_webui.sh -``` - -脚本执行内容: - -- 确保 `~/.hermes/.env` 包含 `API_SERVER_ENABLED`、`API_SERVER_HOST`、`API_SERVER_KEY`、`API_SERVER_PORT` 和 `API_SERVER_MODEL_NAME` -- 重启 Hermes gateway 以启动 API 服务器 -- 将 Open WebUI 安装到 `~/.local/open-webui-venv` -- 在 `~/.local/bin/start-open-webui-hermes.sh` 写入启动器 -- 在 macOS 上安装 `launchd` 用户服务;在支持 `systemd --user` 的 Linux 上安装用户服务 - -默认值: - -- Hermes API:`http://127.0.0.1:8642/v1` -- Open WebUI:`http://127.0.0.1:8080` -- 向 Open WebUI 公告的模型名称:`Hermes Agent` - -常用覆盖参数: - -```bash -OPEN_WEBUI_NAME='My Hermes UI' \ -OPEN_WEBUI_ENABLE_SIGNUP=true \ -HERMES_API_MODEL_NAME='My Hermes Agent' \ -bash scripts/setup_open_webui.sh -``` - -在 Linux 上,自动后台服务设置需要可用的 `systemd --user` 会话。如果你在无头 SSH 机器上并希望跳过服务安装,请运行: - -```bash -OPEN_WEBUI_ENABLE_SERVICE=false bash scripts/setup_open_webui.sh -``` - ### 1. 启用 API 服务器 ```bash
-
2 PRs closed without merging
From the close comments: superseded by another PR 2
Closed issues · 1
- Closed#36121OpenWebUI first-admin race when ENABLE_SIGNUP=true (default) + OPEN_WEBUI_HOST=0.0.0.0 (LAN bind)
How this cluster was grouped
-
Link evidence (
structural links throughout): every member is connected by structural evidence: shared changed files, or a closing/superseded reference. -
Pairwise link density
0.50: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36.1.00means every pair is linked.
Pick up a Lab task
Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.
Open the LabAt a glance
- Subsystem
- acp adapter/bootstrap
- Merged PRs
- #56178
- Closed issues
- 1
- Attempts
- 2 PRs closed without merging
- Fix link checked
- 1 Jul 2026