gateway.yaml。该文件定义网关所做的一切:它在哪里监听、开发者如何登录、推理去往何处,以及应用哪些策略和遥测。本页是该文件中每个选项的参考。
要编写你的第一个配置,请从快速入门开始,它构建一个最小的工作配置并运行它。一旦你有了满意的配置,部署指南涵盖了在 Kubernetes、Cloud Run 或你自己的平台上容器化和托管它。
网关在启动时使用 claude gateway --config /path/to/gateway.yaml 读取该文件一次。每个选项都在启动时根据模式进行验证,因此格式错误的配置在启动时失败并显示字段级错误,而不是在首次使用时失败。
本页末尾的完整示例演示了每个部分。
文件结构
五个部分是必需的。其他所有部分都是可选的,省略的部分采用其默认值。未知的键会导致启动失败,因此拼写错误会显示为命名错误,而不是被静默忽略的设置。 必需部分:listen:绑定地址、公共 URL、TLS 终止oidc:您的身份提供商 (IdP),包括颁发者、客户端、声明映射以及谁可以登录session:网关铸造的持有者令牌,包括密钥和生命周期store:PostgreSQL,用于设备授权和速率限制计数器upstreams:推理的去向,无论是 Anthropic、Amazon Bedrock、Claude Platform on AWS、Google Cloud 的 Agent Platform 还是 Microsoft Foundry
login_notice:开发人员登录时看到的通知admin:Admin API 身份验证和支出限制的保留enforcement:支出限制故障开放或故障关闭行为pricing:合同费率,以及适用于支出计量器和开发人员所见成本数字的乘数models和auto_include_builtin_models:管理员策划的模型列表和每个上游 IDmanaged:按 IdP 组的托管设置策略telemetry:OTLP 转发到您的可观测性堆栈access_control、limits、timeouts、rate_limits:IP 允许/拒绝、请求大小上限、上游首字节时间和每 IP 登录限制load_test_mode:在不调用模型提供商的情况下对网关进行负载测试
密钥扩展
不要直接在gateway.yaml 中写入密钥,如 client_secret、jwt_secret 或 postgres_url。使用下面的一种形式引用它们,网关在启动时从环境变量或文件解析该值:
必需的部分
listen
listen 块控制网关的服务位置:绑定地址和端口、外部可见的源以及可选的 TLS 终止。
仅当某个前端传递的最后一个
X-Forwarded-For 条目不是由任何开发者写入的时,才将其列入 trusted_proxies。不要列出开发者连接时使用的任何地址或地址范围。为收到的每个连接追加其地址的前端符合条件。按开发者发送的原样传递该标头的前端则不符合条件。
以 ipv4:port 或 [ipv6]:port 形式写入的 X-Forwarded-For 条目(某些负载均衡器会这样写)在读取时会去掉端口。附加了端口但没有方括号的 IPv6 地址可能被读取为另一个地址,或根本无法读取。请在任何写入该形式的代理上关闭端口选项。
oidc
oidc 块将网关连接到您的身份提供商,并决定谁可以登录。它命名发行者和 OAuth 客户端,映射携带电子邮件和组的声明,并按电子邮件域或组限制登录。
OpenID Connect (OIDC) 是网关与您的身份提供商一起使用的 SSO 协议;有关在 IdP 端注册的内容,请参阅身份提供商设置。
证书客户端身份验证
如果您的身份提供商使用证书而不是客户端密钥对 OAuth 客户端进行身份验证(如 Microsoft Entra 使用证书凭据),请设置token_endpoint_auth_method: private_key_jwt。需要网关服务器上的 Claude Code v2.1.284 或更高版本。
使用此配置时,网关不发送任何密钥。当开发人员登录时以及网关每次刷新其会话时,网关使用由证书私钥签名的短期 JWT 向 IdP 的令牌端点进行身份验证。该 JWT 使用 RS256 签名,并通过 x5t 和 x5t#S256 指纹标头而不是 kid 来标识证书。您的 IdP 必须能够按指纹找到已注册的证书。
1
创建密钥和证书
创建一个至少 2048 位的未加密 RSA 私钥(PKCS#8 或 PKCS#1 PEM 格式),并为其创建证书。对于任何不满足这些条件的密钥,网关都会拒绝启动。以下 它会将
openssl 命令会创建这样的密钥以及有效期为一年的自签名证书:idp-client.key 和 idp-client.crt 写入当前目录。将这两个文件复制或挂载到网关可以读取的位置。第 3 步中的示例使用 /etc/gateway/。2
将证书上传到 IdP
将证书(而不是私钥)上传到 IdP 上网关的应用注册。
3
将密钥和证书添加到 gateway.yaml
在 这两个值都是 PEM 内容,而不是文件路径,因此请像示例那样使用
client_assertion 块中向网关提供私钥和证书。省略 client_secret,因为当它与 private_key_jwt 一起设置时,网关会拒绝启动。以下 oidc 块使用证书向 Microsoft Entra 租户对网关进行身份验证:${file:/path} 加载挂载的文件。除非 certificate_pem 是单个 PEM 证书(不含证书链的其余部分)且其公钥与 private_key_pem 匹配,否则网关会拒绝启动。4
重启网关并检查启动日志
重启网关,并在启动日志中找到以下行:将该 SHA-1 指纹与 IdP 为您上传的证书显示的指纹进行比较。如果证书已过期或尚未生效,网关仍会启动,但会记录一条警告,说明在您替换证书之前登录和刷新都将失败。要确认 IdP 接受该证书,请让一位开发人员通过网关登录。
轮换客户端证书
网关在启动时读取一次密钥和证书,因此更改后的文件仅在重启后生效。请按以下顺序轮换,以确保任何令牌请求都不会出示 IdP 中不存在的证书:- 将新证书与旧证书一起上传到 IdP。
- 替换
gateway.yaml加载的密钥和证书文件,然后重启网关。如果您运行多个副本,可以使用滚动重启,因为在您删除旧证书之前,IdP 同时拥有这两个证书。 - 在每个副本都重启之后,从 IdP 中删除旧证书。
通过前向代理的 IdP 请求
推理上游在每个版本上都遵守HTTPS_PROXY 和 HTTP_PROXY。网关自己对 IdP、发现、JWKS、令牌和 userinfo 的请求直接进行,除非您设置 oidc.use_proxy: true,这需要 v2.1.227 或更高版本。设置代理变量、use_proxy 未设置且发行者不被 NO_PROXY 覆盖时,网关保持这些请求直接并在启动时记录通知,要求您选择;use_proxy: false 保持它们直接并沉默通知。
使用 use_proxy: true,pod 自己解析每个 IdP 端点的主机名,并要求代理 CONNECT 到解析的 IP 地址,因此代理必须接受 CONNECT 到发现文档命名的每个主机的 IP 地址,不仅仅是发行者。使用 http:// 代理 URL。ca_cert_pem 和SSRF 防护也适用于代理路径。
仅代理出口改变这两者:当它活跃时,IdP 请求遵循代理,除非您设置 use_proxy: false,网关将每个 IdP 主机名交给代理而不首先解析它。
仅代理出口
在网关的环境中设置CLAUDE_GATEWAY_PROXY_IS_EGRESS_BOUNDARY=1,在 HTTPS_PROXY 旁边,当 pod 仅通过该前向代理到达其他主机且无法自己解析公共 DNS 名称时,或当代理拒绝 CONNECT 到 IP 地址时。需要 v2.1.277 或更高版本。它是环境变量而不是 gateway.yaml 键,以便配置文件中的任何内容都无法放松网关的地址检查。
network: 行。
下面的每一行是具有 HTTPS_PROXY 设置的网关上的一类出站请求,默认情况下和仅代理出口活跃时。
仅代理出口保持关闭,除非网关的环境满足所有这三个条件:
HTTPS_PROXY或HTTP_PROXY已设置。NO_PROXY和no_proxy为空。如果您的平台将任一个注入到 pod,在网关容器上将两者设置为空值。在NO_PROXY中列出遥测收集器保持仅代理出口关闭。CLAUDE_GATEWAY_ALLOW_LOOPBACK未打开。pod 自己环回上的收集器或 IdP 无法与仅代理出口结合,因为交给代理的环回地址将是代理主机自己的,因此给这些服务一个代理可以到达的地址。出于同样的原因,网关在仅代理出口活跃时完全拒绝localhost风格的名称。
oidc.use_proxy: false保持内部 IdP 直接。
session
session 块塑造网关在登录后铸造的持有者令牌:签署它们的秘密和它们的生存时间。
store
store 块将网关指向其 PostgreSQL 数据库,该数据库保存设备授权和速率限制计数器。
对于本地开发,将
postgres_url 指向一次性 Postgres 容器,例如 docker run --rm -p 5432:5432 -e POSTGRES_HOST_AUTH_METHOD=trust postgres。
upstreams
upstreams 是一个有序列表。网关会将推理请求转发到第一个能解析所请求模型的上游,并跳过任何其 groups 列表不包含该开发者的上游。
在 5xx、429、401、403、404 或超时时,网关故障转移到下一个上游;其他 4xx 不会,因为这些错误可归因于请求而不是上游。401 或 403 意味着上游拒绝了网关使用的凭据,或拒绝其访问,例如对所请求模型的访问。404 意味着该上游不提供请求的模型,因此列表中的后续上游仍然可以。
如果您在上游上设置 forward_user_identity: true,它返回给携带开发人员电子邮件的请求的 429 不会故障转移。请参阅每用户限制拒绝如何到达开发人员。
404 上的故障转移需要网关 v2.1.198 或更高版本。早期版本即使列表中的后续上游提供模型,也将第一个 404 返回给客户端。
相同提供商的多个上游必须设置不同的 name:。
Amazon Bedrock、AWS 上的 Claude Platform、Google Cloud 的 Agent Platform 和 Microsoft Foundry 客户端在启动时构建一次,其 SDK 在内部刷新凭据,因此轮换云凭据不需要重启。静态 Anthropic API 密钥和持有者在启动时读取;请参阅 Anthropic API。
上游错误消息
网关返回一个上游的错误响应或其自己的502,取决于上游如何应答:
- 上游返回网关不故障转移的状态:该上游的响应。网关不尝试进一步的上游。
- 网关尝试的每个上游都以会触发故障转移的方式失败:返回最后一个
429。如果没有任何上游返回429,网关按顺序优先返回最后一个401或403、最后一个404、最后一个501。如果都没有返回这些状态,则返回网关自身的502,即all upstreams failed (N attempted)。N 统计您的upstreams条目(包括被跳过的条目),减去groups列表不包含该开发者的条目。
- Anthropic 标准错误信封中的
400或413:上游自己的消息,如prompt is too long。AWS 上的 Claude Platform、Agent Platform 和 Microsoft Foundry 为模型 API 拒绝返回此信封。 - 提供商自己形状中的
400或413:capability_rejected:令牌。当网关无法分类拒绝时,400上的upstream rejected the request或413上的request too large for this upstream。 - 任何其他状态:通用的按状态副本,如
429上的upstream rate limit exceeded。
Input is too long for requested model. 替换为 capability_rejected: prompt_too_long。Claude Code 自动压缩该令牌,就像它对 prompt is too long 所做的那样。
保持云上游的 400 或 413 消息或将其替换为 capability_rejected: 令牌需要网关 v2.1.233 或更高版本。
Anthropic API
最小的 Anthropic 上游是来自 Claude Console 的 API 密钥:api_key:发送x-api-key。在 Claude Console 中轮换它并更新环境变量。oauth_token:发送Authorization: Bearer。当您的组织发出短期令牌而不是长期 API 密钥时使用持有者形式。持有者在启动时读取一次,因此通过重新挂载秘密和重启来刷新。
为您运行的代理的每用户身份标头
您可以将provider: anthropic 上游的 base_url 指向您运行的代理而不是 Anthropic API。要告诉该代理哪个开发人员发送了每个请求,在该上游上设置 forward_user_identity: true。代理然后可以按开发人员属性支出。需要网关运行 Claude Code v2.1.233 或更高版本。
例如,对于 upstream-gateway.internal.example.com 上的代理:
当 IdP 令牌不携带电子邮件时,网关仅发送
x-claude-gateway-user-id 并省略两个电子邮件标头。如果您的 IdP 将电子邮件放在不同的声明中,将 oidc.email_claim 设置为该声明。
您的代理不会收到 Claude Code 发送的 x-claude-code-* 标头,例如 x-claude-code-session-id。网关不会将它们传递给任何上游,因此请使用上表中的标头按开发人员对请求进行分组。
当您的代理对携带开发人员电子邮件的请求应答 429 时,网关按原样将该响应返回给开发人员而不是故障转移到下一个上游,因此您的代理的每用户预算或速率限制保持。代理的其他响应遵循普通故障转移规则。如果开发人员的 IdP 令牌不携带电子邮件,网关转发其请求而不带电子邮件标头,因此对其中一个请求的 429 计为上游容量并故障转移。在网关服务器上的 v2.1.267 之前,每个 429 都故障转移。
仅在 base_url 是您操作的代理的上游上设置 forward_user_identity。网关将开发人员电子邮件发送到该 base_url 命名的任何服务器。如果 base_url 是 Anthropic API(默认),网关拒绝启动。
如果您在 Amazon Bedrock 上游上设置
forward_user_identity,网关会在启动时退出并显示 Unrecognized key(s) in object: 'forward_user_identity'。如果您的代理位于 Bedrock 前面,请改为将其列为 provider: anthropic 上游。网关向该上游发送 Anthropic Messages 格式,因此您的代理必须为 Bedrock 转换请求。若要改为向 AWS 标明每个开发人员,请参阅每开发人员 AWS 成本属性。Amazon Bedrock
对于网关替换或前置的客户端 Amazon Bedrock 部署,请参阅 Amazon Bedrock 上的 Claude Code。网关端上游:auth 块使用 AWS SDK 的默认凭据链:环境变量、~/.aws/credentials、ECS 任务角色、EC2 实例元数据或 EKS 上的 IRSA。在生产中,给网关 pod 一个 IAM 角色而不是在容器镜像中嵌入静态密钥。
显式凭据必须完整:当 aws_access_key_id 和 aws_secret_access_key 未一起设置时,或当 aws_session_token 在没有它们的情况下设置时,网关在启动时失败。在 v2.1.207 之前,部分 auth: 块通过验证。
应用 Amazon Bedrock 防护栏
要将 Amazon Bedrock 防护栏应用于网关通过 Bedrock 上游发送的每个推理请求,将guardrail 块添加到该上游。需要网关服务器上的 Claude Code v2.1.281 或更高版本。
bedrock:ApplyGuardrail 给签署此上游请求的主体:网关的 AWS 主体,或使用 assume_role 的 role_arn 中命名的角色。
在每个 bedrock 上游或不在任何上游上设置 guardrail。网关拒绝在混合上启动,因为故障转移可能会将请求发送到没有防护栏的 Bedrock 上游。
防护栏仅覆盖 Bedrock 上游。如果您在 upstreams 中列出另一个提供商,网关将请求发送到该提供商而不带防护栏;如果该提供商是 mantle,则网关拒绝启动。
当 /v1/messages 请求的正文携带 amazon-bedrock-* 字段(如 amazon-bedrock-guardrailConfig)到达设置了 guardrail 的 Bedrock 上游时,网关应答 400 而不是转发它。
添加防护栏输入标签
要让网关添加 Amazon Bedrock 防护栏的提示词攻击过滤器所需的输入标签,请在guardrail 块中设置 input_tagging 并重启网关。在每个 bedrock 上游上设置相同的值,否则网关会拒绝启动。要求网关服务器上运行 Claude Code v2.1.316 或更高版本。不支持该键的版本的网关会在启动时以 Unrecognized key(s) in object: 'input_tagging' 退出。
input_tagging 接受以下值之一:
使用
last_message 时,如果自 Claude 上次回复以来的 user 消息中没有可加标签的文本,网关会改为给自该回复以来的对话中途系统消息加标签。工具调用也算作一次回复。
Amazon Bedrock 对提示词攻击过滤器的指导是为用户输入加标签以排除系统提示词。如果您设置 all_messages_and_system,标记 Claude Code 自身系统提示词的过滤器可能会拦截请求。
以下示例为每条 user 消息中的文本加标签:
user 消息中还可能包含 Claude Code 添加的文本,例如系统提醒,因此请在测试网关上确认普通请求不会被拦截。
在 Anthropic 的测试中,加了标签的会话在相邻提示词之间保持了提示缓存读取,并且标签没有增加输入 token。
输入标签不覆盖的内容
没有任何input_tagging 值能阻止故意将文本放在不加标签位置的开发者。不要指望防护栏评估请求的以下部分:
- 网关不加标签的内容:您的
input_tagging值未包含的消息、工具定义、工具调用输入、图像和 PDF 等。除非您设置all_messages_and_system,否则系统提示词也不加标签。 - 工具结果:这些内容包含 Claude 的工具返回的内容,例如文件内容和网页。在 Anthropic 的测试中,无论是否加标签,字词过滤器都不会评估它们。
记录触发的防护栏过滤器
要找出是哪个 Amazon Bedrock 防护栏过滤器拦截了开发者的请求,请在 Bedrock 上游上设置guardrail_trace: true,重启网关,然后让开发者重新发送该请求。接着在审计日志中找到该请求的 guardrail.trace 事件。需要网关服务器上运行 Claude Code v2.1.314 或更高版本。更早版本的网关在发现 guardrail_trace 时会拒绝启动。
INTERVENED 时,网关会写入一个 guardrail.trace 事件,其中不包含匹配的文本。可通过 email 或 sub 查找开发者的事件。一个流式请求可能产生多个事件,其中一个的 filters 列表可能为空,因此请阅读具有相同 request_id 的所有事件:
该事件不包含过滤器匹配的文本,包括 Bedrock 跟踪中的
match 字段。开发者不会收到 Bedrock 的跟踪数据,因为网关会从每个回复(无论是否流式)中将其删除。
如果客户端在 /v1/messages 请求正文中发送 amazon-bedrock-* 字段,网关在设置了 guardrail_trace 的上游上会返回 400。
另一个 AWS 帐户中的 Bedrock
在 Bedrock 上游上设置assume_role,网关仅使用其自己的 AWS 身份来调用您命名的角色上的 sts:AssumeRole,该角色可以在与网关不同的 AWS 帐户中。该上游的每个 Bedrock 请求都使用 STS 返回的一小时凭据签署,因此没有长期访问密钥跨帐户。
需要网关运行 Claude Code v2.1.281 或更高版本。早期网关在找到键时拒绝启动。
assume_role 块采用三个键:
角色的信任策略命名网关自己的主体,如其 IRSA 或 ECS 任务角色。该主体需要在角色上的
sts:AssumeRole 且没有 Bedrock 权限。如果您设置没有 external_id,删除 Condition。
- 如果 STS 拒绝或无法到达,网关不使用上游自己的凭据发送请求。它记录 STS 错误和要检查的内容,然后尝试您列出的下一个上游。上游错误消息覆盖当没有上游成功时客户端接收的内容。没有
assume_role的后续上游将使用其自己的凭据提供请求,因此仅在这是您想要的情况下列出一个。 - 网关调用区域 STS 端点
sts.<region>.amazonaws.com,其网络必须到达。对于 FIPS 端点,在网关的环境中设置AWS_USE_FIPS_ENDPOINT=true而不是在 AWS 配置文件中的use_fips_endpoint。 assume_role需要 SigV4 源凭据:当它与aws_bearer_token一起设置时,网关会拒绝启动。- 如果没有
groups列表,网关允许的每位开发者都可以使用此上游。要限制开发者可以使用的模型,请在managed策略中设置availableModels。 - 要防止通过该角色提供的模型也从其他账号提供,请为其指定一个自定义 id,使其
upstream_model映射仅包含此上游的名称。对于这样的 id,网关会跳过所有其他上游,因此无论是请求本身还是针对被中止请求的 token 计数,都不会故障转移到其他账号。 - 对内置模型名称的请求仍可能到达此上游,网关会使用同一角色对其签名。除非该账号也应提供这些模型,否则请将此上游列在最后。
每开发人员 AWS 成本属性
默认情况下,网关使用一个凭据签署每个 Bedrock 请求,因此 AWS 在单个 IAM 主体下看到所有开发人员的请求。将session_name: email 添加到 assume_role,网关每个开发人员每小时调用一次 sts:AssumeRole,会话名称设置为该开发人员的电子邮件,并使用返回的凭据签署其请求,因此每个开发人员的请求在 AWS 下以其自己的假设角色会话到达。角色可以在网关自己的帐户中。
需要网关运行 Claude Code v2.1.281 或更高版本。AWS 上的成本属性覆盖 IAM 角色和 AWS 计费显示会话的位置。
session_name 选择哪个已验证的声明成为 AWS RoleSessionName:email 或 sub。网关将除 ASCII 字母、数字和 _+,.@- 之外的任何字符写成 =XX 十六进制(按 UTF-8 字节),并将长于 64 字符的结果缩短为前缀加哈希,因此每个开发人员的会话名称保持有效且唯一。来自其令牌缺少声明的开发人员的请求不通过此上游发送,操作员日志说切换到 sub 或设置 oidc.email_claim。
活跃开发人员每小时每个网关副本成本一个 STS 调用,并发首次请求共享一个调用。
网关也在此角色上进行一个调用:客户端放弃的请求的 token 计数,因此支出限制保持准确。该计数及其单 token 回退请求由共享 claude-apps-gateway 会话签署,因此 AWS 将回退属性到 claude-apps-gateway 而不是开发人员。
对于严格的每开发人员属性,在您列出的每个 Bedrock 上游上设置 assume_role 与 session_name。没有它的上游使用其自己的凭据签署它提供的请求。
Amazon Bedrock Mantle 端点
mantle 提供商将推理发送到 Amazon Bedrock 的 Mantle 端点。它需要网关服务器上的 Claude Code v2.1.283 或更高版本。早期网关版本在启动时拒绝它,因此请在添加之前升级每个副本。
下面的示例将 Mantle 放在首位,其后是一个 Amazon Bedrock 上游,用于提供 models 字段未列出的每个模型:
mantle 上游特有的字段。
为上游的 AWS 身份授予 Mantle 自己用于推理和 token 计数的 IAM 操作,使用 Mantle 端点中列出了这些操作。
对于网关不知道的 Mantle 模型 ID,在顶层
models: 块中添加一个条目,其 upstream_model 将此上游的名称映射到该 ID。然后也将该条目的 id 放入此上游的 models 字段。
bedrock 上游的 guardrail 和 assume_role 设置不会扩展到 Mantle 提供的请求:
guardrail:网关不对发送到 Mantle 的请求应用 Bedrock 防护栏,因此当列出mantle上游而任何bedrock上游设置了guardrail时,网关拒绝启动。assume_role:请在mantle上游本身上设置。没有它时,Mantle 处理的请求会使用mantle上游自身的auth凭据发送。
AWS 上的 Claude Platform
AWS 上的 Claude Platform 在 AWS 基础设施上提供第一方 Anthropic API,位于aws-external-anthropic.<region>.api.aws。它使用第一方模型 ID,按原样遵守 anthropic-beta 标头,并提供 count_tokens,因此没有 Bedrock 特定的转换适用。anthropicAws 提供商需要 Claude Code v2.1.198 或更高版本;早期网关版本在启动时拒绝它。
对于相同平台的客户端部署,请参阅 AWS 上的 Claude Platform 上的 Claude Code。网关端上游:
aws-external-anthropic 签署 SigV4 请求,因此 Bedrock 范围的 IAM 角色不授权它。auth.api_key 中的 API 密钥在同时设置 SigV4 凭据时优先。空 auth 块使用 AWS SDK 的默认凭据链,与 Amazon Bedrock 上游使用的链相同。
因为平台解析第一方模型 ID,内置目录路由到它而不带
models: 块。当您策划 models: 列表时,使用第一方 ID 作为 anthropicAws: 条目的值。
Google Cloud Agent Platform
对于等效的客户端设置,请参阅 Google Cloud 上的 Claude Code。网关端上游:auth 块使用应用默认凭据:GOOGLE_APPLICATION_CREDENTIALS、GCE 元数据或 GKE Workload Identity。服务帐户 JSON 密钥文件被支持但不鼓励;使用 Workload Identity 或将服务帐户附加到 GCE 或 Cloud Run 实例。
设置 region: global 以使用 Google Cloud Agent Platform 的全局端点而不是区域端点。Google 然后将每个请求路由到可用区域,因此您不跟踪按区域模型可用性。设置特定区域将每个请求固定到它。
Microsoft Foundry
对于客户端 Microsoft Foundry 部署,请参阅 Microsoft Foundry 上的 Claude Code。网关端上游:use_azure_ad: true 通过 DefaultAzureCredential 解析:AKS、ACI 或 App Service 上的托管身份;Azure CLI;或环境凭据。API 密钥有效但是项目范围的,不自动轮换。Microsoft Foundry 的端点从 resource: 派生;为主权云(如 Azure Government)设置可选 base_url 以覆盖它。
上游请求上的静态标头
要将固定标头添加到网关发送到一个上游的请求,在该上游上设置headers:。当您运行的代理通过标头路由或属性流量时使用它。
headers: 需要网关服务器上的 Claude Code v2.1.277 或更高版本。早期网关在找到键时拒绝启动。在添加键之前升级每个副本,并在回滚到早期版本之前删除键。
标头转到 base_url 命名的服务器,或当 base_url 未设置时转到提供商自己的端点。提供商也接收它们,除非您的代理删除它们。
此示例通过 upstream-proxy.internal.example.com 上的代理到达 provider: vertex 上游。它设置代理读取的 x-source 标头,并从 PROXY_TOKEN 环境变量发送令牌作为 x-proxy-token:
true 或 false 以便 YAML 将其读取为文本。
要将秘密保持在配置文件之外,使用秘密扩展从环境变量使用 ${VAR} 或从文件使用 ${file:/path} 加载值。解析为空值的 ${VAR} 停止网关启动。
headers: 适用于每个提供商,每个上游仅发送自己的。
并非网关发送到上游的每个请求都携带它们:
在使用 AWS SigV4 签署请求的 Amazon Bedrock 或 AWS 上的 Claude Platform 上游上,这些标头是签名的一部分,因此您的代理必须原样通过它们。
如果您使用网关保留的名称,它拒绝启动,启动错误命名标头。保留名称包括:
authorization和x-api-keyhost、content-type和user-agent- 任何以
anthropic-、x-goog-、x-amz-或x-amzn-开头的名称
多个上游
相同提供商可以出现多次,具有不同的name:。这涵盖不同的区域、通过不同凭据链的不同帐户、预配吞吐量与按需,以及跨提供商故障转移。
网关按顺序尝试上游。5xx、429、401、403、404、超时和缺失端点 (501) 故障转移;其他 4xx 不会。
429 是按上游容量,因此预配吞吐量 (PT) 耗尽故障转移到按需。如果您在上游上设置 forward_user_identity: true,对携带开发人员电子邮件的请求的 429 是按用户拒绝而不是故障转移。
仅在以下情况下,请求才会越过某个上游:
- 该上游已失败
- 该上游不提供所请求的模型
- 该上游的
groups列表不包含该开发者
provider: anthropic上游:timeouts.upstream_ttfb_ms,默认 120 秒- 其他提供商:最多一小时。要缩短流式请求的等待时间,请在网关 v2.1.295 或更高版本上设置
timeouts.upstream_ttfb_ms。非流式模型请求无论如何都最多等待一小时
404 是按上游模型可用性,因此未启用模型的上游不阻止提供它的后续上游。无法解析请求的模型的上游被跳过而不进行网络往返。
此示例首先路由预配吞吐量 Amazon Bedrock 分配,溢出到按需和第二个帐户,并最后回退到 Anthropic API:
在云提供商之间或直接 Anthropic API 之间故障转移改变哪个协议、地理位置和其他条款控制请求。
CLI 对网关应用相同的功能门控,无论哪个上游提供给定请求,因此默认情况下故障转移不会发送上游会拒绝的正文字段。如果您在策略中设置了一小时缓存 TTL,它会发送到列表中的每个上游,因此仅当所有上游都接受它时才设置。
将每个团队发送到各自的上游
要将每个团队的请求发送到其各自的 AWS 账户或 Google Cloud 项目,请为每个团队列出一个上游,并为每个上游提供一个groups 列表。只有所列 IdP 组中的开发者才能访问该上游,无论是首次尝试还是故障转移。所有提供商都支持 groups。网关服务器上需要 Claude Code v2.1.314 或更高版本。
以下示例为 payments-eng 和 search-eng 组各分配一个 AWS 账户,并添加一个没有 groups 列表、所有开发者都可使用的上游:
当团队的上游以
403 拒绝所请求的模型时,网关会尝试该团队所在行中提供该模型的下一个上游。要将团队限定在一个上游,请为每个上游提供 groups 列表,并确保没有其他上游列出该团队开发者所属的组。这样该团队将没有故障转移,而不属于任何所列组的开发者发出的请求将以 400 失败。
要让每个开发者到达您预期的上游,请编写完全匹配的条目,并将开放的上游放在最后:
- 条目:按照您的 IdP 在 groups 声明中发送的形式准确编写每个组,
match.groups也会读取该声明。当网关发现空列表或空条目时会拒绝启动。网关不会根据您的 IdP 检查条目,因此不匹配任何人的条目不会引发警告。 - 顺序:将没有
groups列表的上游放在最后。它为所有人提供服务,因此如果排在前面,它会抢在团队自己的上游之前接收该团队的请求。
开发者不属于任何所列组时会发生什么
如果每个上游都有groups 列表,不属于其中任何组的开发者会看到以下错误,并且网关不会联系任何提供商:
groups 列表的上游。
网关会在每次令牌刷新时重新读取开发者所属的组。如果您的 IdP 在刷新时未包含组信息,该开发者将不属于任何组:
- 已设置
oidc.allowed_groups:网关拒绝该刷新,会话结束 - 否则,如果某个上游没有
groups列表:该开发者的请求会转到该上游 - 否则,如果每个上游都有
groups列表:该开发者的请求会以上述错误失败
oidc.google_groups,请将 oidc.userinfo_fallback 设置为 true,以便从该端点补充组信息。
可选部分
login_notice
要在开发者登录时向其显示一条通知,请将顶层 login_notice 键设置为通知文本,最多 500 个字符。此示例说明了该网关面向哪些人员以及在何处申请访问权限:
Notice from <gateway hostname> 下方看到该文本。文本中的换行会变为空格。该通知在登录之前显示,因此任何能够访问网关的人都可以读取它。
需要网关服务器上运行 Claude Code v2.1.319 或更高版本;若要在终端界面中显示,开发者的机器上也需要该版本。较早版本的网关在发现该键时会拒绝启动。请在添加该键之前升级所有副本,并在回滚之前移除该键。
admin
可选。启用 /v1/organizations/spend_limits(它与 Anthropic 的公开 Admin API 一致),并在 /v1/messages 上按开发者执行支出限制。有关上限的设置和执行方式,请参阅支出限制;本节介绍用于启用和调整该功能的 gateway.yaml 键。
共享预算顺序
共享预算是整个组共同消耗的一个月度限额。要设置共享预算,请在设置该组月度上限的请求中添加pooled_budget,例如用 "pooled_budget": {"amount": "500000"} 表示 $5,000。该请求还需要该组的 scope、"period": "monthly" 以及 amount,后者仍是每位成员各自的上限。
对于属于多个此类组的开发者,每个请求都会计入第一个支出低于其限额的预算;当所有预算都已用完时,请求会被拒绝。pooled_conflict_rule 设置网关尝试这些预算的顺序:
default_order:限额最大的优先,限额相同时按组名升序排列priority_list:先按列表顺序尝试pooled_priority_order中各组的预算,然后按组名尝试其他组的预算
pooled_conflict_rule: priority_list,网关会忽略该列表并在启动时记录一条警告。
早于 v2.1.319 的网关服务器在发现 pooled_conflict_rule 或 pooled_priority_order 时会拒绝启动。请在添加任一键之前升级所有副本,并在回滚之前移除这两个键。
enforcement
enforcement 块控制存储不可用时支出限制检查的行为。
pricing
pricing 块告诉支出计量器按什么价格计费,而不是使用美元标价,因此上限和 /effective 会反映您的合同价格。金额仍以美元计,并且仍然是估算值,而不是发票。两个前提条件:
- 网关服务器上的 Claude Code 为 v2.1.227 或更高版本。更早的版本会在启动时拒绝这个未知键。
- 存在
admin:块,或者在 v2.1.268 或更高版本中,存在至少包含一个策略的managed:块。如果设置了pricing但两个块都不存在,网关将拒绝启动,因为没有任何内容会读取它。
计量器匹配覆盖行的方式:
- 对于
upstream(一个upstreams[].name)为model提供服务的请求,该行会替换标价。这包括较高的快速模式费率,因此快速请求和标准请求按相同的四个费率计量。 - 内置 ID(例如
claude-sonnet-4-6)的匹配方式与models[].id相同,涵盖计量器按该模型计价的所有带日期形式、区域性 Amazon Bedrock 形式或 Google Cloud Agent Platform 形式。其他任何字符串(例如别名或推理配置文件 ARN)会不区分大小写地匹配客户端发送的 ID 或发送到上游的字符串。 - 当多行重叠时,计量器选择最具体的行,而不是第一行:首先是
model为发送到上游的确切模型字符串的行,其次是与客户端发送的确切 ID 匹配的行,最后是指定内置模型的行。 - 未知的上游名称会导致启动失败,同一上游的两行指定相同模型(包括同一内置模型的两种写法)也会导致启动失败。对于任何可请求模型都无法使用的行,网关会在启动时发出警告。
- 网页搜索请求保持 $0.01 的标价;乘数仍然适用于它们。
加价
在网关服务器上使用 v2.1.271 或更高版本时,您可以将multiplier 设置为大于 1(最高 10),以高于提供商收费的价格进行计量,例如用于内部成本分摊费率。此示例将每个请求按价格的 120% 计量:
admin: 块时,加价也适用于支出限制。计量器按价格的 120% 计数,因此开发者会更早达到上限。网关会在启动时记录一条说明此情况的警告。
乘数不会改变上游提供商对这些请求的收费。
如果网关还将费率发送到已登录的客户端,开发者需要 Claude Code v2.1.271 或更高版本才能看到加价。更早的客户端会忽略大于 1 的 multiplier,并显示不含加价的成本。
如果您将 multiplier 设置为大于 1,早于 v2.1.271 的网关服务器将拒绝启动。
将费率发送到已登录的客户端
在网关服务器上使用 v2.1.268 或更高版本时,网关还会将pricing 中的费率作为 modelPricing 托管设置,放入其提供的 managed 策略中。
被某个策略匹配的开发者随后会在 /usage、状态栏和 OpenTelemetry 中看到 pricing 费率。未匹配任何策略的开发者不会收到托管设置,因此其数据保持按标价计算。客户端在 Claude Code v2.1.242 或更高版本中应用此设置。
- 网关添加的内容:除非策略的
cli块已设置modelPricing,否则网关会添加multiplier,并针对客户端可以请求的每个模型 ID,添加为该 ID 提供服务的第一个上游的覆盖行。仅由故障转移上游收取的费率保留在网关上。 - 带有
groups列表的上游:当它是为某个模型 ID 提供服务的第一个上游时,网关不会为该 ID 添加行。开发者随后会看到 Claude Code 自己为该 ID 设定的费率(当 Claude Code 识别该 ID 时,即该模型的标准费率)乘以multiplier。 - 让某个策略退出:在该策略的
cli块中将modelPricing设置为{},其开发者将保持标价。 - 保留策略自身的费率:如果策略的
cli块使用自己的multiplier或overrides设置了modelPricing,则该modelPricing会完整保留,网关不会向其中添加自己的任何费率。
models
models 块是一个可选的、由管理员维护的模型列表,在 /v1/models 提供,并用于按上游转换模型 ID。对于非美国 Amazon Bedrock 区域、Amazon Bedrock 预置吞吐量 ARN 和 Microsoft Foundry 部署名称,此块是必需的。
upstream_model 下的每个键必须与已配置上游的 name 匹配,该名称默认为提供商名称。不匹配任何上游的键会导致启动失败,因此请省略您不使用的提供商对应的行。
要在 auto_include_builtin_models: false 的情况下让开发者使用 fable 别名,请在 models 中添加一个 claude-fable-5 条目。对于登录到网关的开发者,fable 别名解析为该 ID。没有该条目时,他们的消息会失败,错误以 API Error: 400 model claude-fable-5 is not in the operator's model allowlist 开头。
managed
managed 块定义基于 IdP 组或电子邮件域的基于角色的访问策略。策略按顺序评估;默认情况下选择第一个匹配项,然后将其合并到 match: {} 兜底基础层上。匹配两个角色策略的用户只会获得第一个,因此除非您应用所有匹配的策略,否则第二个策略的拒绝规则不会生效。策略按用户在 GET /managed/settings 提供,并使用 ETag/304 缓存。
match: {} 兜底策略按惯例放在最后,被视为基础层。其他每个策略都会从兜底策略继承自己未设置的任何键,因此按角色的条目只需列出与组织默认值不同的内容。合并规则取决于键的类型:
- 允许列表:
availableModels和permissions.allow。特定策略的列表会完全替换基础层的列表。 - 拒绝列表和 hook 数组:取基础策略与该策略的并集:
permissions.deny和permissions.askdisabledMcpjsonServers和deniedMcpServersblockedMarketplaces和deniedModelshooks事件类型数组
- 记录类型的键:
env、modelOverrides和skillOverrides。这些进行浅合并,因此按角色的env块会覆盖它设置的键,并从基础层继承其余的键。
availableModels 还会在 /v1/messages 的服务器端执行,因此无论客户端发送什么,被拒绝的模型都会返回 400。空列表会拒绝所有模型。该检查还涵盖开发者选择模型之前会话启动时使用的模型,因此请让会话在策略允许的模型上启动。
网关在转发请求之前会自行验证 model 值,因此格式错误的值永远不会到达上游。在以下两种情况下,它会以 400 拒绝请求:
- 当该值缺失或为空时,网关会以消息
model is required拒绝请求。该检查要求网关运行 Claude Code v2.1.228 或更高版本。 - 当该值存在但不是字符串时,网关会以消息
model must be a string拒绝请求。要求网关运行 Claude Code v2.1.221 或更高版本。
未匹配任何策略的已通过身份验证的用户将获得网关的默认值,即目录中的所有模型且没有托管设置。如果您希望有一个确定的默认策略,请在最后添加一个
match: {} 兜底策略。
请将组织范围的拒绝规则放在 match: {} 策略中,因为组策略的规则仅在用户的令牌携带该组时才适用。
网关本身不保存用户目录。它根据用户的 IdP 令牌对每个请求进行授权,从令牌的
groups 声明中读取组成员身份,并据此评估策略。没有可枚举的名单,也没有需要预先创建的账户,因此也没有 SCIM 端点,因为没有任何内容可供 SCIM 同步。请在事实来源处进行用户和组的生命周期管理,即您的 IdP 的原生 SCIM 预配或专用的身份治理平台。在那里管理的成员身份和取消预配会通过令牌自动传递到网关。如果您希望对 Claude 账户本身进行 SCIM 预配,那是 Claude for Enterprise 的功能。有两个传播时钟:- 策略内容:编辑策略并重新部署后,已连接的 Claude Code 客户端会在下一次托管设置轮询时(一小时内)收到更改,但仅在下次启动时生效的更改除外
- 组成员身份:更改用户的组成员身份会改变与其匹配的策略。这在下一次会话重新签发时生效,即下一次静默刷新,最长不超过
session.ttl_hours。
应用所有匹配的策略
匹配多个角色策略的用户只会获得第一个,除非您在policies 旁边设置 policy_mode: layered。使用 layered 时,与用户匹配的每个策略都会生效,直到第一个 match: {} 策略为止。
policy_mode 要求网关服务器上的 Claude Code 为 v2.1.316 或更高版本。不支持该键的版本的网关在发现该键时会拒绝启动。请在添加该键之前升级每个副本,并在回滚到更早版本之前删除该键。此示例中,一个组失去 WebFetch,另一个组获得 Opus:
no-web 和 opus-users 的用户在默认的 first_match 和 layered 下分别收到的内容。
网关按照与基础层相同的合并规则,将每个匹配的策略合并到列在其下方的策略上:
- 允许列表、单值以及
sandbox等块:每一项完整地取自设置了它的、列在最前面的匹配策略,因此两个组的availableModels列表不会叠加。 - 拒绝列表和 hook 数组:这些在所有匹配的策略之间叠加,因此属于两个组的用户会获得两个组的拒绝规则。
env、modelOverrides和skillOverrides:条目按名称合并,由设置了该名称的、列在最前面的匹配策略提供其值。desktop键:这些按照基础desktop块的规则合并。
layered 时,网关会因某些设置而拒绝启动,包括以下设置:
!模式:任何策略(包括match: {}策略)的permissions.deny或permissions.ask列表中,Read或Edit规则里的!否定- 兜底策略之外对 hook 的限制:除
match: {}以外的任何策略中的disableAllHooks、allowedHttpHookUrls或httpHookAllowedEnvVars
让会话在策略允许的模型上启动
如果availableModels 未包含 Claude Code 的默认模型,会话将收到 400 响应,直到开发者选择一个列出的模型(例如使用 /model)。在网关会话中,默认模型是 opus 别名解析到的 Opus 模型,而单独使用 availableModels 不会改变它。
要解决此问题,请在同一 cli 块中设置 enforceAvailableModels: true,然后检查列表中包含哪种条目:
- 别名(例如
sonnet)或内置 ID(例如claude-sonnet-4-6):会话会在其中一个模型上启动,/model中的 Default 选项会解析为该模型 - 列表中没有别名或内置 ID:会话可能仍在内置默认模型上启动,因此还需在该策略的
cli块中将model设置为列出的 ID 之一
models 定义的自定义 ID,并让会话在该 ID 上启动:
会导致网关在启动时停止的匹配器值
启动时,网关会检查每个策略的match 块以及 admin_groups 列表。以下任一值都会使网关停止,并显示一条指明该字段的错误:
- 空的
groups列表 groups或admin_groups中的空条目- 空的
email_domain - 包含
@、空白或逗号的email_domain。网关在此检查之前会修剪该值并去除一个前导@。请写一个不带修饰的域,例如example.com。
- 空的
email_domain:网关跳过域检查,因此email_domain为空且没有groups列表的策略会匹配每个已通过身份验证的用户 - 空的
groups列表:该策略不匹配任何人 - 包含
@、空白或逗号的email_domain:该策略不匹配任何人 groups或admin_groups中的空条目:仅当用户的 IdPgroups声明也包含空条目时,该条目才会匹配该用户。在admin_groups中,这种匹配会授予管理员访问权限。如果您的admin_groups列表从未包含空条目,则没有人会通过这种方式获得管理员访问权限。
选择 cli 或 code
策略的 Claude Code 设置(例如拒绝读取 .env 文件的规则)放在 cli 或 code 键下的块中。code 是推荐的键,cli 是旧版键。两个键接受相同的内容。键决定了设置在何处执行:
cli:终端、VS Code 和 JetBrains 扩展以及 Agent SDK。在cli下,Claude Desktop 的 Code 选项卡获得的是派生设置,因此像Read(./.env)这样的限定范围规则不会在那里阻止用户。code:相同的位置,并且也可以覆盖 Claude Desktop 的 Code 选项卡。
cli 的文件照常工作;如果网关在带有 desktop 键的策略中发现 cli,会在启动时发出警告,但仍会启动。请切换到 code,以便设置也能覆盖 Code 选项卡。
切换之前,请阅读在 Code 选项卡中应用 code 设置。策略需要 desktop 键,并且用户的机器需要完成设置后这些设置才会在那里生效,此外 Claude Desktop 中的网页搜索会被关闭。
此策略将拒绝规则放在 code 下,并带有一个空的 desktop 键:
serve_to_desktop 行。在说明中提到 cli 块的地方,请使用您的 code 块。
serve_to_desktop: true 是向 Code 标签页提供策略 cli 设置的旧方式。当 Claude Desktop 通过 bootstrapUrl 连接时,它不起作用。当您的策略使用 cli 时,提到此键的启动警告意味着这些设置未到达 Code 标签页:
- 要覆盖 Code 标签页:在用户的计算机满足在 Code 标签页中应用
code设置中的条件后,切换到code - 要继续使用
cli:在策略中的cli旁设置serve_to_desktop: false以消除警告
cli 中包含什么
每个 code 或 cli 值都是一个完整的 Claude Code managed-settings.json 文档,与您通过 MDM 或 /etc/claude-code/managed-settings.json 部署的 schema 相同,只是此处以 YAML 表示。CLI 在托管层级(高于用户和项目设置)应用所交付的文档,以取代服务器托管设置。因此,它会忽略仅限于操作系统级策略来源的设置,例如 policyHelper 和 wslInheritsWindowsSettings。
网关在启动时根据 CLI 的设置 schema 验证每个文档,因此无法识别的顶层键会导致启动失败,并显示指明每个违规键的错误。schema 中有意开放的部分仍接受任意值,因为较新的客户端可能识别网关 schema 无法识别的条目。这些开放的键包括 env、pluginConfigs 以及嵌套在 permissions 下的键。
由于验证使用的是网关已安装版本中捆绑的 schema,要在托管配置中放入较新 Claude Code 版本引入的顶层设置键,需要先升级网关。在推广新策略之前,请先在一个客户端上进行冒烟测试。
完整的键参考请参阅 Claude Code 设置。运维人员最常首先使用的键:
由于这些设置通过网络到达,CLI 在应用以下设置之前会向每位开发者显示安全批准对话框:
hooks- 需要开发者批准的
env变量,例如代理和基础 URL 变量 - shell 执行设置,例如
apiKeyHelper和statusLine - 沙箱二进制设置
sandbox.bwrapPath、sandbox.socatPath和sandbox.ripgrep - 拦截流量、注入凭据或削弱隔离的沙箱设置,例如
sandbox.network.tlsTerminate和代理端口设置。安全批准对话框列出了全部此类设置。
env 变量时不会向开发者显示批准对话框,例如模型选择设置和数值限制。其他交付的变量可能需要开发者批准;非空的代理、base-URL 或 OTEL_EXPORTER_OTLP_ENDPOINT 值始终需要。当交付的变量需要批准时,对话框会列出它的名称。环境变量与批准对话框提供了详细信息,包括四个隐私开关,其交付值决定它们是否需要批准。
网关的遥测配置会推送 OTEL_EXPORTER_OTLP_ENDPOINT,因此设置 telemetry.forward_to 会在每个交互式客户端上触发对话框。该对话框保护的是开发者的机器免受被入侵或恶意网关的影响,而不是保护组织免受开发者的影响。
非交互式运行(例如 claude -p、Agent SDK 会话或 Claude Desktop 的 Code 选项卡中的会话)无法显示对话框。它仅在该次运行中应用推送的设置,并且不会将其记录为已批准,因此开发者的下一个交互式会话仍会显示对话框。
如果开发者拒绝,Claude Code 会退出该会话,而不是应用策略。因此,当您向一个广泛的策略推送新的 hook 或任何会触发对话框的环境变量时,每位匹配的开发者都会在其交互式会话中看到该对话框。正在运行的交互式会话会在下一次每小时轮询时显示它,否则它会在开发者下次交互式启动时出现。
cli 键在早期版本中名为 settings,网关仍接受该写法作为别名。对于新部署,请使用 code。
在部署前测试策略
要测试策略更改,请让网关连接一个临时的 Postgres 数据库启动。网关会先连接 Postgres 并应用其 schema 迁移,然后才检查cli、code 和 desktop 块的内容。如果无法连接数据库,启动会在 could not connect to Postgres 处停止,且不会报告这些块内容的任何信息。
终端会话中的上下文窗口
通过/login 登录的终端会话对 Opus 4.7 及更高版本、Sonnet 5 及更高版本以及 Fable 模型使用 1M 上下文窗口。模型 ID 不需要 [1m] 后缀,会话在约 967K token 时压缩。在开发者机器上的 Claude Code v2.1.287 之前,除非模型 ID 以 [1m] 结尾,否则 Claude Code 将 Opus 和 Fable 模型视为具有 200K 窗口。
要让终端会话改为在 200K 边界处压缩,请在策略的 env 中设置自动压缩窗口:
[1m] 结尾的模型 ID。
要改为关闭 1M 上下文,请在同一 env 块中设置 CLAUDE_CODE_DISABLE_1M_CONTEXT: "1"。Claude Code 随后将每个模型视为具有 200K 窗口。在交互式会话中,每位开发者需要在批准对话框中批准此变量后它才会生效。
一小时提示缓存
要请求一小时的提示缓存 TTL 而非默认的五分钟,请将以下键添加到策略现有的code、cli 或 settings 块中,然后重启网关。这些键要求网关服务器和客户端上运行 Claude Code v2.1.242 或更高版本。
promptCacheTtl 涵盖主对话。subagentPromptCacheTtl 是可选的,涵盖子代理、工作流和后台请求。此示例将两者都添加到以 cli 为键的 match: {} 策略中:
promptCacheTtl,请以策略匹配的用户身份登录网关,然后检查您的缓存写入使用了哪个 TTL。传入 --model 以对网关提供的每个模型重复此检查。
一小时缓存写入的费用高于五分钟写入。要让支出限额计入这一较高费率,网关服务器上需要 v2.1.286 或更高版本。
策略中的 MCP 服务器
要向策略匹配的 Claude Code 客户端提供 MCP 服务器,请在该策略的cli 块中设置 managedMcpServers。网关服务器和客户端上需要 Claude Code v2.1.259 或更高版本。
网关在启动时使用与 Claude Code 在客户端上应用的相同规则检查每个条目;如果某个条目未通过检查,网关将拒绝启动并指明该条目。
如果您在 gateway.yaml 中写入 ${VAR} 引用,网关会在运行条目检查之前,在启动时通过密钥展开从其环境中解析它,因此每个匹配的客户端都会收到字面值并可以读取它。提供服务器的标头指南适用于展开后的值。
网关会拒绝 cli 块中的 .mcp.json 写法 mcpServers,其启动错误会指明应使用的键为 managedMcpServers。在 v2.1.259 之前,网关会拒绝 cli 块中的任何 MCP 服务器定义。
Claude Desktop 叠加层
如果您的组织还部署了 Claude Desktop,同一个网关可以同时为两个客户端提供服务。在 Claude Desktop 的托管配置中,将bootstrapUrl 指向 <listen.public_url>/user/bootstrap。Claude Desktop 从该 URL 派生 OAuth 颁发者,针对此网关运行相同的设备代码登录,并从响应中获取其配置。
要求网关服务器上的 Claude Code 为 v2.1.203 或更高版本,并且需要显式选择加入:除非与用户匹配的策略带有
desktop 键,否则 /user/bootstrap 返回 404。空的 desktop: {} 即可让策略选择加入,而 match: {} 基础层上的 desktop 键会让所有继承它的策略选择加入。审计日志会将每个请求记录为 desktop_bootstrap.serve 或 desktop_bootstrap.denied。desktop;此时网关会对每个用户从 /user/bootstrap 返回 404。
网关为 Claude Desktop 派生的设置
网关从匹配策略的cli 或 code 块以及顶层网关配置派生出 bootstrap 响应的大部分内容:
-
模型列表,来自
availableModels。该列表不包含策略通过deniedModels或availableModelsMatch: exact阻止的模型。此筛选要求网关服务器上的 Claude Code 为 v2.1.299 或更高版本。Claude Desktop 中的扩展上下文介绍了每个模型的 1M 上下文选项 -
禁用的工具,来自仅包含工具名称的
permissions.deny条目。如果您在策略的desktop块中设置了disabledBuiltinTools,网关会提供您的值与派生列表的并集,因此您可以通过这种方式禁用更多工具,但无法重新启用通过permissions.deny禁用的工具 -
出站允许列表,来自
sandbox.network.allowedDomains。如果您在策略的desktop块中设置了coworkEgressAllowedHosts,网关会使用该值代替派生列表。如果网关提供的允许列表包含*,且网关未同时提供 Claude Desktop 的allowedWorkspaceFolders,Claude Desktop 不会在 Code 选项卡中启用 Bash 沙箱 -
一个指向网关自身的 OTLP 端点,以及已登录用户的身份属性。网关会将其在该端点收到的导出数据转发到您的
forward_to目标。当您同时设置telemetry.forward_to和listen.public_url时,网关会包含该端点和这些属性。 Claude Desktop 使用一种编码导出所有信号:http/protobuf;如果您在策略的env中将OTEL_EXPORTER_OTLP_PROTOCOL或其按信号的变体之一设置为http/json,则使用http/json。在网关服务器上的 Claude Code v2.1.261 之前,响应始终设置为http/json,因此仅接受 protobuf 的收集器会拒绝 Claude Desktop 的导出
desktop 块中设置 disabledBuiltinTools、coworkEgressAllowedHosts 或 Claude Desktop 自己的 managedMcpServers 设置,网关服务器上需要 Claude Code v2.1.232 或更高版本。Claude Desktop 的 managedMcpServers 接受数组值而不是对象。
网关会从 bootstrap 响应中省略没有 Claude Desktop 对应项的键,例如 hooks 以及像 Bash(npm *) 这样的限定范围权限规则。
在 Code 选项卡中应用 code 设置
当以下所有条件都满足时,策略在其 code 键下保存的 Claude Code 设置会在 Claude Desktop 的 Code 选项卡中生效:
- 策略还带有
desktop键,空的desktop: {}也算 - Claude Desktop 为 2.9939.2 或更高版本
- 机器上的 Claude Code 托管设置指定了此网关
- 该机器通过私有网络上的 HTTPS 访问网关
cli 重命名为 code 之前,请先将客户端托管设置部署到这些机器。当前两个条件满足而后两个条件之一不满足时,策略匹配的用户会得到以下结果之一:
- 通过 HTTPS,且 Claude Desktop 捆绑了 Claude Code v2.1.296 或更高版本:Code 选项卡不会启动,对用户提示词的回复会说明原因
- 通过 HTTPS,且 Claude Desktop 捆绑了更早的版本:Code 选项卡启动但不带您的
code设置,会话中也没有任何提示 - 通过普通 HTTP:无论 Claude Desktop 捆绑哪个版本,Code 选项卡都会启动但不带您的
code设置
/managed/settings 时,Code 选项卡同样会启动但不带您的 code 设置,即使在满足全部四个条件的机器上也是如此。
在带有 desktop 键的策略中,包含设置的 code 块会在 Cowork、Chat 和 Code 选项卡中关闭 WebSearch 工具。关于 MCP 服务器,请参阅 managedMcpServers 的适用范围。
直接设置 Claude Desktop 设置
在cli 旁边添加可选的 desktop 块,即可直接设置 Claude Desktop 设置。以扁平键名写入 Claude Desktop 托管配置参考中的设置。请省略 Claude Desktop 仅从 MDM 或本地文件读取的键,例如 bootstrapUrl;网关会在启动时拒绝它们。
此示例为 eng-contractors 组在其 cli 设置旁设置了三个 Claude Desktop 键:
网关在启动时拒绝的内容
网关在启动时根据 Claude Desktop 自身使用的配置 schema 验证每个desktop 块,因此错误会在网关启动时以指明该键的错误形式暴露出来,而不会传递到每个已连接的桌面客户端。当块中包含以下内容时,网关会在启动时失败:
- 未知的键
- 已识别的键,但其值会被 Claude Desktop 拒绝或静默丢弃,例如空值或嵌套条目中拼写错误的子键。在 v2.1.260 之前,对于
managedMcpServers或orgPluginSettings条目的嵌套对象中拼写错误的字段,网关会静默丢弃,而不是在启动时失败。 - 由网关自行计算的键:推理连接、模型列表和 OTLP 中继。请通过
upstreams、models以及telemetry部分的forward_to配置这些内容。 - 当前键的旧版别名。在启动错误中,网关会指明应写入的规范键。
transport 的 managedMcpServers 条目,网关会启动并记录一条指明替代项的警告。
在 v2.1.232 之前,网关只接受由 11 个功能开关键组成的固定列表(例如 chatTabEnabled 和 disableAutoUpdates),并在启动时拒绝其他所有键。在 v2.1.227 之前,网关还会在启动时拒绝 chatTabEnabled 和 chatAdvancedFileAnalysisEnabled。
需要更新的网关或 Claude Desktop 版本的键
网关根据其已安装版本捆绑的 schema 验证desktop 块,与验证 cli 块的方式相同。要交付由较新 Claude Desktop 版本引入的设置,请先升级网关。例如,userPluginMarketplacesEnabled 和 userPluginUploadsEnabled 需要网关服务器上的 Claude Code v2.1.260 或更高版本,以及成员机器上的 Claude Desktop 1.37937.0 或更高版本。
blockReadsOutsideWorkingDirectories、disableBypassPermissionsMode、configRecheckIntervalMinutes 和 sshClientPath 需要网关服务器上的 Claude Code v2.1.281 或更高版本。microsoftAuthBroker 的 required 值以及 Microsoft 365 managedMcpServers 条目的 continuousAccessEvaluation 字段也是如此。早于 required 值的 Claude Desktop 版本会将其读取为 disabled,因此请仅在每位成员的 Claude Desktop 都支持后再设置 required。Claude Desktop 的托管配置参考列出了首次读取每个键的版本。
sshTransport 需要网关服务器上为 Claude Code v2.1.293 或更高版本。desktop 块中设置了 orgPluginSettings,网关会以 Claude Desktop 1.15200.0 及更高版本读取的数组形式提供它。较旧的桌面客户端会忽略该数组且不执行任何插件工具策略,因此在依赖它之前,请将成员更新到 1.15200.0 或更高版本。
角色策略如何继承基础 desktop 块
对于策略的 desktop 块未设置的键,网关会从 match: {} 兜底策略的 desktop 块中补充,方式与从基础层补充策略的 cli 块相同。如果您在基础层和角色策略中都设置了 disabledBuiltinTools 或 builtinToolPolicy,网关会保留基础层的限制:
disabledBuiltinTools:网关使用基础层列表与策略列表的并集builtinToolPolicy:如果您在基础层中将某个工具设置为allow以外的值,即使您在角色策略中为同一工具设置了allow,网关也会保留该值
banner),因此如果您在角色策略中设置了 banner.text,网关会丢弃基础层的 banner.backgroundColor。
策略更改何时到达 Claude Desktop
使用更改后的策略重新部署网关后,Claude Desktop 大多数设置仅在下次启动时应用:- 已关闭:Claude Desktop 在启动时获取 bootstrap 响应,因此更改从下次启动开始生效
- 已打开:Claude Desktop 默认每 10 分钟检查一次响应是否有更改,并在无需重启的情况下应用少数设置。对于其余设置,例如
skillCreationEnabled,用户会在侧边栏中看到 Relaunch Claude Desktop 卡片,并在重启应用之前保留之前的配置。默认 24 小时后,Claude Desktop 会显示重启对话框,并在 2 分钟无操作后自行重启
desktop 块中设置 relaunchEnforcementHours。网关服务器上需要 Claude Code v2.1.260 或更高版本,成员机器上需要 Claude Desktop 1.40609.0 或更高版本。设置为 0 时,Claude Desktop 一发现更改就会显示对话框。
Claude Desktop 中的扩展上下文
如果您通过网关提供 Claude Desktop,其模型选择器会为每个可以使用 1M 上下文窗口运行的已列出模型提供 1M 上下文选项。这些模型包括 Claude Opus 4.6 及更高版本、Claude Sonnet 4.6 及更高版本以及 Fable 模型。该选项即模型的[1m] 变体,扩展上下文对此有介绍。网关服务器上需要 Claude Code v2.1.284 或更高版本。
在以下情况下,models 条目不会获得 1M 选项:
- 可以为该条目提供服务的某个上游将其映射到不支持 1M 的模型,包括网关仅在故障转移时才访问的上游
- 其
id和任何upstream_model值都没有指定 Claude 模型,例如路由到应用程序推理配置文件 ARN 的自定义别名
- 让用户从 1M 选项开始:在策略的
desktop块中设置modelPrefer1mContext: true。当第一个列出的模型具有 1M 选项时,尚未选择模型的用户会从该 1M 选项开始。已经选择模型的用户保留其选择。 - 手动提供该选项:如果您的网关服务器运行的版本早于 v2.1.284,或某个条目未指定 Claude 模型,请使用此方式。在
models中将该模型列出两次,一次使用其普通 ID,一次附加[1m],两者使用相同的upstream_model映射。Claude Desktop 会将这一对显示为一个带有 1M 选项的模型。网关提供[1m]条目时不会对其进行检查,因此请仅为上游以 1M 提供服务的模型添加此类条目。
移除 1M 选项
要从选择器中移除该选项,请在策略cli 键下的 env 块中设置 CLAUDE_CODE_DISABLE_1M_CONTEXT: "1"。如果您还列出了 id 以 [1m] 结尾的条目,网关仍会提供它,因此也请删除该条目。
该变量也会传递到策略匹配的开发者的终端会话。有关它在那里的作用,请参阅扩展上下文。
与其他托管来源的优先级
如果设备还有通过 MDM 交付的策略或本地managed-settings.json,则网关交付的设置优先级最高。托管设置页面上的托管层级内的优先级说明了本地来源何时生效,并列出了 Claude Code 从每个管理员来源读取的键(无论它选择了哪个来源),例如沙箱锁定键、forceRemoteSettingsRefresh 以及按变量的 env 合并。在 MDM 配置文件或托管设置文件中配置的 policyHelper 仅在网关未交付任何设置时运行;该条目说明了其输出会替换哪些内容。
Claude Desktop 等嵌入宿主可以通过 SDK 的 managedSettings 选项提供策略。来自嵌入宿主的父级设置说明了 Claude Code 何时应用它,限制父级设置列出了在没有 allowManaged*Only 锁定时仍然适用的放宽方向设置。
网关策略适用于机器上的每次 Claude Code 调用,包括非交互式 claude -p 运行以及由 Agent SDK 生成的会话。如果启动时网关不可达,已登录的会话会以错误退出,而不是在没有其策略的情况下运行。
telemetry
CLI 将指标、日志以及(启用时的)追踪发送到网关,网关将它们原样转发到每个已配置的目标。导出使用基于 HTTP 的 OpenTelemetry Protocol(OTLP)。要跳过中继并让会话直接导出到您的收集器,请在策略中指定收集器。有关 CLI 发出的指标和事件,请参阅监控使用情况。
在通过 /login 登录的会话中,CLI 会在每次导出中标注已通过身份验证的用户身份,该身份从网关签发的 JWT 中读取:user.id、user.email 和 user.groups 属性。因此,按开发者的成本和使用情况归因无需开发者端进行任何配置。Claude Code 在开发者登录之前记录的事件不带有此身份。要了解开发者的组发生变化时哪个属性会随之变化,请参阅会话打开期间的组变化。
通过网关登录的 Claude Desktop 和 Cowork 会话会在其遥测中同时标注 user.email、user.groups 和 enduser.id,因此您可以通过对 user.email 或 user.groups 进行一次查询来涵盖终端、Desktop 和 Cowork 的使用情况。user.groups 是以逗号分隔的 IdP 组列表。
Desktop 和 Cowork 遥测还带有 enduser.sub,即您的身份提供商为该用户签发的 sub 声明,它在用户电子邮件更改时保持不变。终端会话在 user.id 下标注相同的值,因此将 enduser.sub 与终端 user.id 匹配的查询可以同时涵盖一个用户的终端、Desktop 和 Cowork 使用情况。在 Desktop 和 Cowork 导出中,user.id 是一个匿名标识符,而不是主体。
与 Claude Code 的所有 OpenTelemetry 数据一样,这些属性只会发送到您的组织配置的目标,绝不会发送给 Anthropic。
如果用户的组列表经百分比编码后超过 255 个字符,或者某个组名包含逗号或等号,网关会在该用户的 Desktop 和 Cowork 遥测中省略 user.groups,而不是将其截断。该用户的终端会话仍带有完整列表。
当主体经百分比编码后超过 255 个字符,或者包含空格、可打印 ASCII 之外的字符,或 , ; = \ " % 之一时,网关会省略 enduser.sub。该用户的 Desktop 和 Cowork 遥测会保留其其他属性。
要在 Desktop 和 Cowork 遥测中包含 user.email 和 user.groups,网关服务器上需要 Claude Code v2.1.265 或更高版本;要包含 user.groups,每位开发者的机器上还需要 Claude Desktop 1.24012 或更高版本。
要包含 enduser.sub,网关服务器上需要 Claude Code v2.1.274 或更高版本。
forward_to URL 必须使用 https://,但位于网关自身回环接口上的收集器是一个例外:
http://localhost:<port>可以通过配置验证,但除非您在网关的环境中设置了CLAUDE_GATEWAY_ALLOW_LOOPBACK=1,否则 SSRF 防护会以ECONNREFUSED_SSRF阻止每次导出- 除非设置了该变量,否则
http://127.0.0.1:<port>或http://[::1]:<port>会导致启动失败
HTTPS_PROXY 时,网关会通过该代理发送导出数据。
要直接访问内部收集器,请将其按主机名或以带前导点的域(例如 .internal.example.com)添加到 NO_PROXY,这要求网关服务器上的 Claude Code 为 v2.1.277 或更高版本。请确保网关可以不经代理访问该收集器。不带前导点的条目只匹配该确切名称,不匹配其下级名称。CIDR 范围不会匹配。
启用仅代理出站时,请改为在代理中允许该收集器,因为任何 NO_PROXY 条目都会使仅代理出站保持关闭。
CLI 中的遥测默认处于关闭状态。当您同时设置 telemetry.forward_to 和 listen.public_url 时,网关会通过 /managed/settings 推送六个环境变量,为已连接的客户端启用遥测:
CLAUDE_CODE_ENABLE_TELEMETRY=1OTEL_METRICS_EXPORTER、OTEL_LOGS_EXPORTER和OTEL_TRACES_EXPORTER,如果至少一个forward_to目标启用了该信号,则各自设置为otlp,否则设置为noneOTEL_EXPORTER_OTLP_ENDPOINT=<public_url>OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
OTEL_RESOURCE_ATTRIBUTES。
在网关服务器上的 Claude Code v2.1.265 之前,网关会将全部三个导出器选择器都推送为 otlp,包括没有任何目标选择加入的信号。
推送的端点由公共 URL 构建,因此指标和日志不需要开发者或策略进行任何 OTEL 配置。
通过 /login 登录的开发者无法使用自己的 OTEL 配置重定向导出:
- 本地设置的变量:Claude Code 在托管层级应用推送的变量,因此每个变量都会覆盖开发者在本地为其设置的值。
- 本地配置的端点:启用 OTLP/HTTP 导出后,无论网关是否推送了遥测变量,CLI 都会忽略任何本地配置的端点。除非策略将您的收集器指定为端点,否则其导出会发送到网关。
forward_to 目标,网关会接受并丢弃它。如果开发者已经将 Claude Code 遥测导出到您的某个收集器,请将其添加为 forward_to 目标(如果他们导出日志或追踪,则启用相应信号),以便在他们登录后该收集器继续接收其数据。要改为跳过中继,请在策略中指定收集器。
追踪还要求每个客户端上设置 CLAUDE_CODE_ENHANCED_TELEMETRY_BETA=1。请在托管策略的 env 块中设置它,因为网关不会推送它。开发者会在推送的端点已触发的同一安全批准对话框中批准它。
请仅在您希望追踪其组的策略中将其设置为 1。根据合并规则,未设置它的策略会从您的 match: {} 兜底策略继承该值(如果兜底策略设置了它)。要让某个组的客户端即使在开发者本地设置了该变量时也不发送追踪,请在该组的策略中将其设置为 0。
protobuf 和 JSON 两种 OTLP 编码都会被转发,任何兼容 OpenTelemetry 的后端都可以用作目标。
发送累积指标
如果您的收集器只接受累积指标,请将OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE 设置为 cumulative。Claude Code 默认发送增量指标,网关转发它们时不会进行转换。请在每种会话读取该变量的位置设置它:
- 终端会话:在策略的
cli或code键下的env块中 - 在用户机器上运行的 Cowork 会话:在该机器上客户端托管设置的
env块中 code策略下的 Code 选项卡会话:在满足code设置生效的条件后,在策略的env块中cli策略下的 Code 选项卡会话:在运行该会话的机器上客户端托管设置的env块中。通过 SSH 时,那是远程主机。
parentSettingsBehavior: "merge"。否则,Cowork 会话和 cli 策略下的 Code 选项卡会话在运行时将不带有 Claude Desktop 作为父级设置传递给它们的出站允许列表和其他策略。
添加自己的标签
要在通过网关登录的会话的遥测上添加固定标签,例如service.namespace 或 deployment.environment.name,请设置 telemetry.resource_attributes。每个标签都是一个 OpenTelemetry 资源属性,每个目标都会收到相同的标签。
仅当您同时设置 telemetry.forward_to 和 listen.public_url 时,会话才会获得这些标签。此示例添加了两个标签:
- 名称只能使用字母、数字、
.、_和- - 名称不能是保留名称。保留名称不区分大小写进行比较,包括所有以
user.、enduser.或identity.开头的名称,以及service.name、service.version、claude.deployment_mode、host.arch、os.type、os.version和wsl.version - 值为非空的可打印 ASCII,不含空格,也不含
, ; = \ " %中的任何字符 - 值在网关按百分比编码后计数时最多 255 个字符,因此
/、:和@各计为三个字符 - 值为文本,因此请为数字、
true或false加引号
telemetry.resource_attributes,网关服务器上需要 Claude Code v2.1.281 或更高版本。更早的网关发现该键时会拒绝启动。请在添加该键之前升级每个副本,并在回滚到更早版本之前移除该键。
通过 /login 登录的终端会话会以 OTEL_RESOURCE_ATTRIBUTES 的形式接收标签,与其他遥测变量一起推送。如果您在策略的 env 块中设置了 OTEL_RESOURCE_ATTRIBUTES,该策略匹配的终端会话会获得该值而不是这些标签。Claude Desktop 从网关接收标签,同时接收 user.email 和其他身份属性。
Claude Code 还会将每个标签复制到每个指标数据点上,因此您可以在不索引资源属性的后端中按标签筛选指标。要关闭此复制,请参阅指标基数控制。
会话打开期间的组变化
终端会话将user.groups 放在 OTLP 资源上,并再次放在每个指标数据点和事件上。如果开发者的组在会话打开期间发生变化,下一次静默刷新之后的使用情况所对应的数据点和事件会带有新的组。资源会保留旧的组,直到开发者重启 Claude Code,因此请按数据点或事件上的属性进行分组。
如果您在 OpenTelemetry Collector 的 Prometheus remote write 导出器中启用了 resource_to_telemetry_conversion,该导出器会用资源上的值替换每个数据点的 user.groups,因此每个数据点都会显示旧的组。要保留数据点上的值,请在该导出器之前从资源中删除 user.groups。
此 OpenTelemetry Collector resource 处理器会在列出它的管道中删除该属性:
resource/drop-user-groups 添加到指标管道的 processors 之后,每个序列都会带有来自其自身数据点的 user_groups 标签。
直接导出到您的收集器
要让通过/login 登录的会话将遥测直接发送到您的收集器而不经过中继,请在托管策略的 env 块中将 OTEL_EXPORTER_OTLP_ENDPOINT 设置为收集器的 https:// 基础 URL。Claude Code 会在您设置的 URL(例如 https://otel-collector.example.com:4318)后附加 /v1/metrics、/v1/logs 或 /v1/traces,并通过 OTLP/HTTP 将每个信号导出到那里。要求每位开发者机器上的 Claude Code 为 v2.1.265 或更高版本。更早的客户端通过中继导出。
要向收集器进行身份验证,请在同一 env 块中设置 OTEL_EXPORTER_OTLP_HEADERS。会话永远不会将开发者的网关会话令牌发送到以这种方式指定的收集器。
当您在策略中添加或更改此端点时,Claude Code 会在交互式会话中应用它之前,要求每位开发者在安全批准对话框中批准它。
Claude Code 在直接导出信号之前会检查端点,检查失败时该信号会保留在中继上。检查包括:
- 端点来自网关本身。如果您在 MDM 配置文件或本地
managed-settings.json中设置了同一变量,导出会保留在中继上。 - URL 使用
https://,或使用指向回环地址的http:// - URL 解析为以
/v1/<signal>结尾的路径,且不带查询或片段。Claude Code 会根据通用变量自行构建该路径。对于按信号的变量(例如OTEL_EXPORTER_OTLP_METRICS_ENDPOINT),它会按原样使用,因此请在其中包含完整路径。 - URL 不是网关自己的主机。指向网关的端点会保留中继路径及其会话令牌。
- 您和开发者都未在任何设置来源中配置
otelHeadersHelper。配置了该辅助程序时,每个信号都会保留在中继上。
OTEL_*_EXPORTER 选择器决定哪些信号要导出。
仅设置端点并不会启用导出,因此还需设置启用导出的变量,除非网关已经推送了它们:
- 如果网关已经推送了遥测变量,它们涵盖启用、选择器和协议,您显式设置的端点会覆盖推送的
<public_url>值。仅对没有任何forward_to目标启用的信号,才需要您自行将OTEL_*_EXPORTER选择器设置为otlp。 - 如果网关没有推送,还需设置
CLAUDE_CODE_ENABLE_TELEMETRY=1、OTEL_*_EXPORTER选择器和OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf。
目标失败时
网关不会缓冲、重试或存储遥测,因此对于未能到达目标的导出,它会将其丢弃,而不是延迟交付。每个目标独立成功或失败,并且无论哪种情况,导出的客户端都会收到成功响应,因此交付失败只会出现在网关的日志中。 向某个目标连续五次交付失败后,网关会以 30 秒为间隔暂停向其转发,并记录每次暂停,直到某次交付成功。任何错误响应、超时或连接错误都计为交付失败,但400、413、415、422 和 431 除外,这些表示收集器因负载格式错误或过大而拒绝了该次导出。
被拒绝的负载既不会增加也不会重置失败计数:网关会继续向该目标转发,并在该目标第一次拒绝时以及此后每第一百次拒绝时,记录一条指明该目标和状态的警告。
HTTP 调优
四个可选的顶层块access_control、limits、timeouts 和 rate_limits 用于调优 HTTP 层面的行为。默认值适用于大多数部署。
如果两个
access_control 列表都留空(即默认情况),网关会为任何客户端地址提供服务,因此只有您的网络能限制谁可以访问它。这一点很重要,因为网关可以推送在开发者机器上运行命令的托管设置。
当 allow_cidrs 为空时,网关会在两个地方发出警告,但不会改变其响应任何请求的方式:
- 启动时:运行日志中的一条警告建议仅允许私有地址段
10.0.0.0/8、172.16.0.0/12、192.168.0.0/16、100.64.0.0/10、127.0.0.0/8、::1/128和fc00::/7,以及开发者连接所用的其他内部地址段。如果将网关绑定到环回地址,并且既未设置trusted_proxies也未设置public_url(如本地开发时),则不会出现该警告。 - 运行时:当首次有请求来自这些私有地址段之外的地址时,网关会记录一条警告,并发出一个携带客户端 IP 的
access.public_client审计事件。两者在每个进程中各触发一次。链路本地地址169.254.0.0/16和fe80::/10不算作公网地址。网关会在此检查运行之前响应/healthz和/readyz,因此来自公网地址段的健康探测不会触发它。
listen.trusted_proxies 中,网关看到的将是中继的地址(通常是私有地址),因此运行时警告和私有允许列表都无法捕获经由它中继的流量。
如果该中转方应列入 listen.trusted_proxies,请将其列入。无论如何,都应确保网关及其前面的所有组件无法从公共互联网访问。
load_test_mode
load_test_mode 块可让您在不调用模型提供商的情况下对网关进行负载测试。启用后,网关会照常构建并签名每个提供商请求,但将其丢弃而不发送,并通过其正常的响应路径以流式方式返回一条预设回复。该回复是填充文本,开头有一句话说明它是预设的。
要求网关服务器上运行 Claude Code v2.1.282 或更高版本。更早版本的网关在发现该键时会拒绝启动。请在添加该块之前升级每个副本,并在回滚之前移除该块。
以下示例使用默认值启用该模式,即约 750 个 token 的文本回复,在约 10 秒内以流式传输:
在此模式下的负载测试涵盖网关、您的 Postgres 以及网关前面的所有组件。它不涵盖提供商的限制、速度和网络路径,也不涵盖每个副本在并发上游请求限制处的等待。当打开的请求数超过该限制(即生产请求开始等待的临界点)时,副本仍会记录
client requests are open 警告。
由于不会向提供商发送模型请求,副本每个请求的 CPU 用量只是估算值,且读数低于生产环境,因为生产环境还需要加密发往提供商的流量。请针对真实提供商进行小规模试点,以确认副本数量。在 v2.1.283 之前,该估算值读数会低得多。
启用该模式时,请求可以携带一个 x-load-test-user 请求头,其值为最多七位数的整数。网关会将每个数字计为一名独立的开发者,并使用随请求附带的令牌所属开发者的电子邮件和组。
请为负载测试部署提供单独的空数据库,因为如果数据库中已有任何开发者产生过花费,网关在启用该模式时会拒绝启动。
完整示例
此完整参考配置演示了每个核心部分;HTTP 调整块保持其默认值。复制它,删除您不需要的,并填入您的值。快速入门中的配置是此的最小版本。gateway.yaml
客户端托管设置
上面的所有内容配置网关服务器。将开发者机器指向网关是在每个设备上单独配置的,通过 Claude Code 的托管设置。网关无法自己推送登录密钥,因为这些密钥是告诉客户端网关在哪里的内容。 对于 CLI,在每个 OS 的managed-settings.json 中设置这些密钥。这两个登录密钥将每个开发者的 /login 路由到你的网关:
parentSettingsBehavior: "merge" 保持 Claude Desktop 向其嵌入式 Claude Code 会话传递出站允许列表的功能;向 Claude Desktop 会话传递策略解释了该机制以及选择加入必须位于的位置。
为了防止开发者通过云提供商变量或他们自己的 ANTHROPIC_BASE_URL 绕过网关,请在同一文件中添加 "allowedProviders": ["gateway"]。Claude Code 随后会拒绝机器上未设置为云网关的每个会话,并仅允许网关在它是 forceLoginGatewayUrl 命名的网关或文件的 env 块将其 URL 设置为 ANTHROPIC_BASE_URL 的网关时。claude gateway 拒绝在设置该列表的机器上运行,因此请在网关主机上保持该密钥关闭。请参阅设置参考中的 allowedProviders 条目。需要 Claude Code v2.1.285 或更高版本。
将 managed-settings.json 文件部署到每个设备,通常通过你的 MDM 平台。文件路径因平台而异。请参阅每个机制存储策略的位置。
默认情况下,Windows 上的注册表策略或 macOS 上的托管首选项 plist 会替换 managed-settings.json 文件而不是与其合并,除了上面的例外密钥和跨源检查。此代码片段中的所有三个密钥都遵循最高优先级源规则,因此通过组策略或配置文件传递策略的团队必须改为将所有三个密钥放在该机制中。
对于 Claude Desktop,在 Claude Desktop 自己的托管配置中设置 bootstrapUrl 密钥为 <listen.public_url>/user/bootstrap。登录流程和每组策略随后与 CLI 的匹配,一旦策略通过 desktop 密钥在服务器端选择加入;没有选择加入,/user/bootstrap 返回 404。有关服务器端部分,请参阅 Claude Desktop 覆盖层。
Claude Code 从机器上的托管源读取并遵循 forceLoginGatewayUrl、gatewayInternalNetworks 和 forceLoginMethod 的 "gateway" 值:managed-settings.json、macOS plist 或 Windows HKLM 注册表,或策略助手。在网关负载中设置它们不会配置网关登录。关于开发者自己的 ~/.claude/settings.json,请参阅在用户设置中设置网关 URL。
不要在有效负载中包含 forceLoginMethod 和 forceLoginOrgUUID。Claude Code 仍然从有效负载中读取这两个密钥以进行启动凭证检查,因此在机器上保留 Anthropic 颁发的凭证的开发者会获得管理员策略需要云网关登录下描述的启动退出,即使他们已经登录。
相关
- Claude 应用网关概述:快速入门和开发者连接
- 部署指南:IdP 设置、容器镜像、Kubernetes 和 Cloud Run,以及操作
- 支出限制:每开发者上限和 Admin API