LLM 认证代理让您的组织能够为所有来自 LangSmith 的模型调用强制执行自身的认证流程,这样提供商凭据就不会暴露给最终用户,并且每个请求都可以追溯到具体的执行者。 LLM 认证代理是一个基于 Envoy 的组件,它运行在您的环境中,位于 LangSmith 与您的上游 LLM 提供商或网关(例如 OpenAI、Anthropic 或内部的 LLM 网关如 LiteLLM)之间。LangSmith 使用短期有效的 JWT(JSON Web Token)对每个请求进行签名。代理会验证 JWT,可选地注入提供商凭据或转换请求和响应体,然后将请求转发到上游。它适用于 SaaS 和 自托管 LangSmith 客户。
LLM 认证代理需要 LangSmith Enterprise 计划。更多详情,请参考 定价 或 联系我们的销售团队。
在以下情况时,您需要使用 LLM 认证代理:
  • 针对您自己的提供商网关认证 Playground 或 LLM-as-judge 评估 请求。
  • 注入特定于提供商的 API 密钥或认证头,而不将其暴露给最终用户。
  • 转换请求或响应体(例如,在 OpenAI 格式和自定义网关格式之间进行转换)。
特别是对于 OAuth2 client_credentials,模型配置上的 OAuth 客户端凭据 是一种按配置自服务的替代方案,工作区管理员无需搭建认证代理即可设置。路由在配置级别上是互斥的——启用了 OAuth 的配置不会通过认证代理。

工作原理

来自 LangSmith 的每个请求在代理中都会经历以下步骤:
  1. 验证 JWT(签名、签发者、受众)
  2. 调用您的 ext_authz 服务,该服务接收已验证的 JWT 并返回要作为请求头注入的提供商凭据
  3. 可选地调用您的 ext_proc 转换器,它可以重写请求和响应体(例如,在 OpenAI 格式和自定义网关格式之间进行转换)
  4. 将带有自定义头(静态或动态)的请求转发到上游提供商
ext_authz 服务和转换器都是客户部署的组件,它们与代理一起在您的环境中运行。根据您的用例,可以启用其中一个或两者。 架构图显示 LangSmith 向自托管认证代理签发签名的 JWT,代理验证 JWT,应用客户定义的认证,并将请求转发给上游模型提供商。

前提条件

  • LangSmith Enterprise 计划(SaaS 或自托管版本 0.13.33+)
  • 拥有 Helm 3 的 Kubernetes 集群
  • Envoy v1.37 或更高版本(Helm chart 默认使用 envoyproxy/envoy:v1.37-latest)
  • 您上游 LLM 提供商或网关的 URL(代理将请求转发到的目标地址)
认证代理目前支持 Playground、Evals、Fleet、Chat 和 Insights 功能。 Playground 和 Evals 在 v0.13.33+ 版本可用。Chat 和 Insights 在 v0.13.39+ 版本可用。

1. 配置 JWT 签名(仅限自托管 LangSmith)

对于 LangSmith SaaS,请跳过此步骤。JWT 签名已预先配置。 使用 step CLI(或您偏好的内部流程)生成 Ed25519 密钥对。Ed25519 是 LangSmith 用于签署 JWT 的签名算法。私钥用于签署每个请求;认证代理仅使用公钥来验证签名。
将 JWKS 存储到 Kubernetes Secret 中:
JWKS(JSON Web Key Set)是一种用于发布加密密钥的标准 JSON 格式。LANGSMITH_SIGNING_JWKS 包含 Ed25519 私钥,并作为 Kubernetes Secret 存储。它永远不会暴露。LangSmith 会自动提取相应的公钥并在 /.well-known/jwks.json 路径提供服务。认证代理通过获取此公钥端点来验证 JWT 签名,而无需私钥。 在您的 LangSmith values.yaml 中引用此 Secret:
LLM_AUTH_PROXY_ISSUER 设置签名 JWT 中的 iss 声明。使用 langsmith 以匹配 SaaS 默认值,或使用自定义标识符(如 langsmith:self-hosted:<short_identifier>)以区分您的安装实例。此值必须与第 4 步中认证代理 chart 里的 jwtIssuer 相匹配。

2. 为您的组织启用 LLM 认证代理

选项 A: 为特定组织启用:在 LangSmith UI 中,导航至 设置 页面,复制左上角 组织 旁边的组织 ID。对您的 LangSmith PostgreSQL 数据库执行以下命令:
选项 B: 为所有组织启用:在您的 LangSmith values.yaml 中的 commonEnv 下添加以下内容:
此设置对个人组织无效。

3. 在 LangSmith 中配置组织设置

