加固 OPL 数据空间
OPL 数据空间是一个自托管应用,它会给已认证用户暴露模型推理、工具执行、代码流水线等能力。和数据库、容器镜像仓库、CI 服务器一样,部署方需要自己负责环境、网络暴露面与配置策略。 OPL 数据空间提供本页提到的控制项,但如何组合使用,取决于你的部署环境、合规要求与威胁模型。
本页关注的是“有哪些可用于加固部署的配置项”,而不是替代完整安全方案。你最终仍然需要根据自己的环境来决定哪些项必须启用。
网络放置
OPL 数据空间更适合部署在私有、可信网络里,类似数据库或内部 CI 服务。
更稳妥的生产部署通常会把它放在以下边界之后:
- VPN(WireGuard、Tailscale)
- 零信任访问代理(Cloudflare Access、Pomerium)
- 带认证与 IP 白名单的反向代理
DDoS 防护、爆破防护、连接限速、fail2ban 这类能力,通常应该放在代理层或网络层,而不是依赖应用本身。
如果你是第一次部署 OPL 数据空间,建议先看本页最后的 Quick Reference,再按需逐节细化。
Secret Key
WEBUI_SECRET_KEY 用于:
- 签发 JWT(登录 token)
- 派生 OAuth 会话加密密钥
默认行为
当你通过 Docker 或 open-webui serve 启动时,如果没有显式设置 WEBUI_SECRET_KEY,应用会自动生成一个随机 key,并保存到数据目录中的 .webui_secret_key。后续重启会继续读取它。
因此,对单实例部署来说,通常不需要手工设置。
什么时候必须显式设置
如果你在负载均衡后运行多个 OPL 数据空间实例,它们必须共享同一个 key。否则:
- 一个实例签发的 token
- 会被另一个实例视为无效
从而导致登录失败或会话异常。
可用下面的方式生成:
openssl rand -base64 32然后把同一个值传给所有副本。
轮换影响
修改 WEBUI_SECRET_KEY 会使所有现有会话失效,用户需要重新登录。
认证与注册
注册
默认情况下,注册入口只在首个用户注册之前开放。第一个注册用户会自动成为管理员,之后注册会自动关闭。
新账户的默认角色是 pending,这意味着即便管理员后来重新打开了注册入口(ENABLE_SIGNUP=true),新用户仍然需要管理员审批后才能真正使用系统。
DEFAULT_USER_ROLE=pending密码校验
OPL 数据空间默认不强制密码复杂度。若 要开启:
ENABLE_PASSWORD_VALIDATION=true
PASSWORD_VALIDATION_REGEX_PATTERN='^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^\w\s]).{8,}$'
PASSWORD_VALIDATION_HINT='Minimum 8 characters with uppercase, lowercase, number, and special character.'密码以 bcrypt 哈希存储,并受其 72 字节输入上限约束。
用环境变量初始化管理员账户
适合自动化部署:
WEBUI_ADMIN_EMAIL=admin@yourcompany.com
WEBUI_ADMIN_PASSWORD=your-strong-password
WEBUI_ADMIN_NAME=Admin这一组配置只会在“数据库中尚无用户”时生效。
组织与作用域化管理
如果你的部署启用了组织,不要假设所有“管理员界面”都天然是全局的。审计员、经理、组织管理员、全局管理员在不同作用域下看到的数据与设置入口可能不同。
在加固部署中,建议明确记录:
- 哪些角色能改租户内配置
- 哪些设置只能由全局管理员控制
- 团队如何确认当前选中的组织作用域
这能减少“改错租户”或“误以为某个功能实例级关闭,实际只是组织级关闭”的风险。
纯 SSO 环境
如果所有认证都由 OAuth/OIDC 提供方负责,可以隐藏本地登录表单:
ENABLE_LOGIN_FORM=false
ENABLE_PASSWORD_AUTH=false
ENABLE_PASSWORD_CHANGE_FORM=false这适合 SSO-only 环境,避免向用户暴露不应使用的本地密码路径。
会话与 Cookie 安全
Cookie 设置
在 HTTPS 部署下,建议:
WEBUI_SESSION_COOKIE_SECURE=true
WEBUI_SESSION_COOKIE_SAME_SITE=strict| Variable | Default | 作用 |
|---|---|---|
WEBUI_SESSION_COOKIE_SECURE | false | 只允许通过 HTTPS 发送 cookie |
WEBUI_SESSION_COOKIE_SAME_SITE | lax | 控制 cookie 是否随跨站请求发送 |
同样规则也适用于 OAuth cookie,除非你单独设置了 WEBUI_AUTH_COOKIE_SECURE 与 WEBUI_AUTH_COOKIE_SAME_SITE。
Token 过期时间
默认 JWT 过期时间是 4w。可以改短:
JWT_EXPIRES_IN=24h若设为 -1,则等于完全关闭过期机制, OPL 数据空间会打印警告。
Token 撤销
如果没有 Redis,用户登出后 token 仍然有效,直到它自然过期。这意 味着:
- 被泄露的 token 无法通过登出来失效
- 改密码不会立刻踢掉旧会话
- 管理员停用账号也不会即时生效
若配置了 Redis, OPL 数据空间才能维护 token 撤销列表,实现真正的生产级会话失效。
如果暂时无法部署 Redis,至少应缩短 JWT_EXPIRES_IN,例如 1h 或 4h。Redis 配置可参考 Redis 教程。
CORS
CORS_ALLOW_ORIGIN 决定哪些站点能从浏览器中向你的 OPL 数据空间 API 发起请求。
默认值是 *,代表允许任意来源,启动时 OPL 数据空间会对此发出警告。
生产环境建议收紧到自己的域名:
CORS_ALLOW_ORIGIN=https://chat.yourcompany.com多个来源之间用分号分隔:
CORS_ALLOW_ORIGIN=https://chat.yourcompany.com;https://internal.yourcompany.com如果你有桌面端自定义协议,也可补充:
CORS_ALLOW_CUSTOM_SCHEME=app安全头
OPL 数据空间提供 SecurityHeadersMiddleware 注入 HTTP 安全头,但默认不会自动启用任何项,需要通过环境变量显式打开。
一个常见的起始配置如下:
HSTS=max-age=31536000;includeSubDomains
XFRAME_OPTIONS=DENY
XCONTENT_TYPE=nosniff
REFERRER_POLICY=strict-origin-when-cross-origin
PERMISSIONS_POLICY=camera=(),microphone=(),geolocation=()
CONTENT_SECURITY_POLICY=default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'
CONTENT_SECURITY_POLICY_REPORT_ONLY=default-src 'self'; report-uri /csp-report
CROSS_ORIGIN_EMBEDDER_POLICY=require-corp
CROSS_ORIGIN_OPENER_POLICY=same-origin
CROSS_ORIGIN_RESOURCE_POLICY=same-origin
REPORTING_ENDPOINTS=default="https://your-report-collector.example/reports"如果你启用了 CSP,建议先从宽松策略开始,再逐步收紧。可以先用 CONTENT_SECURITY_POLICY_REPORT_ONLY 测试,避免一上来就把前端资源拦坏。
如果同时设置:
CROSS_ORIGIN_EMBEDDER_POLICY=require-corpCROSS_ORIGIN_OPENER_POLICY=same-origin
就会启用跨源隔离。这可能导致外部图片、脚本或 iframe 无法加载,除非对方资源明确带有合适的 CORS 头。
HTTPS 与 TLS
OPL 数据空间本身不终止 TLS。推荐把它放在 Nginx、Caddy、HAProxy 等反向代理之后,由代理负责 HTTPS。具体配置见 HTTPS Reference。
启用 HTTPS 后,通常至少再补:
WEBUI_SESSION_COOKIE_SECURE=true
HSTS=max-age=31536000;includeSubDomains