Skip to main content
沙盒功能目前处于私密预览阶段。随着我们的迭代,API 和功能可能会发生变化。注册等待列表以获取访问权限。
认证代理允许沙箱代码调用外部 API(OpenAI、Anthropic、GitHub 等),而无需硬编码凭据。当在沙箱上配置后,代理 sidecar 会使用你的工作区密钥,自动将认证头注入到匹配的出站请求中。
在创建引用这些密钥的沙箱之前,你必须在 LangSmith 工作区 设置中配置你的密钥(例如 OPENAI_API_KEY)。

配置认证代理规则

在创建沙箱时添加 proxy_config。每条规则指定:
字段描述
match_hosts要拦截的主机(支持类似 *.github.com 的通配符)
match_paths要匹配的路径(空值 = 所有路径)
headers要注入的头部,每个头部包含 nametypevalue
no_proxy完全绕过代理的主机(例如 localhost

头部类型

每个头部都有一个 type,控制其值的存储和显示方式:
类型描述
workspace_secret使用 {KEY} 语法引用工作区密钥。在推送时解析。
plaintext值按原样存储和返回。用于非敏感头部。
opaque仅写入。值在静态存储时加密,且永远不会通过 API 返回。

单个 API 示例

创建一个沙箱,自动将 OpenAI API 密钥注入到出站请求中:
curl -X POST "$LANGSMITH_ENDPOINT/api/v2/sandboxes/boxes" \
  -H "x-api-key: $LANGSMITH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "snapshot_id": "<snapshot-uuid>",
    "name": "openai-sandbox",
    "wait_for_ready": true,
    "proxy_config": {
      "rules": [
        {
          "name": "openai-api",
          "match_hosts": ["api.openai.com"],
          "headers": [
            {
              "name": "Authorization",
              "type": "workspace_secret",
              "value": "Bearer {OPENAI_API_KEY}"
            }
          ]
        }
      ]
    }
  }'
沙箱现在可以调用 OpenAI,无需设置 API 密钥——代理会自动注入它。

多个 API 示例

添加多条规则以同时向多个服务进行身份验证:
curl -X POST "$LANGSMITH_ENDPOINT/api/v2/sandboxes/boxes" \
  -H "x-api-key: $LANGSMITH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "snapshot_id": "<snapshot-uuid>",
    "name": "multi-api-sandbox",
    "wait_for_ready": true,
    "proxy_config": {
      "rules": [
        {
          "name": "openai-api",
          "match_hosts": ["api.openai.com"],
          "headers": [
            {
              "name": "Authorization",
              "type": "workspace_secret",
              "value": "Bearer {OPENAI_API_KEY}"
            }
          ]
        },
        {
          "name": "anthropic-api",
          "match_hosts": ["api.anthropic.com"],
          "headers": [
            {
              "name": "x-api-key",
              "type": "workspace_secret",
              "value": "{ANTHROPIC_API_KEY}"
            },
            {
              "name": "anthropic-version",
              "type": "plaintext",
              "value": "2023-06-01"
            }
          ]
        },
        {
          "name": "github-api",
          "match_hosts": ["api.github.com"],
          "match_paths": ["/repos/*", "/user"],
          "headers": [
            {
              "name": "Authorization",
              "type": "workspace_secret",
              "value": "Bearer {GITHUB_TOKEN}"
            }
          ]
        }
      ],
      "no_proxy": ["localhost", "127.0.0.1"]
    }
  }'

通过 SDK 配置

from langsmith.sandbox import SandboxClient

client = SandboxClient()

client.create_sandbox(
    snapshot_id=SNAPSHOT_ID,
    name="openai-sandbox",
    proxy_config={
        "rules": [
            {
                "name": "openai-api",
                "match_hosts": ["api.openai.com"],
                "headers": [
                    {
                        "name": "Authorization",
                        "type": "workspace_secret",
                        "value": "Bearer {OPENAI_API_KEY}",
                    }
                ],
            }
        ]
    },
)

使用回调的动态凭据

静态规则在沙箱创建时从你的工作区密钥中提取凭据。对于需要按请求解析的凭据——短期 OAuth 令牌、按用户范围限定的令牌、由你自己的认证服务颁发的令牌——请改用回调。代理会向你提供的 URL 发送 POST 请求,你的端点返回要注入的头部,代理会缓存结果。 回调与规则一起在 proxy_config 下配置:
字段描述
match_hosts要拦截的主机(语法与规则相同;支持类似 *.github.com 的通配符)。
url你的回调端点。必须是代理可访问的 http://https:// URL。
request_headers附加到代理 → 回调请求的头部,例如你的端点用于验证请求的 HMAC 或共享密钥。仅允许 plaintextopaque 类型(不允许 workspace_secret)。
ttl_seconds解析后的头部在重新调用回调前缓存的时间。必须在 60 到 3600 之间。
静态规则优先。 如果 rules 中的任何规则匹配主机,则跳过该主机的回调。在规则内,首次匹配优先;如果多个回调匹配,同样适用首次匹配优先。

回调契约

当代理需要为匹配的主机解析凭据且缓存未命中时,会发出以下请求:
POST <callback.url>
Content-Type: application/json
<request_headers from your config, attached verbatim>

{"host": "api.example.com", "port": 443}
你的端点必须以 2xx 状态码和 JSON 主体响应:
{
  "headers": {
    "Authorization": "Bearer <token>",
    "X-Org-Id": "..."
  }
}
代理将响应中的每个头部注入到沙箱的出站请求中,并将响应缓存 ttl_seconds。任何非 2xx 响应、传输错误或格式错误的 JSON 都会导致失败关闭:沙箱的请求将被拒绝,并返回 502 callback resolution failed(不注入头部,不缓存响应)。

示例

当你的 OAuth 令牌由你自己的服务按需颁发时,使用回调:
curl -X POST "$LANGSMITH_ENDPOINT/api/v2/sandboxes/boxes" \
  -H "x-api-key: $LANGSMITH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "snapshot_id": "<snapshot-uuid>",
    "name": "callback-sandbox",
    "wait_for_ready": true,
    "proxy_config": {
      "callbacks": [
        {
          "match_hosts": ["api.github.com", "*.githubusercontent.com"],
          "url": "https://auth.your-app.example.com/sandbox-credentials",
          "request_headers": [
            {
              "name": "X-Integrator-Secret",
              "type": "opaque",
              "value": "<shared-secret-your-endpoint-verifies>"
            }
          ],
          "ttl_seconds": 300
        }
      ]
    }
  }'

通过 SDK 配置

from langsmith.sandbox import SandboxClient

client = SandboxClient()

client.create_sandbox(
    snapshot_id=SNAPSHOT_ID,
    name="callback-sandbox",
    proxy_config={
        "callbacks": [
            {
                "match_hosts": ["api.github.com", "*.githubusercontent.com"],
                "url": "https://auth.your-app.example.com/sandbox-credentials",
                "request_headers": [
                    {
                        "name": "X-Integrator-Secret",
                        "type": "opaque",
                        "value": "<shared-secret-your-endpoint-verifies>",
                    }
                ],
                "ttl_seconds": 300,
            }
        ]
    },
)