在 LangSmith UI 中,导航至 设置 > 通用,配置以下项:
  1. JWT 受众: 代理将验证的 aud 声明值(例如,example-audience)。此值必须与第 4 步中认证代理 chart 里的 jwtAudiences 相匹配。
  2. 启用 LLM 认证代理: 为您的组织启用开关。
  3. 允许的 URL: 控制代理可以将 JWT 转发到的目标 URL。这可以防止凭据被转发到非预期的主机。选择以下三个选项之一:
    • 允许所有(默认):允许将 JWT 转发到任何上游 URL。等同于无限制。
    • 全部阻止: 阻止将 JWT 转发到所有 URL。
    • 自定义: 指定一个明确的允许 URL 模式列表。不接受空字符串和单独的 *。当 LLM 认证代理开关关闭时,此控件被禁用。
    LangSmith 中的 LLM 认证代理设置,显示启用 LLM 认证代理复选框、JWT 受众字段以及已选择“允许所有”的允许 URL 单选按钮。

4. 安装认证代理 Helm chart

添加 LangChain Helm 仓库:
创建一个 values.yaml 文件,配置上游 URL 和 JWT 验证设置。对于 JWKS 配置,有两个选项:
  • jwksUri(推荐): 指向您 LangSmith 实例的 /.well-known/jwks.json 端点。Envoy 会自动获取并缓存公钥,支持无缝的密钥轮换。
  • jwksJson(内联): 将 JWKS JSON 直接粘贴到 values.yaml 中。适用于测试或无法访问外部网络的(air-gapped)环境,此时认证代理无法访问 LangSmith 的出站网络。轮换密钥需要更新 chart。仅包含公钥组件;省略 d 字段(私钥)。
如果两者都设置,jwksUri 优先。
安装 chart:

编写 ext_authz 服务

当您需要添加、删除或编辑授权头时(例如,基于 JWT 中的身份注入提供商 API 密钥),请使用 ext_authz。您的服务接收已验证的 JWT 以及可选的请求体,并返回需要向上游注入的头信息。这使用了 Envoy 的 HTTP ext_authz 过滤器(而非 gRPC)。 在 values.yaml 中启用它:

工作原理

在转发每个请求之前,Envoy 会使用与原始请求相同的 HTTP 方法调用您的服务,地址为 <serviceUrl>/check<original_path>。您的服务在 x-langsmith-llm-auth 请求头中接收已验证的 JWT。 您的服务返回一个纯 HTTP 响应:
  • 2xx: 允许请求。任何与 allowedUpstreamHeaders 模式(默认:authorization 和 x-*)匹配的请求头都会被注入到上游请求中。要在转发前剥离 JWT,请在响应中包含 x-envoy-auth-headers-to-remove: x-langsmith-llm-auth。
  • 非 2xx: 拒绝请求。状态码以及任何与 allowedClientHeaders 模式(默认:www-authenticate 和 x-*)匹配的头信息都会返回给客户端。

部署选项

您的 ext_authz 服务可以两种方式运行:
  • 边车(Sidecar): 在与代理相同的 Pod 中运行该服务。在 values.yaml 的 authProxy.deployment.sidecars 下添加容器,并在 authProxy.deployment.volumes 下添加任何所需的卷。使用 localhost URL,例如 http://localhost:10002。
  • 独立部署: 独立部署该服务,并将 extAuthz.serviceUrl 指向它。使用集群内 DNS 名称,例如 http://my-auth-service.my-namespace.svc.cluster.local:8080,或者如果该服务有自己的入口,则使用外部 HTTPS URL。

示例部署

下面的示例是一个执行 OAuth2 客户端凭据令牌交换的最小化 Python ext_authz 服务。对于每个请求,它返回一个缓存的 Authorization 头(其中包含一个新的访问令牌),并在令牌过期前从配置的令牌端点刷新它。完整示例请参见 chart 仓库中的 e2e/oauth/。
有关 extAuthz 参数的完整列表,请参阅 Helm chart README。

编写 ext_proc 转换器

当您需要重写请求或响应体时(例如,在 OpenAI 格式和自定义网关格式之间进行转换,或向请求负载注入额外字段),请使用 ext_proc。这使用了 Envoy 的 ext_proc 过滤器。 与 ext_authz(HTTP)不同,ext_proc 使用双向 gRPC 流。Envoy 会为每个处理阶段(请求头、请求体、响应头、响应体)向您的转换器服务发送一条消息,您的服务则为每个阶段回复变异操作。您的转换器必须实现 envoy.service.ext_proc.v3.ExternalProcessor gRPC 服务。请参见 chart 仓库中的 e2e/transformer/ 获取一个示例 Go 实现。

何时使用 ext_proc 与 ext_authz

如果您只需要注入认证头(例如,API 密钥),请使用 ext_authz。如果您需要重写请求体或响应体,请使用 ext_proc。两者可以同时启用。 在 values.yaml 中启用 ext_proc:
设置 failureModeAllow: true 以便在转换器不可用时允许请求通过。默认值(false)会拒绝请求。

