[Bug]: Team ID not verified on JWT

该报错通常出现在 LiteLLM Proxy 启用 JWT 认证并配置了 virtual_key_claim_field 的场景下,当同一用户从多个应用(如不同 OIDC 客户端)登录时,第二个应用不会重新解析 team_id_jwt_field 。优先排查 virtual_key_claim_fi

快速结论:该报错通常出现在 LiteLLM Proxy 启用 JWT 认证并配置了 virtual_key_claim_field 的场景下,当同一用户从多个应用(如不同 OIDC 客户端)登录时,第二个应用不会重新解析 team_id_jwt_field。优先排查 virtual_key_claim_field 的取值是否被两个应用共享(例如都用 preferred_username)。

适用环境:LiteLLM v1.103.1;Helm chart 部署,组件化模式;启用 enable_jwt_auth: true 与 litellm_jwtauth 配置。

最快修复方案:将 virtual_key_claim_field 指向每个应用各不相同的 claim(例如 OIDC 客户端 id 或 azp),或为每个应用配置独立的 issuer 条目;这样两个应用会解析到不同的 virtual key。

注意事项:该方案下 mapping 是按应用(per app)共享,而不是按用户+应用(per user and app)区分,同一应用内所有用户会共用同一映射。Issue 中维护者只验证了 mapping lookup 逻辑,未端到端测试 auto_register。按用户+应用独立建 key,或在映射时额外校验 team claim 与 key 所属 team,属于尚未设计的新功能,非当前已有能力。

问题场景

用户使用 LiteLLM Proxy,通过 JWT → virtual key 映射来按应用限制模型访问权限。配置了多个 team,不同 team 可访问不同模型;JWT issuer 根据请求来源(app 1 / app 2)在 JWT 中写入不同的 user-role claim,并配置 team_id_jwt_field: user-role。用户首次从 app 1 连接时能被正确映射到对应 team,但从 app 2 连接时 team 映射被忽略,仍继续复用 app 1 首次创建的 virtual key,导致 app 2 的 team claim 从未生效。

报错原文

[Bug]: Team ID not verified on JWT

原因分析

维护者复查当前 main 分支后判断,问题来自 key mapping 的匹配方式,而不是 team claim 本身失效:

  • 当 virtual_key_claim_field: preferred_username 时,查找是以 issuer、该字段名及其值为 key 进行的。
  • 两个应用发送的用户名相同,因此第二次登录会命中第一次登录创建的 key 并复用它。
  • 一旦 mapping 匹配成功,正常的 JWT 路径会被跳过,而 team_id_jwt_field 只在正常 JWT 路径中被读取,所以来自 app 2 的 team claim 从未被读取。

维护者在仅 mock 数据库边界、使用真实 mapping 查找的情况下复现:两个 JWT 具有相同的 preferred_username、不同的 user-role,会解析到同一个 key 和 team;若把 virtual_key_claim_field 改为 user-role,则解析为两个不同的 key 和 team。

环境排查

  • 确认 LiteLLM 版本(Issue 中为 v1.103.1)。
  • 确认部署方式(Issue 中为 Helm chart,componentized)。
  • 检查 litellm_jwtauth 下 virtual_key_claim_field 的取值,是否为所有应用共享(如 preferred_username)。
  • 检查 team_id_jwt_field / team_ids_jwt_field 指向的 claim,以及各应用 JWT 中该 claim 的值。
  • 检查 unregistered_jwt_client_behavior(Issue 中为 auto_register)与 user_id_upsert 配置。
  • 在 LiteLLM 管理界面确认该用户对应的 key 所属 team 是否为 app 1(验证 key 是否被复用)。

解决步骤

  1. 确认现象:用户从 app 1 首次登录后,在 admin UI 检查该用户对应的 key 是否只显示 team app1。维护者建议先做这一项自查,以确认 key 复用的判断成立。
  2. 将 virtual_key_claim_field 从 preferred_username 改为每个应用各不相同的 claim,例如 OIDC 客户端 id 或 azp(前提是两个应用是不同的客户端)。这样两个应用会解析到不同的 key 和 team。
  3. 或者为每个应用配置独立的 issuer 条目,使不同应用走不同的 JWT 路径。
  4. 如果已经使用 team_ids_jwt_field(claim 值包含多个 team,如 ["app1","app2"])并通过 x-litellm-team-id 选择 team,需要注意:auto_register 首次请求只按当次解析出的单个 team 创建 mapping 与 virtual key。发送 x-litellm-team-id: app1 时 key 只带 app1,team_ids_jwt_field 允许 header 从 claim 中挑选 team,但不会在创建时把用户加入 claim 中的每一个 team。
  5. 若需要按用户+应用独立建 key,或在映射时校验 team claim 与 key 所属 team,这属于新功能,需要向维护者提交 feature request(Issue 中用户表示会自行提交)。

验证方法

在修改 virtual_key_claim_field(或 issuer 配置)后,分别用 app 1 与 app 2 的 JWT 登录,观察是否解析到两个不同的 virtual key,并检查各自对应的 team 是否为 app 1 与 app 2。若两个应用仍命中同一 key,则说明用于区分的 claim 取值仍相同。Issue 中维护者仅验证了 mapping lookup 逻辑,未端到端跑通 auto_register,因此涉及自动注册的完整链路需要自行确认。

参考来源

BerriAI/litellm #44182

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 27740

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注