身份验证与安全
Libre WebUI 使用本地用户账户和 JWT 会话。全新安装始终允许引导创建一名本地管理员。此后所有本地或 OAuth 账户的公开注册默认关闭。
首次设置
数据库没有用户时:
- Libre WebUI 显示首次设置流程。
- 用户创建第一个本地账户。
- 该账户获分配
admin角色。 - 除非明确启用,否则后续所有公开注册保持关闭。
现有数据库保留当前用户和角色。
本地账户
本地注册要求:
- 用户名
- 密码长度为 12 个字符至 72 个 UTF-8 字节,包含大写字母、小写字母和数字
- 可选电子邮件
密码在存储前使用 bcrypt 哈希。登录和注册路由有速率限制。
注册审批
公开注册本身不会授予访问权限。通过公开注册表单或 OAuth 提供商创建的每个账户初始状态均为 pending,必须经管理员批准才能登录。
唯一例外是引导:空数据库中的第一个真实账户以原子方式创建为 active,角色为 admin,确保全新安装能得到可用管理员。之后的注册都等待审核。
待审批用户会看到:
- 注册成功但不返回会话令牌。API 响应
202和approvalRequired: true,界面说明需要管理员批准。 - 使用正确密码登录也会以
403和代码ACCOUNT_PENDING("Your account is waiting for administrator approval")拒绝。OAuth 登录重定向到带?approval=pending的登录页。 - 每个已验证请求都会从数据库重新读取账户状态,因此会话绝不会超越账户的
active状态。
管理员会看到:
- 用户管理显示 待审批 卡片,列出等待账户,并为每个账户提供 激活账户 和拒绝操作。拒绝即删除;没有单独的暂停状态。
- 管理员登录后会收到应用内通知:用户入口显示徽章,新注册到达时显示提示。待审批摘要约每分钟轮询一次(
GET /api/users/pending-approvals,仅管理员)。 - 审批(
PATCH /api/users/:id/approve,仅管理员)记录批准者和时间,但不更改角色:已批准账户仍为user,直到管理员提升。审批在用户下一次登录尝试时生效,无需重新创建任何内容。
升级不会影响现有账户:只有该功能发布后通过公开注册创建的账户初始为待审批。管理员从用户管理创建的账户立即激活。
主动启用公开注册
注册默认禁用。仅在希望接受新本地或 OAuth 账户的期间设置以下后端环境变量:
ENABLE_SIGNUP=true
计划注册窗口结束后恢复为 false。公开注册关闭时,现有本地和 OAuth 用户仍能登录,管理员仍能从用户管理创建账户。
即使 ENABLE_SIGNUP=false,空数据库也始终允许创建一个本地管理员;OAuth 不能占用该引导名额。私有远程部署应在首次启动前,将主机名置于 Cloudflare Access 等身份允许列表之后,再从受保护路由创建初始管理员。
角色
| 角色 | 用途 |
|---|---|
admin | 实例管理、用户管理、系统设置和可信 Work 运行时操作 |
user | 常规聊天、模型、角色、文档和设置流程 |
模型安装、删除、复制、推送和卸载仅限管理员,因为这些操作会更改宿主机资源。
Work 访问权限
Work 默认仅限管理员,因为它允许所选模型在受管容器中执行任意命令。管理员可从设置中的用户管理选项卡向所有活跃用户开放 Work;设置在重启后保留并立即生效,包括已打开的终端会话。宿主机文件夹工作区在所有模式下仍仅限管理员,因为它们会绑定挂载服务器路径。应将所有获准使用 Work 的人视为可信运行时操作员,而不只是 WebUI 用户。
管理员授权依据数据库中的当前角色检查,而不只依赖现有 JWT 中缓存的角色。因此,降低管理员权限会立即撤销 Work 访问。后端随后尝试中止活跃运行并停止该用户的 Work 容器和预览,同时保留任务记录和命名卷。若 Docker 清理失败,访问仍保持撤销,角色更改会报告清理失败,操作员必须恢复 Docker 访问并重试。
删除用户会销毁该用户的 Work 数据。Libre WebUI 先停止受管容器并移除 Work 卷,再删除账户和数据库记录。若 Docker 无法证明清理成功,账户删除会失败,以便管理员修复运行时问题后重试。
组与资源授权
管理员可从设置中的用户管理选项卡创建组并管理成员。组是资源授权主体:聊天、笔记、文档、知识集合、文件夹、角色、提示词、技能或日历的所有者可通过访问 API 向用户或组授予 read、write 或 admin。所有可共享界面使用同一共享对话框(参阅共享),管理员也可同样限定已注册工具服务器。资源默认保持私有;全局 admin 角色不授予其他用户内容的访问权限。成员身份在请求时求值,因此移除成员会立即撤销组授权。设置中用户管理选项卡的“有效访问”视图通过列出角色、组、功能访问和所有到达授权,解释用户为何能访问资源。
安全审计日志
安全敏感操作——登录及失败、退出、会话和令牌撤销、用户/组/授权/令牌更改——记录在独立于使用分析的只追加审计日志中。详细信息在存储前脱敏:类似密钥的键会删除,载荷大小受限,因此密码、令牌和提示词内容绝不进入日志。组和授权修改在同一数据库事务中写入审计事件,因此更改不会没有轨迹。管理员可从设置中的用户管理选项卡查询日志;默认保留 180 天(AUDIT_RETENTION_DAYS)。
会话
后端使用 JWT_SECRET 签署 JWT。生产环境应设置稳定密钥:
JWT_SECRET=replace-with-a-long-random-secret
更改 JWT_SECRET 会使现有会话失效。本地和 OAuth 登录令牌使用 JWT_EXPIRES_IN,默认 7d;修改只影响新会话。WebSocket 连接会将持久令牌换成短期、一次性票据,并在底层会话过期时关闭。
每次登录还会创建绑定到 JWT 的服务器端会话记录。设置 → 会话按设备列出登录方式、首次和最近活动及到期时间。在此撤销会话(或“退出其他会话”)会立即在所有副本上使令牌失效,并关闭其活跃 WebSocket;退出当前会话采用相同方式。该功能前签发的令牌没有会话 ID,在到期前仍有效,但从新登录执行“退出其他会话”还会设置账户级截止点并拒绝它们。
双重身份验证与通行密钥
设置 → 会话同时管理第二因素和无密码登录:
- 身份验证器应用(TOTP)。 注册会显示 base32 密钥和可供任何身份验证器使用的
otpauth://链接;确认首个 6 位代码会激活并显示十个一次性恢复码。之后,密码登录返回短期挑战而非会话,POST /api/auth/mfa/verify使用 TOTP 或恢复码完成登录。每个已接受代码的时间步会记录,防止截获代码重放;恢复码只存储为带密钥的单向查找令牌,每个只能使用一次。禁用或重新生成恢复码需要再次证明一个因素。 - 通行密钥(WebAuthn)。 “使用通行密钥登录”通过可发现凭据进行无密码登录;注册和登录都要求用户验证(屏幕锁、生物识别或 PIN)。接受
none证明,支持 ES256 和 EdDSA 凭据;凭据材料静态加密,ID 保存为带密钥查找令牌。挑战只可使用一次,五分钟后过期;非零签名计数器未递增会作为克隆信号拒绝。通行密钥需要安全 HTTPS 源,开发环境可用localhost;实例通过多个主机名访问时设置WEBAUTHN_RP_ID。
密码正确后签发的 MFA 挑战令牌使用派生自但不同于 JWT_SECRET 的密钥签名:它绝不能验证 API 请求,仅绑定一个账户和用途,成功后即消耗。
管理员可要求所有账户使用第二因素(用户 → 双重验证策略卡片,或设置 MFA_REQUIRED_MODE=required)。没有第二因素的用户下次登录时会先完成注册,之后才签发会话。管理员也可从用户列表重置用户的 TOTP 注册以恢复账户;通行密钥保留,由用户从设置管理。注册、激活、验证失败、禁用、策略更改、通行密钥注册/移除和管理员重置都会记录到安全审计日志。
MFA 适用于密码登录。OAuth 和 OIDC 登录依赖身份提供商的第二因素,不会再次挑战。API 令牌不受影响:它们不经过会话身份验证。
API 令牌
设置 → API 密钥可创建供程序使用的个人访问令牌(前缀 lwk_)。密钥仅显示一次,只存储哈希。每个令牌携带明确范围列表(chat、models、documents、notes、personas、media、work、admin);后端为每类路由映射所需范围,因此仅笔记令牌不能访问聊天或管理,令牌永远不能访问会话管理。令牌支持可选过期时间、记录最近使用、可随时撤销,并在副本间按令牌限流。只有管理员可创建 admin 范围令牌,使用时账户仍必须拥有管理员角色。chat 范围令牌也是 OpenAI 兼容公共 /v1 API 的密钥。
Cloudflare Turnstile
同时配置两个密钥时,Turnstile 会保护密码登录和注册:
TURNSTILE_SITE_KEY=...
TURNSTILE_SECRET_KEY=...
TURNSTILE_EXPECTED_HOSTNAME=chat.example.com
前端分配不同的 login 和 signup 操作。后端通过 Cloudflare 验证令牌,并拒绝主机名或操作与请求不匹配的响应。未显式设置 TURNSTILE_EXPECTED_HOSTNAME 时,BASE_URL 提供预期主机名。
缺少任一密钥时,Turnstile 会禁用。
GitHub OAuth
配置:
GITHUB_CLIENT_ID=...
GITHUB_CLIENT_SECRET=...
GITHUB_CALLBACK_URL=https://your-domain.example/api/auth/oauth/github/callback
GitHub OAuth 流程创建用户名带 gh_ 前缀的本地用户,默认分配 user 角色。
Hugging Face OAuth
配置:
HUGGINGFACE_CLIENT_ID=...
HUGGINGFACE_CLIENT_SECRET=...
HUGGINGFACE_CALLBACK_URL=https://your-domain.example/api/auth/oauth/huggingface/callback
Hugging Face OAuth 流程创建用户名带 hf_ 前缀的本地用户,默认分配 user 角色。
两个 OAuth 提供商都使用密码学随机 state,并绑定到短期 HttpOnly、SameSite Cookie。回调拒绝缺失或不匹配的状态。成功后,JWT 通过 60 秒 HttpOnly Cookie 返回前端,立即交换并清除;Bearer 令牌绝不会放入回调 URL、浏览器历史或 referrer 标头。
重定向与 CORS
设置 BASE_URL 作为回调默认值,设置 CORS_ORIGIN 供浏览器访问:
BASE_URL=https://your-domain.example
CORS_ORIGIN=https://your-domain.example
本地开发应加入 Vite 开发源:
CORS_ORIGIN=http://localhost:5173,http://127.0.0.1:5173
演示模式
演示模式是前端预览模式。它会预填已禁用的演示凭据并使用模拟 API 响应,不是生产身份验证模式。
安全检查清单
- 设置强
JWT_SECRET。 - 将
DATA_DIR保存在持久、受访问控制的存储中。 - 将
ENCRYPTION_KEY与数据库一同备份。 - 为公开注册配置 Turnstile。
- 公共部署使用 HTTPS。
- 将提供商 API 密钥限制到所需最小范围。
- 保持 OAuth 回调 URL 完全准确。
- 仅向可信任、可操作后端容器运行时的人员授予 Work 访问(管理员账户或向所有用户开放模式)。