为你的项目配置 OIDC¶
OIDC 是 Legate 在共享和生产环境中推荐的管理员认证方式。身份提供商负责证明“这个人是谁”,Legate 负责内部用户、平台管理员权限、工作空间成员关系、邀请、会话和最终授权。
Legate 没有本地密码数据库、密码重置或公开注册。切换到 OIDC 不会出现一个 Legate 用户名密码表单。
认证模型¶
Legate 明确区分三个对象:
| 对象 | 含义 |
|---|---|
| User | Legate 内部稳定用户,以数字 userId 参与授权 |
| Identity | 精确的 (providerId, OIDC subject) 外部身份绑定 |
| Session | 登录成功后创建的可撤销、不透明浏览器会话 |
返回用户只通过 (providerId, subject) 匹配。Legate 不会因为 OIDC email 相同就自动合并账号。Email 只在一次性首位管理员匹配和邀请认领时使用,并且必须来自 verified email claim。
前置条件¶
准备以下资源:
- 一个支持 OIDC Authorization Code Flow 的身份提供商;
- 可访问的 HTTPS issuer 和 discovery endpoint;
- Legate 对外 HTTPS origin,例如
https://legate.example.com; - 身份提供商中注册的 confidential client;
- 客户端 ID 和客户端 secret;
- 可被 Legate 读取的 secret file;
- 一个新的或已完成身份迁移的 PostgreSQL 数据库;
- 同源托管的 Legate Console,或经过严格设计的管理客户端。
生产配置要求 issuer、authorization、token 和 JWKS 等 OIDC endpoint 使用 HTTPS。Legate 只接受非对称 RS、PS 或 ES ID Token 签名算法,不支持跳过 issuer、签名或 TLS 验证的危险开关。
1. 在身份提供商创建客户端¶
为 Legate 创建 confidential OIDC client,并注册精确回调地址:
建议至少允许以下 scopes:
openid 是必需 scope。使用 email 邀请或 email bootstrap 时,IdP 还必须返回经过验证的邮箱声明。
只注册实际使用的回调,不要使用通配符。Legate 的 --admin-public-url 必须与浏览器访问的 origin 一致。
2. 保存客户端 Secret¶
把 secret 放入独立普通文件,不要直接写进 Provider JSON:
install -d -m 700 /etc/legate/secrets
install -m 600 /dev/null /etc/legate/secrets/corp-oidc-client-secret
再通过秘密管理系统把真实值写入该文件。Kubernetes projected Secret 的符号链接可以使用,只要打开后的最终目标是普通文件。
Legate 启动时读取并修剪文件内容。空文件、非普通文件、无法读取或超过大小限制都会导致启动失败。Secret 不会出现在公开认证配置响应中。
3. 编写 Provider 配置¶
创建 /etc/legate/admin-oidc.json:
{
"entry": "page",
"defaultProviderId": "corp",
"providers": [
{
"id": "corp",
"label": "Company SSO",
"issuerUrl": "https://id.example.com/realms/company",
"clientId": "legate-admin",
"clientSecretFile": "/etc/legate/secrets/corp-oidc-client-secret",
"scopes": ["openid", "email", "profile"],
"enabled": true
}
]
}
根字段:
| 字段 | 说明 |
|---|---|
entry |
page 显示登录方式列表;redirect 直接跳转默认 Provider |
defaultProviderId |
默认 Provider;redirect 模式必填且必须已启用 |
providers |
1 到 32 个 Provider 配置 |
Provider 字段:
| 字段 | 说明 |
|---|---|
id |
永久身份命名空间,小写字母开头,可含小写字母、数字、_、- |
label |
Console 展示名称 |
issuerUrl |
IdP 发布的精确 issuer URL |
clientId |
OIDC client ID |
clientSecretFile |
secret 文件路径 |
scopes |
必须包含 openid |
enabled |
是否允许新登录并保留该 Provider 的会话路径 |
解析器拒绝未知字段、重复 JSON key、尾随 JSON、重复 Provider ID 和无效 URL。不要依赖拼写错误被忽略。
Provider ID 是身份边界
同一个 Provider ID 的 issuer 和 client ID 指纹不能被替换。迁移到新 issuer、租户或 client 时,请创建新的 Provider ID,并通过邀请或明确迁移流程绑定用户。
4. 配置首位平台管理员¶
新的 OIDC 数据库还没有可登录的平台管理员。推荐用精确 subject 配置一次性 bootstrap:
如果无法提前得到 subject,可以改用 verified email:
--admin-bootstrap-provider-id=corp
[email protected]
Subject 和 email 只能选择一个。第一个完全匹配的成功回调会在一个事务中:
- 创建内部用户;
- 绑定外部 identity;
- 授予平台管理员;
- 创建会话;
- 永久封存 bootstrap 标记。
封存后保留或修改这些启动参数都不会再创建第二位平台管理员。不要使用共享邮箱做 bootstrap,也不要在确认匹配人之前把服务暴露给用户。
已有可用平台管理员的数据库通常不需要 bootstrap 参数。
5. 启动 Legate¶
export LEGATE_DATABASE_DSN='postgres://legate:[email protected]:5432/legate?sslmode=require'
legate \
--listen=:8080 \
--redis-addr=redis.internal:6379 \
--redis-prefix=legate-production \
--admin-auth-mode=oidc \
--admin-public-url=https://legate.example.com \
--admin-oidc-providers-file=/etc/legate/admin-oidc.json \
--admin-bootstrap-provider-id=corp \
--admin-bootstrap-subject=exact-idp-subject
启动期间 Legate 会执行 OIDC discovery,并要求 discovery 文档中的 issuer 与配置精确相等。结构性错误、issuer 不匹配或不安全 endpoint 会阻止启动。
首次成功 discovery 会缓存经过验证的元数据。之后遇到临时网络故障时,可以使用完整缓存启动但暂停该 Provider 的新登录,并在后台有界重试。不要因为 IdP 临时故障切换到 disabled。
6. 配置 HTTPS 入口¶
OIDC 的正常部署要求浏览器通过 --admin-public-url 指定的 HTTPS origin 访问 Console 和 /api。如果 TLS 在反向代理终止:
- Central 的监听端口不能被不受信任网络直接访问;
- 代理必须覆盖
Host、X-Forwarded-Proto和X-Forwarded-For; - Central 只信任通过
--admin-trusted-proxy-cidr配置的直接代理网络; - 代理不能把客户端传入的
X-Forwarded-For原样转发。
典型的 Nginx API 片段:
location /api/ {
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://legate-central:8080;
}
对应 Central 参数应精确到实际入口网络,例如:
不要为了省事信任整个集群、VPC 或 0.0.0.0/0。Legate 使用解析后的客户端 IP 对登录、回调和恢复请求限速。
会话与 CSRF¶
OIDC 登录使用 Authorization Code Flow、PKCE、nonce、一次性 state 和浏览器绑定。登录尝试保存在 PostgreSQL,因此回调可以落到任意 Central 副本。
正常会话:
- 空闲超时 60 分钟;
- 绝对超时 12 小时;
- 浏览器只保存不透明 Cookie;
- PostgreSQL 保存会话和 CSRF 值的 SHA-256 散列;
- 退出、用户停用、身份禁用或 Provider 禁用会立即使相关会话失效。
生产 Cookie 使用 Secure、HttpOnly 或受控可读属性、SameSite=Lax 和 Path=/。修改状态的请求必须把 CSRF Cookie 值放入 X-Legate-CSRF。存在 Origin 时必须与 public URL 精确一致。
因此 OIDC Console 推荐同源部署。--admin-cors-origin 不是绕过 Cookie 和 CSRF 约束的办法。
邀请其他用户¶
OIDC 模式没有公开注册。平台管理员或目标工作空间的 admin 成员可以邀请新用户:
{
"email": "[email protected]",
"providerId": "corp",
"role": "admin"
}
邀请有效期为 7 天。只有同一 Provider 返回的相同 verified email 可以认领邀请。认领后,权限来自 Legate 已保存的工作空间成员关系,而不是 OIDC claim 中的 group 或 role。
对于已经存在的用户,先按精确 email 解析内部 userId,再用 userId 加入工作空间。不要重复邀请已经激活的用户。
验证配置¶
启动后检查公开配置:
应看到 mode: "oidc"、预期的登录方式和默认 Provider,但不应看到 client secret。
匿名访问当前用户接口应返回 401:
然后完成以下人工检查:
- 从 Console 发起登录,确认跳转到正确 IdP tenant。
- 确认回调返回同一 HTTPS origin。
- 完成首位管理员 bootstrap。
- 刷新页面,确认会话可以落到多个 Central 副本。
- 邀请一个非平台管理员并验证工作空间边界。
- 退出后确认旧会话立即失效。
恢复认证(可选)¶
恢复认证用于 IdP 登录路径全部不可用时,为一个已经存在的启用平台管理员换取 15 分钟恢复会话。它不能创建用户、不能授予平台管理员,也不能替代正常 OIDC。
生成 32 个随机字节的无填充 base64url Token:
openssl rand 32 \
| openssl base64 -A \
| tr '+/' '-_' \
| tr -d '=' \
> /etc/legate/secrets/admin-recovery-token
chmod 600 /etc/legate/secrets/admin-recovery-token
三个参数必须一起配置:
--admin-recovery-user-id=1
--admin-recovery-token-file=/etc/legate/secrets/admin-recovery-token
--admin-recovery-source-cidr=10.20.0.0/16
source CIDR 描述最终管理员客户端网络,不是入口代理网络。成功交换会撤销目标用户之前的会话。恢复 Token 应离线保管、定期演练,并限制能够读取文件和访问恢复源网络的主体。
本地 OIDC 开发¶
--admin-allow-insecure-local-oidc 允许隔离开发环境使用 HTTP,但所有 public、issuer、discovery、authorization、token 和 JWKS URL 都必须是:
localhost;*.localhost;- 回环 IP。
该开关在其他认证模式或远程 HTTP endpoint 上会被拒绝。不要把它暴露到局域网。
Docker Compose 本机部署为了快速入门显式使用 --admin-auth-mode=disabled,不包含 IdP,不能用于验证 OIDC。OIDC 环境必须另外提供 HTTPS 同源入口和符合本页约束的 Provider;不要把入门 Compose 直接暴露到局域网或共享环境。
配置变更与上线¶
当前版本不支持 OIDC Provider、bootstrap 或 recovery 配置的混合版本滚动变更。每次改变这些配置时:
- 在所有目标节点渲染完全一致的参数、JSON 和 Secret;
- 预先验证 IdP discovery、回调、Secret、恢复用户和 CIDR;
- 停止接收管理请求并停止全部旧 Central 实例;
- 确认旧进程完全退出后应用配置;
- 使用相同二进制和字节一致配置启动所有实例;
- 验证公开配置、登录、会话撤销和恢复路径。
把 Provider 设置为 enabled: false 或从配置中删除会撤销它的 OIDC 会话,但不会删除用户、身份、邀请和工作空间成员关系。重新启用不会恢复已经撤销的会话。
生产检查清单¶
- [ ] public URL 是精确 HTTPS origin。
- [ ] IdP 回调只注册
/api/auth/callback的精确地址。 - [ ] Provider ID、issuer 和 client ID 已作为长期身份边界评审。
- [ ] client secret 位于只读 Secret 文件,不在 JSON、镜像或日志中。
- [ ] 首位管理员使用精确 subject;使用 email 时已确认 verified claim。
- [ ] Central 监听端口不被入口之外的网络访问。
- [ ] trusted proxy CIDR 只包含真实直接代理。
- [ ] Console 与 API 同源,CSRF 流程未被代理破坏。
- [ ] 至少有两条经过验证的平台管理员登录路径,或已配置恢复认证。
- [ ] IdP 故障、Provider 禁用和 stop-all 配置变更已演练。