Files
2026-07-26 21:32:12 +08:00

3.3 KiB
Raw Permalink Blame History

安全模型

中文 · English

信任边界

只有 Open WebUI 对公网开放。Runtime、Gateway、PostgreSQL 和 Redis 位于内部 Compose 网络。

Open WebUI 会转发一个短期 HS256 用户 JWT。Runtime 和 Gateway 会验证其签名、签发者、 过期时间和主体,并且还要求独立的服务 Bearer Key。因此,仅复制用户身份 Token 不能调用 任何内部服务。Runtime 在接受公开请求时验证一次身份,之后每次调用 Gateway 都会基于已验证 身份重新签发一个新的短期 Token。长时间运行的 Agent 不会复用已经过期的原始请求 Token。

浏览器永远不会获得:

  • 上游 Provider URL 或 API Key
  • Provider 模型 ID
  • Workspace Gateway 服务密钥;
  • 用户身份签名密钥;
  • Docker、SSH、MCP/OpenAPI、提示词或实验配置。

工作区隔离

每个用户都会获得独立容器和命名卷,其名称来自不可变 Open WebUI 用户 ID 的 SHA-256 哈希。 容器:

  • 以 UID/GID 1000 运行;
  • 使用只读根文件系统和可写 /workspace 卷;
  • 将 Python 虚拟环境、用户软件包和缓存状态保存在持久化 /workspace 卷中;
  • 允许出网时使用专用的每用户 Bridge 网络;
  • 丢弃全部 Linux Capability
  • 启用 no-new-privileges
  • 设置内存、CPU 和 PID 限制;
  • 不挂载 Docker Socket
  • 不向宿主机发布任何端口。

只有 Workspace Gateway 在本地模式下获得 Docker Socket。Runtime 和 Open WebUI 永远不会 获得它。远程模式会移除 Socket 挂载,将指定 SSH 配置只读挂载,并把 Docker 权限转移到通过 SSH 连接的执行主机。

工作区路径会被规范化,任何逃逸 /workspace 的路径都会被拒绝。文件浏览和下载使用同一 身份边界。单文件下载默认限制为 128 MiB,目录归档采用流式传输。

部署密钥

密钥只存在于 Git 之外、权限为 600 的部署 .env 中。镜像不包含 Provider 或基础设施凭据。 应用代码不会把 Provider 凭据返回浏览器、写入日志或提交到 Git。

Web 镜像从固定 commit 的 Open WebUI 版本构建,Node 和 Python 基础镜像均固定 Digest。 RAG/向量、云存储、媒体模型、浏览器自动化和未使用的密码学依赖被排除。发布验收会同时审计 仓库环境与最终 Web 镜像。scripts/audit-web-image.sh 要求:

  • pip check 报告 Python 环境依赖一致;
  • pip-audit 报告零个已知 Python 漏洞,且不忽略任何漏洞 ID;
  • Trivy 报告零个可修复的 High/Critical 操作系统或库漏洞。

scripts/audit-images.sh 对 Web、Runtime、Gateway 和用户 Workspace 镜像应用相同的 High/Critical 可修复漏洞门禁。截至 2026-07-26,四个镜像均通过。Trivy 还在 Web 镜像中 报告了 38 个 Debian 尚未提供修复的 High/Critical 问题;发布门禁通过 --ignore-unfixed 单独记录它们,而不是假装应用层修改能够修复。

面向恶意公网用户前仍需加强

工作区运行在专用物理 Docker 主机上,与公网 Web 和数据库服务分离,但 Docker Daemon 仍是高价值边界。在将系统视为恶意多租户基础设施之前,还应加入每工作区出网策略、镜像签名、 集中审计保留、备份恢复演练、配额和资源滥用告警。