进阶 omnigent.ai 2026-10-14 06:47:13 · 25 阅读
第10章 Omnigent 第10章:认证与单点登录(SSO)
Auth & SSO
认证与单点登录
Omnigent 支持三种用户认证方式,请根据实际环境选择最适合的一种:
内置账户
如果通过 Docker 或云平台部署,默认已启用基于内置账户的认证。
非 Docker 部署
对于非 Docker 部署,需手动启用内置账户:
OMNIGENT_AUTH_ENABLED=1 omni server start
创建首个管理员
出于安全考虑,服务器不会自动生成密码。在未配置管理员时,服务器将报告 needs_setup。
进行配置:打开 Web UI 创建管理员账户,或在终端运行 omni server 并按提示输入用户名和密码。
对于无头部署,可通过 --admin-password 或 OMNIGENT_ACCOUNTS_INIT_ADMIN_PASSWORD 预设密码。
邀请团队成员
前往 Admin > Members > Invite 创建一次性邀请链接。
无需邮件服务器,直接发送链接即可。注册仅限受邀者。
关于公共部署的安全提示
在存在携带密码的账户之前,创建管理员的端点 (POST /auth/setup) 是故意未加认证的。因此,如果操作员尚未到达表单时,实例暴露于公共 URL,它可能会被首个访问者占据。请预先设置 OMNIGENT_ACCOUNTS_INIT_ADMIN_PASSWORD,以便在启动时直接创建管理员,或者在完成设置前保持服务私有。
单点登录 (OIDC)
允许团队使用 Google、GitHub、Okta 或 Microsoft 登录。添加一个 OIDC Issuer 即可将模式切换为 SSO,无需额外标志。
在 deploy/docker/.env 中设置以下内容:
OMNIGENT_OIDC_ISSUER=https://accounts.google.com
OMNIGENT_DOMAIN=agents.yourcompany.com
OMNIGENT_OIDC_CLIENT_ID=...
OMNIGENT_OIDC_CLIENT_SECRET=...
docker compose up -d # 重启以生效
唯一的外部步骤是在提供商(例如 Google Cloud Console,或 GitHub > Settings > Developer settings)处创建一个应用,以获取 client ID 和 secret。将其回调 URL 设置为 https:///auth/callback。
自定义 email claim
Omnigent 默认从 IdP 的 id_token 中的 email claim 读取用户身份。部分提供商会省略该 claim——Microsoft Entra ID 通常仅颁发 preferred_username (UPN)——这会导致登录失败并提示 Could not determine user email。请将 Omnigent 指向承载身份的其他 claim:
OMNIGENT_OIDC_EMAIL_CLAIM=preferred_username
OMNIGENT_OIDC_SKIP_EMAIL_VERIFICATION=1
email_verified 仅描述 email claim,因此自定义 claim 不包含已验证标记。除非设置 OMNIGENT_OIDC_SKIP_EMAIL_VERIFICATION=1 以豁免此检查,否则登录将被拒绝——请仅对信任该 claim 提供担保的 IdP 启用此设置。设置后,claim 值会被修剪并按电子邮件地址规范。这仅适用于通用 OIDC 路径;GitHub 始终要求已验证的主电子邮件。
公开 PKCE 客户端与显式端点
通用 OIDC 路径(Okta、Auth0、Keycloak、Entra ID 以及任何发布 /.well-known/openid-configuration 的 IdP)接受两个额外的操作员级选项。两者仅配置 Omnigent 登录——不影响上游 MCP 凭据或共享会话的凭据所有权——且均不会放宽每次登录时执行的签名、过期、电子邮件验证、准入或重新认证检查。
公开客户端(无 client secret)
如果在 IdP 中将 Omnigent 注册为公开客户端,请通过 OMNIGENT_OIDC_TOKEN_ENDPOINT_AUTH_METHOD=none 选择加入,并保持 OMNIGENT_OIDC_CLIENT_SECRET 未设置:
OMNIGENT_OIDC_ISSUER=https://identity.example.com
OMNIGENT_OIDC_CLIENT_ID=omnigent
OMNIGENT_OIDC_TOKEN_ENDPOINT_AUTH_METHOD=none
Omnigent 仍会将 client ID、redirect URI 和 PKCE verifier 发送至 token 端点,但完全省略 client_secret 字段。两种模式均使用 PKCE S256,因此 IdP 必须强制执行 PKCE 和一次性授权码。
这是一个显式选择。默认的 client_secret_post 仍然要求 OMNIGENT_OIDC_CLIENT_SECRET——缺失 secret 永远不会自动切换为公开客户端模式。如果将 none 与 client secret 一起设置,或设置了其他值,或将 none 与 GitHub 登录组合使用,服务器将拒绝启动。如果正在从推断出公开客户端模式(基于缺失 secret)的自定义集成中迁移,请显式添加 OMNIGENT_OIDC_TOKEN_ENDPOINT_AUTH_METHOD=none。
显式端点(跳过发现)
当发现机制不可用,或公布的端点不适合部署时,设置所有三个覆盖项,服务器将在启动时跳过发现获取:
OMNIGENT_OIDC_ISSUER=https://identity.example.com
OMNIGENT_OIDC_CLIENT_ID=omnigent
OMNIGENT_OIDC_TOKEN_ENDPOINT_AUTH_METHOD=none
OMNIGENT_OIDC_AUTHORIZATION_ENDPOINT=https://login.example.com/authorize
OMNIGENT_OIDC_TOKEN_ENDPOINT=https://tokens.example.com/token
OMNIGENT_OIDC_JWKS_URI=https://keys.example.com/jwks
OMNIGENT_OIDC_REDIRECT_URI=https://omnigent.example.com/auth/callback
OMNIGENT_OIDC_COOKIE_SECRET=<64-hex-chars>
仅设置一个或两个覆盖项会导致启动失败,避免混合端点源;保持所有三项未设置以继续使用发现机制。
覆盖项也适用于机密客户端,且公开客户端模式可与发现机制共存——这两个选项相互独立。
GitHub 登录不支持覆盖项,其保持固定端点。
端点主机可能与 Issuer 不同,但 ID token 的 iss 必须与 OMNIGENT_OIDC_ISSUER 完全匹配,且 aud 必须与 client ID 匹配。
授权端点上的查询参数(例如 ?p=policy)会被保留。在名称冲突时,Omnigent 自身的 OAuth 参数优先。
仅受信操作员应设置这些地址。token 端点接收授权码,对于机密客户端还接收 client secret;JWKS 端点决定信任哪些签名密钥。每个覆盖项必须是绝对 HTTPS URL,不得包含嵌入的凭据或 fragment。纯 HTTP 仅针对 localhost、127.0.0.1 或 [::1] 的本地测试被接受。
签名算法
使用 PS256 签名的 ID token 将与现有的 RSA (RS256/RS384/RS512) 和 EC (ES256/ES384/ES512) 算法一同进行验证。
验证设置
使用新设置重启服务器,从无痕浏览器窗口登录,然后运行 omni login 并完成浏览器流程。两者应识别出同一预期账户。
如果企业目录省略了 email_verified,独立的 OMNIGENT_OIDC_SKIP_EMAIL_VERIFICATION=1 设置(参见自定义 email claim)仍是操作员的选择——上述选项不会自动启用它。
基于 Header 认证
如果服务器位于现有 SSO 代理(例如 OAuth2 Proxy、Cloudflare Access)之后,且该代理注入可信 Header,Omnigent 可直接从 X-Forwarded-Email 读取用户身份。Omnigent 端无需额外认证配置。
访问控制
启用认证后,控制谁可以登录以及他们能访问什么。
作用范围取决于认证模式。allowed_domains 仅适用于 OIDC 登录;留空意味着无域名限制。内置账户仅限邀请,因此域名白名单不适用;基于 Header 的认证将身份完全委托给代理。admins 列表在内置账户和 OIDC 模式下均有效。
管理员及管理界面
管理员是 admins 列表(上方所示)中的身份,以及添加到运行时可编辑的 /admins 文件中的任何人(无需重启即可重新加载)。
列出的身份将在下次登录时提升为管理员。
管理员在 Web UI 的 Settings 下拥有三个管理部分,适用于内置账户和 OIDC 模式:
Settings > Members — 用户名单(用户名、角色、最后登录时间)。
Settings > Policies — 服务器范围内的上下文策略。
Settings > Sharing — 服务器范围内的会话共享策略(参见下方的 Session sharing)。
在内置账户模式下,Members 还包含管理操作(邀请成员、重置密码、移除);在 OIDC 下它是只读名单,因为身份由 IdP 所有并在首次登录时预置。另外,每个已登录账户(内置或 OIDC)都有一个 Settings > Account 部分,显示当前登录身份,包含注销控件,仅在内置账户模式下提供更改密码功能。
移除成员
在内置账户模式下,Remove (DELETE /auth/users/{id}) 在一个数据库事务中撤销该账户所有仍可用于操作的内容。
每个经过认证请求都会重新检查存储的账户状态——包括在其他服务器副本上——因此无需等待缓存失效。移除后:
登录立即停止。现有的浏览器 Cookie 和 JWT 被拒绝,账户的设备/刷新授权(omni login,移动端和桌面端登录)被撤销,导致 token 刷新失败并返回 invalid_grant。
为该用户创建或由该用户创建的未完成的邀请和魔术登录链接被删除。
已保存的权限被移除。会话共享授权、已保存的提供商连接(GitHub、Databricks)、项目和每日支出/预算检查点被删除。位于被移除用户项目中的会话与项目分离,而非被删除。
计划任务被禁用。该用户的计划任务被标记为已删除且不再触发。
主机被移除。用户注册的主机如同从主机列表中删除一样被拆除:绑定的会话被分离,启动凭据被清除。托管云沙箱主机保留为墓碑状态,直到确认其沙箱终止。
会话历史保留。对话保留在数据库中,但无法代表被移除的所有者启动新的 runner。
移除是数据库提交边界,而非终止开关:在移除提交之前已获准的工作可以完成,但此后无法为该身份授予任何新权限。不能移除自己的账户,且最后剩余的管理员不能被移除。
用户名可复用。如果稍后再次邀请相同用户名,它将成为全新账户:不继承旧账户的共享会话、连接、项目或会话所有权,且旧 Cookie 仍然失效。
为共享用户配置密码
与从未注册过的用户名共享会话会为该用户创建一个无密码条目。要允许其登录,请在 Settings > Members 中对该行使用 Reset:首次重置将配置其凭据,同时保留已与其共享的会话,随后可以使用返回的密码登录。
升级现有账户部署
引入此撤销模型的版本会增加 schema 迁移,为现有账户及其保存的凭据打标。账户模式部署必须将所有共享数据库的服务器和调度器一起升级——旧代码无法理解新列,因此混合版本是不安全的。
备份数据库。
停止所有写入者:每个共享数据库的服务器和调度器。
升级应用并运行迁移。
仅重启新版本。
在普通浏览器会话中重新登录,并重启在升级前开始的任何提供商 OAuth 连接握手。
现有的刷新授权(CLI、移动端、桌面端登录)继续有效并更新为升级后的 token;普通 Cookie 和 JWT 需要重新登录。不要针对升级后的 schema 回滚到旧版本。
会话共享
管理员设置服务器范围内的共享策略,规定用户之间如何共享会话。它适用于服务器上的每个会话,且仅影响新授予——撤销、列出已授予、会话所有权以及已存在的授予在所有模式下均保持有效。有两种配置方式:
启动时,通过 OMNIGENT_SHARING_MODE 环境变量。
运行时,通过 Web UI 中的 Settings > Sharing。这会持久化一个覆盖项,立即生效且无需重启。
共享模式有四个层级:
OMNIGENT_SHARING_MODE=read_only omni server start
未设置或无法识别的值将默认回退为 on。在 restricted_read_only 下,如果工作区路径是文件系统根 (/)、根用户主目录 (/root),或主父目录的直接子目录(如 /home/alice、/Users/bob 或 /var/home/carol),则被认为过于宽泛而无法共享;主目录的子目录(例如 /home/alice/proj)仍可共享。
公共访问
独立于上述层级,公共访问开关控制会话是否可以与任何拥有链接的人共享(公共读访问)。它与共享模式独立——可以在禁用公共链接的同时保持正常的用户间共享。
OMNIGENT_PUBLIC_SHARING=off omni server start
除非值显式为假 (0 / false / no / off),否则公共访问是启用的;未设置或无法识别的值将默认回退为启用。它也可以在运行时从 Settings > Sharing 编辑。禁用时,Share 对话框隐藏公共访问切换,服务器拒绝新的公共授予;已公共共享的会话在撤销前保持公共状态。
新会话的默认可见性
默认情况下每个会话以私有状态启动,由所有者显式共享。第三个设置“新会话的默认可见性”允许管理员让新会话以公共读访问启动。它有三个选项:
OMNIGENT_DEFAULT_PUBLIC_SESSIONS=sandbox omni server start
与上述两个设置不同,此设置默认失败关闭 (fail closed):未设置或无法识别的值解析为 off,因此拼写错误永远不会暴露会话。它也可以在运行时从 Settings > Sharing 编辑,或通过 PUT /v1/sharing 上的 default_public_sessions。
该默认值在会话创建、分叉或由计划任务触发时应用(执行目标为 managed_sandbox 的任务计为沙箱会话)。它仅是创建时的默认值:所有者随时可以从 Share 对话框撤销公共授予,且现有会话永远不会改变。以下几类会话始终保持私有:
子 agent 会话,它们跟随父级授权。
侧边聊天,它们是调用者自身视图的私有草稿分叉。
单用户(无认证)服务器,其中根本不涉及共享。
默认值授予的权限永不超过所有者手动授予的范围。当共享模式为 off 或公共访问被禁用时,该设置处于非活动状态;在 restricted_read_only 下,它会跳过工作目录过宽而无法共享的会话(见上文)。当高层设置覆盖时,Settings > Sharing 会灰化控件并显示有效值(Private);当阻塞解除时,保存的选择将恢复。
当部署自行管理共享模式、公共访问或默认可见性时(例如注入自身策略的托管服务),Settings > Sharing 将当前值显示为只读,且无法在此处更改。
域名白名单
将注册限制为特定电子邮件域名。在服务器配置 (/data/config.yaml) 中:
allowed_domains: [yourcompany.com]
admins: [you@yourcompany.com]
邀请外部人员
需要放行域名外部的人(如承包商)?设置 OMNIGENT_OIDC_ALLOW_INVITES=1 并发送一次性邀请链接。
迁移
已在使用某种认证模式并希望切换?这些命令可以迁移现有用户,而不丢失会话或管理员权限。
从内置账户到 SSO
如果最初使用内置账户并希望切换到 OIDC,一条命令即可将所有人迁移过来,使其保留会话和管理员权限:
omni debug migrate-accounts-to-oidc --domain yourcompany.com --commit
如果没有 --commit,该命令是试运行 (dry run),仅报告将发生的变化而不修改任何内容。
| 模式 | 适用场景 |
|---|---|
| 内置账户 | 独立部署且无外部 IdP。使用用户名/密码配合邀请链接。 |
| 单点登录 (OIDC) | 使用自有 IdP:Google、GitHub、Okta、Microsoft。 |
| 基于 Header 认证 | 位于现有的 SSO 代理之后,该代理会注入 X-Forwarded-Email。 |
| 模式 | 行为 |
|---|---|
| on | 允许任何层级的授予(读 / 编辑 / 管理)以及公共和工作区读取。这是默认值。 |
| read_only | 新授予上限为读(查看);编辑和管理授予被拒绝。 |
| restricted_read_only | 只读,且工作目录为用户主目录或文件系统根目录的会话完全不可共享——即使读取也不允许。 |
| off | 共享被禁用。无法创建新授予,Share 控件隐藏。 |
| 值 | Settings > Sharing 标签 | 行为 |
|---|---|---|
| off | Private | 新会话以私有状态启动。所有者显式共享它们。这是默认值。 |
| sandbox | Cloud sandbox sessions public | 在服务器管理的云沙箱中运行的会话以公共状态启动;用户自有机器上的会话保持私有。 |
| all | All sessions public | 每个新会话均以公共读访问启动。 |