[Bug]: Azure AI Foundry Anthropic endpoints 400 when azure_ad_token leaks into request body

当 LiteLLM 代理使用 azure_ad_token (或 Workload Identity Federation)连接 Azure AI Foundry Anthropic 端点时,认证字段会随 extra_body 被合并进请求 JSON,端点按 Anthropic schema 严格校

快速结论:当 LiteLLM 代理使用 azure_ad_token(或 Workload Identity Federation)连接 Azure AI Foundry Anthropic 端点时,认证字段会随 extra_body 被合并进请求 JSON,端点按 Anthropic schema 严格校验后拒绝未知字段,返回 400(azure_ad_token: Extra inputs are not permitted)。优先排查 litellm_params 中的认证字段是否进入了发往上游的请求体。

适用环境:LiteLLM v1.107.0 及 main(Issue 报告版本);评论中在 LiteLLM 1.109.0 衍生部署上复现。涉及 Azure AI Foundry Anthropic Claude 模型、Azure AI Foundry 上的 Nemotron Ultra、MiniMax M3、Mistral Medium 3.5,认证方式为 Microsoft Entra ID 的 azure_ad_token(如 oidc/google/... Workload Identity Federation)。操作系统、Python、CUDA、显卡版本在 Issue 中未说明。

最快修复方案:升级到包含 PR #49769 的 LiteLLM 版本(该 PR 已合并,覆盖 Azure AI chat 分发路径;Anthropic 转换路径由 PR #46706 处理)。若暂时无法升级,可优先尝试在模型配置中加入 additional_drop_params: [azure_ad_token, client_id, tenant_id],评论中验证该配置下 chat 与流式请求可通过。