处理模式

通过 processingMode 控制哪些阶段发送给您的转换器。只启用您需要的阶段,因为禁用未使用的阶段可以降低延迟。
  • 对于请求体重写,请使用 BUFFERED:在发送前缓冲整个请求体,对于 JSON 重写最为简单。
  • 对于流式 LLM 响应体重写,请使用 STREAMED:在数据块到达时发送,延迟更低,但实现更复杂。
  • 使用 NONE 完全跳过某个阶段。
当修改请求体时,您的 ext_proc 服务还必须通过 HeaderMutation 更新 content-length 头以匹配新的请求体大小。Envoy 会拒绝 content-length 与修改后的请求体不匹配的响应。

请求流程

启用了 ext_proc 用于头注入和体重写的示例:

示例部署

下面的示例将一个最小化的 Go 转换器部署为 Kubernetes Deployment。它从请求头中读取 JWT,注入 Authorization 头,并将请求体从 OpenAI 格式重写为自定义格式。
对于生产环境,请预先构建容器镜像,而不是在 init 容器中编译。请参阅 Helm chart 仓库 中的 e2e/transformer/Dockerfile 获取多阶段构建示例。

附加配置

HTTP 代理

Envoy 不遵守 HTTP_PROXY、HTTPS_PROXY 或 NO_PROXY 环境变量。请显式配置 HTTP 代理:

无公共入口部署

当认证代理没有公共入口且仅可通过内部 Kubernetes 网络访问时,必须配置 LangSmith 服务以允许出站请求到私有 IP 地址。如果没有这些设置,内置的 SSRF 防护会阻止对私有 IP 的请求。 在您的 LangSmith values.yaml 中添加以下环境变量:
  • SSRF_ALLOW_K8S_INTERNAL — 所有进行 LLM 调用的服务都需要。将此添加到支持 commonEnv 的服务的 commonEnv 中,或为不支持 commonEnv 的服务添加到每个服务的 extraEnv 中。
  • SSRF_ALLOW_PRIVATE_IPS_PLAYGROUND — 仅 playground 服务需要。将其添加到 playground.deployment.extraEnv 中。
如果 commonEnv 不适用于您部署中的所有必需服务,请通过 extraEnv 在每个进行 LLM 调用的服务上单独设置 SSRF_ALLOW_K8S_INTERNAL。

其他选项

有关入口、自动伸缩、资源限制和其他配置选项,请参阅 Helm chart README。
为了生产环境的可靠性,请将 authProxy.autoscaling.hpa.minReplicas 设置为至少 3。

完整配置示例

JWT 声明参考

LangSmith 使用 Ed25519 (EdDSA) 签署 JWT。公钥在 /.well-known/jwks.json 路径提供,并由代理自动获取。认证代理使用这些公钥验证签名。 JWT 通过 x-langsmith-llm-auth 请求头传递给您的 ext_authz 或转换器服务。

常见问题

支持。通过 values.yaml 中的 httpProxy 部分配置 HTTP 代理。详情请参阅 HTTP 代理。
支持,通过 customCa 配置自定义 CA 证书,通过 mtls 配置双向 TLS。
不能。认证代理只有一个 upstream 字段。
能。多个组织可以通过其在 LangSmith 中的模型配置指向同一个认证代理实例。
可以,但仅在自托管环境下,我们通常建议将认证代理放在专用入口后面,以便通信使用 HTTPS。要允许 HTTP,请在您的 LangSmith values.yaml 中的 commonEnv 和 playground.deployment.extraEnv 下添加 LLM_AUTH_PROXY_ACCEPT_HTTP。 要为 Chat 和 Insights 启用到认证代理的 HTTP 流量,请在相应的 extraEnv 部分设置此环境变量:config.polly.agent.extraEnv(用于 Chat,以前称为 Polly)和 config.insights.agent.extraEnv。
能。当认证代理仅可通过内部 Kubernetes 网络(无公共入口)访问时,请为所有进行 LLM 调用的服务添加 SSRF_ALLOW_K8S_INTERNAL,并为 playground 服务同时添加 SSRF_ALLOW_K8S_INTERNAL 和 SSRF_ALLOW_PRIVATE_IPS_PLAYGROUND。配置详情请参阅 无公共入口部署。
当认证需要超越 OAuth2 client_credentials 的自定义逻辑时,使用 LLM 认证代理。例如,将 LangSmith JWT 交换为特定于提供商的令牌、注入 GCP 或 AWS 身份,或重写请求体和响应体。当每个工作区或团队需要自助控制其针对自定义网关的 OAuth2 client_credentials 时,使用 模型配置上的 OAuth 客户端凭据。两者可以在同一组织内共存;路由是按配置进行的。

Helm chart 参考

有关可配置值的完整列表,请参阅 Helm chart README。