用企业身份调用模型
业务系统携带企业身份源签发的用户令牌直接调用模型,按人员与部门计量,部门额度照常生效
用企业身份调用模型
业务系统(例如行内的办公、客服或审批系统)可以不申请 API 密钥,而是直接携带企业身份源(OIDC)为当前用户签发的令牌调用模型。网关在本地完成令牌校验与授权,每一次调用都记到具体的人员和部门名下,部门额度与人员额度照常生效。
| 对比项 | API 密钥 | 企业身份令牌 |
|---|---|---|
| 凭据由谁签发 | 管理员在「模型服务 → API 密钥管理」中创建 | 企业身份源为当前登录用户签发 |
| 计量归属 | 归属到密钥 | 归属到具体人员、部门与工作空间 |
| 部门额度、人员额度 | 不适用 | 生效 |
| 凭据轮换 | 管理员手动轮换 | 令牌到期后由业务系统向身份源重新获取 |
| 可调用的模型 | 密钥绑定的模型服务 | 该用户在所选工作空间中可用的模型服务 |
1. 工作方式
- 业务系统从企业身份源为当前用户取得 JWT(ID Token,或 JWT 格式的 Access Token)。令牌的受众(
aud)是业务系统自己的客户端标识。 - 业务系统直接调用网关,在
Authorization头中携带该令牌。调用地址、请求体与使用 API 密钥时完全相同。 - 网关用本地保存的身份源签名公钥验证令牌,按令牌中的
sub找到对应的平台用户,再判断该用户能否在本次调用归属的工作空间中使用所请求的模型。 - 令牌到期后,由业务系统向身份源重新获取;整个过程不需要访问管理控制台的任何接口。
网关验证令牌所需的一切(签发方、受众白名单、人员与工作空间关系、签名公钥)都保存在网关节点本地。签名公钥由网关直接从身份源获取并保存在本地,因此即使控制面长时间不可用,已有用户的调用也不受影响,见第 6 节。
2. 前置条件
由单位管理员在管理控制台完成以下配置(详细步骤见「身份源与登录安全」专题):
- 接入 OIDC 身份源:在「单点登录」页选择「IAM」,类型选「OpenID Connect」,填写身份源地址(Issuer)、客户端标识与客户端密钥,保存并完成测试登录。
- 开启业务系统调用:在同一页面的「业务系统调用」区块打开「允许业务系统用身份源令牌调用模型」,并在「业务系统客户端标识」中填写业务系统在身份源中的客户端标识(至少一项)。业务系统取得的用户令牌,其受众必须是这里登记的标识之一。
- 人员已存在于平台中:调用人必须是本单位的启用用户,并且已与该身份源建立关联——用户通过该身份源单点登录过一次,或由通讯录同步推送时已完成关联。被停用的用户无法调用。
- 工作空间与模型可用:调用人至少属于一个工作空间,所请求的模型服务已分发给该用户或该工作空间。
保存时,平台会立即从身份源读取一次签名公钥并校验身份源地址是否可访问;读取失败时保存不会成功,页面显示具体原因。
注意事项:
- 只有单位的 OIDC 身份源可以开启业务系统调用;OAuth2(通用)身份源和平台级身份源不提供此项。
- 同一个签发方只能被一个单位用于业务系统调用。已被其他单位使用时,保存会失败并提示「该身份源已被其他单位用于业务系统调用」。
- 网关只接受以下非对称签名算法签发的令牌:RS256、RS384、RS512、PS256、ES256、ES384、EdDSA。使用 HS256 等对称算法或未签名的令牌会被拒绝。
3. 调用地址
保存身份源配置后,页面会显示「业务系统调用地址」,即本平台的公开访问地址。模型调用接口位于该地址下的 /api/v1/agent-gateway/ 路径,与使用 API 密钥时相同:
| 协议 | 接口 |
|---|---|
| OpenAI 兼容 | POST /api/v1/agent-gateway/openai/v1/chat/completions、POST /api/v1/agent-gateway/openai/v1/responses、POST /api/v1/agent-gateway/openai/v1/embeddings |
| Anthropic 兼容 | POST /api/v1/agent-gateway/anthropic/v1/messages |
| Gemini 兼容 | POST /api/v1/agent-gateway/gemini/v1beta/models/模型名:generateContent |
| 模型列表 | GET /api/v1/agent-gateway/openai/v1/models(另有 Anthropic、Gemini 对应的列表接口) |
令牌可以按各协议的习惯放在 Authorization: Bearer、x-api-key 或 x-goog-api-key 中,网关按令牌的格式自动识别为企业身份令牌。
4. 请求示例
curl https://zenova.example.com/api/v1/agent-gateway/openai/v1/chat/completions \
-H "Authorization: Bearer $IDP_ID_TOKEN" \
-H "X-Zenova-Workspace: 4f1c2b7e-9a3d-4c55-8e0f-2a6b1d9c7e31" \
-H "Content-Type: application/json" \
-d '{
"model": "your-gateway-model",
"messages": [{"role": "user", "content": "请总结这份报销单的要点。"}]
}'Authorization:身份源为当前用户签发的令牌。X-Zenova-Workspace:本次调用归属的工作空间 ID(UUID)。model:可用的模型名称,可先调用模型列表接口查看当前用户在该工作空间中可用的模型。
4.1 指定工作空间
每一次企业身份调用都必须归属到一个具体的工作空间:
| 情况 | 结果 |
|---|---|
带 X-Zenova-Workspace,且用户是该工作空间成员 | 按该工作空间调用 |
带 X-Zenova-Workspace,但用户不是该工作空间成员 | 403,workspace_not_member |
| 不带该请求头,用户恰好属于一个工作空间 | 自动使用该工作空间 |
| 不带该请求头,用户属于多个工作空间或不属于任何工作空间 | 400,IDP_WORKSPACE_REQUIRED |
租户管理员使用企业身份令牌调用时同样需要指定工作空间。建议业务系统始终携带该请求头。
4.2 令牌要求
| 声明 | 要求 |
|---|---|
iss | 与身份源配置中的 Issuer 完全一致 |
aud | 至少包含一个已登记的业务系统客户端标识;包含多个受众时,azp 也必须是已登记的标识 |
exp | 必须存在且未过期 |
nbf、iat | 不晚于当前时间(允许 60 秒时钟偏差) |
sub | 与该用户在此身份源中的主体标识一致 |
头部 kid | 能在身份源公布的签名公钥中找到 |
身份源轮换签名公钥后,网关遇到新的 kid 时会直接向身份源获取最新公钥(每个节点每 60 秒最多一次)。
5. 计量、额度与调用记录
- 调用记录中的调用方显示为「业务系统(身份源令牌)」,并带有调用人与所属部门。
- 用量按调用人、部门、职能组与工作空间归集,可在用量与费用页面按部门查看。
- 部门额度、职能组额度与人员额度与该用户在平台内直接使用时一样生效;超出额度时按额度设置拒绝调用。
- 路由规则、护栏与流量保护对企业身份调用照常生效。
6. 控制面不可用时的行为
| 场景 | 行为 |
|---|---|
| 控制面停机(任意时长),已有用户调用 | 正常调用 |
| 控制面停机期间网关节点重启 | 正常调用:节点从本地保存的配置与签名公钥启动 |
| 控制面停机期间身份源轮换签名公钥 | 正常调用:网关直接从身份源获取新公钥 |
| 控制面停机期间新入职的用户 | 无法调用,控制面恢复、节点配置更新后可用 |
| 控制面停机期间被停用或离职的用户 | 在节点配置更新前仍可调用,与 API 密钥吊销的生效方式相同 |
| 身份源停机 | 已签发且未过期的令牌照常可用;业务系统无法取得新令牌 |
7. 错误排查
错误按请求所用协议(OpenAI、Anthropic、Gemini)的错误格式返回,错误码位于错误对象的 code 字段。
| 状态码 | 错误码 | 含义 | 处理方法 |
|---|---|---|---|
| 401 | IDP_TOKEN_INVALID | 令牌未通过校验:签名不正确、签发方未开启业务系统调用、受众不在白名单中、令牌已过期、用户不存在或已停用 | 依次确认:身份源配置已开启业务系统调用;令牌 aud 为已登记的客户端标识;令牌未过期;调用人已通过该身份源登录过一次且账号处于启用状态。出于安全考虑,响应不区分具体原因 |
| 401 | IDP_TOKEN_ALGORITHM_REJECTED | 令牌使用了不接受的签名算法(对称算法或未签名) | 在身份源中改用 RS256、ES256 等上文列出的非对称算法签发令牌 |
| 400 | IDP_WORKSPACE_REQUIRED | 用户属于多个工作空间或不属于任何工作空间,且未指定工作空间 | 在请求头 X-Zenova-Workspace 中填写工作空间 ID;用户不属于任何工作空间时,请管理员将其加入工作空间 |
| 400 | invalid_request_error | X-Zenova-Workspace 的值不是合法的工作空间 ID | 填写工作空间的 UUID |
| 403 | workspace_not_member | 用户不是所指定工作空间的成员 | 更换工作空间,或请管理员添加成员 |
| 404 | model_not_found | 模型不存在,或该用户在此工作空间中不可用 | 调用模型列表接口查看可用模型;请管理员将模型服务分发给该用户或工作空间 |
| 403 / 429 | 额度或限流相关错误码 | 部门、人员额度用尽,或命中流量保护 | 查看调用记录中的拒绝来源,按额度与路由规则处理 |
管理员可以在调用记录中按调用人筛选企业身份调用,确认调用方、模型、状态码与耗时。