注意事项:additional_drop_params 属于临时规避,Issue 提到它会把相应字段从请求体中去除但保留 bearer 头;评论中的后续请求捕获显示,实际泄漏到 JSON 的只有 azure_ad_token,client_id 与 tenant_id 已被过滤。因此在你的版本上,必需丢弃的字段组合可能不同,需以实际抓包为准。修复本身未覆盖所有 Azure AI 路径(#46706 只处理 Anthropic 请求体,#49769 处理 chat 分发路径),使用模型路由器时仍需确认版本是否已包含相应修复。

问题场景

用户在 LiteLLM 代理中配置 Azure AI Foundry 托管的 Claude 模型(例如 azure_ai/claude-mythos-5-1),并使用 Microsoft Entra ID 认证(azure_ad_token,如 Workload Identity Federation 或 Entra ID token)。通过代理的 /v1/chat/completions 发起请求时,Azure AI Foundry 的 Anthropic 端点 https://<resource>.services.ai.azure.com/anthropic/v1/messages 返回 HTTP 400,并提示未尝试 fallback。评论显示同一问题也出现在 Azure AI Foundry 上的 Nemotron Ultra、MiniMax M3、Mistral Medium 3.5(非 Claude 的 Azure AI chat 场景)。

报错原文

{
  "error": {
    "message": "litellm.BadRequestError: Azure_aiException - {\"type\":\"error\",\"error\":{\"type\":\"invalid_request_error\",\"message\":\"azure_ad_token: Extra inputs are not permitted\"},\"request_id\":\"req_011Cg4MvX6AR5jvdhxU3CEZq\"}\n\nLiteLLM: model group 'claude-mythos-5-1' failed with the error above. No fallback was attempted.",
    "type": "invalid_request_error",
    "param": null,
    "code": "400"
  }
}

{"type":"error","error":{"type":"invalid_request_error","message":"azure_ad_token: Extra inputs are not permitted"}}

原因分析

根因是认证凭据泄漏进了请求体:

  • 在代理请求处理过程中,来自 litellm_params 的认证字段(azure_ad_token、client_id、tenant_id)进入了 extra_body / optional_params。
  • 在 litellm/llms/azure_ai/anthropic/transformation.py 中,_promote_extra_body_to_optional_params(optional_params) 会把 extra_body 中的条目提升到 optional_params。
  • AzureAnthropicConfig.transform_request 调用父类 AnthropicConfig.transform_request 时,通过 **optional_params 把这些参数展开进最终请求体 data。
  • 现有代码只移除了 extra_body、max_retries、stream_options,没有剥离 azure_ad_token、azure_ad_token_provider、client_id、tenant_id 等认证字段。
  • Azure AI Foundry 端点严格按 Anthropic schema 校验 JSON 字段,遇到无法识别的键即返回 <field>: Extra inputs are not permitted。

评论补充:同样的 extra_body 合并也会把 azure_ad_token 复制进非 Claude 的 Azure AI chat 和模型路由器的请求体(AzureAIStudioConfig.transform_request 将其复制到 optional_params,父类再展开)。使用无凭据参数的复现中,get_optional_params 返回的 extra_body 键集合里含有且仅含有 azure_ad_token。另需注意版本差异:在 1.109.0 衍生部署的抓包中,client_id 与 tenant_id 已被过滤,只有 azure_ad_token 泄漏,因此你的版本上实际泄漏字段可能不同,可能原因需以抓包确认。

环境排查

  • 确认 LiteLLM 版本:Issue 报告为 v1.107.0 及 main;评论复现于 1.109.0 衍生部署;修复位于 #49769(chat 路径)与 #46706(Anthropic 路径),确认当前版本是否已包含。
  • 确认模型路由类型:azure_ai/ 的 Anthropic Claude 模型(走 Anthropic 转换路径)还是其他 Azure AI chat 模型(走 AzureAIStudioConfig / AzureModelRouterConfig 路径),两条路径修复来源不同。
  • 确认 litellm_params 中是否直接配置了 azure_ad_token、azure_ad_token_provider、client_id、tenant_id、azure_scope。
  • 确认发往上游的实际请求体:评论通过真实 HTTP 客户端加 mock transport 抓包定位,建议同样检查 JSON 中是否残留认证字段,并确认 bearer 头是否仍存在。
  • Issue 未提供 Python、CUDA、PyTorch、显卡相关信息,无需作为排查项。

解决步骤

  1. 记录当前配置,重点看 litellm_params:model: azure_ai/claude-...、api_base、azure_ad_token、client_id、tenant_id。
  2. 使用最小请求复现:向代理的 /v1/chat/completions 发送一条简单消息(请求示例见 Issue 正文),确认返回 400 且报错含 azure_ad_token: Extra inputs are not permitted。
  3. 抓取实际发往上游的请求体(或使用 mock transport),确认 JSON 中是否出现 azure_ad_token 等认证字段,同时确认 Authorization bearer 头存在。
  4. 升级 LiteLLM 到包含 #49769 的版本(Anthropic 路径还需确认包含 #46706)。该 PR 已由维护者确认合并,是首选修复。
  5. 若暂时无法升级,可优先尝试在对应模型配置中加入 additional_drop_params: [azure_ad_token, client_id, tenant_id]。评论中该配置下 chat 与流式请求均通过;若你的抓包显示只泄漏 azure_ad_token,也可只丢弃该字段。
  6. 使用模型路由器或非 Claude Azure AI chat 模型时,确认所用版本是否已包含 #49769,否则 extra_body 合并问题可能仍在该路径出现。

验证方法

重复同一最小请求,代理应返回 200 OK,且上游响应中不再出现 Extra inputs are not permitted。同时抓取上游请求体,确认 azure_ad_token 等认证字段已不在 JSON 中,Authorization bearer 头仍正常携带;流式 stream: true 请求也应一并验证。

参考来源

BerriAI/litellm #46701(含 PR #46706 与 PR #49769)

GamsGo AI

AI 工具推荐

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

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

了解 GamsGo AI

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

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 32287

发表回复

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