Claude apps gateway
自托管的 Claude apps gateway:SSO 登录、按组模型访问、OTLP 遥测,路由到 Bedrock、Claude Platform on AWS、Google Cloud、Foundry 或 Anthropic API;快速开始、连接开发者(含 gatewayInternalNetworks、Claude Desktop、父级设置与锁)、强制执行内容与限制。
Claude apps gateway 面向必须或倾向于经自己的云提供商路由推理的组织(例如为了满足数据驻留要求)。如果你没有这个要求,并且想要 SCIM 预配或网页与移动端 Claude Code 这样的其他功能,Claude Enterprise 可能更合适(所有部署方式的完整对比见功能可用性页)。
Claude apps gateway 是一个自托管服务,位于开发者的 Claude Code 客户端与你的模型提供商之间。开发者用你的企业身份提供商(IdP)登录,而不是持有 API key 或云凭据。网关持有上游凭据,按 IdP 组强制执行模型访问和托管设置,并把用量遥测转发到你自己的可观测性栈。它包含在 claude 二进制里,所以在笔记本上运行 Claude Code 的同一个可执行文件,用 claude gateway --config gateway.yaml 运行网关服务器。
本页涵盖:为什么用 Claude apps gateway(它比你自己运行的网关多了什么,以及什么时候别的更合适);带前提条件的快速开始,让网关从零到有一个已登录的开发者;连接开发者,包括通过托管设置设置网关 URL;可用性与限制,涵盖哪些 Claude Code 功能能经网关工作以及服务器支持什么。配套页面更深入:配置参考涵盖快速开始所写 YAML 文件里的每个选项,部署指南涵盖每个 IdP 的设置、Kubernetes 和 Cloud Run 部署以及运维。
为什么用 Claude apps gateway
网关概览讲网关做什么以及为什么要运行一个。Claude apps gateway 是 Anthropic 自己的网关,内置在 claude 二进制里,并随每个 Claude Code 发布一起测试,所以它转发 Claude Code 发送的头和请求字段,运营者不必维护单独的允许列表。部署后它给你:
- 凭据:上游 API key 或云凭据只存在于你的基础设施里。开发者用企业 SSO 认证并收到短期 bearer 令牌,所以人员离职在你的 IdP 里处理:取消预配一个用户,他们的网关访问在会话寿命(默认一小时)内过期。
- 访问控制:你的 IdP 组映射到模型允许列表和托管设置策略。网关在服务端强制执行模型访问,拒绝对未授予模型的请求,并选择每个组的托管设置策略,由 CLI 在托管设置层应用。不同的团队得到不同的模型、工具和权限,开发者无法覆盖他们的策略所锁定的内容。
- 设置交付:网关自己向已登录的客户端交付托管设置,取代 claude.ai 管理控制台的服务器托管设置。
- 遥测:每个已配置的目的地默认收到带 token 计数、模型、用户身份和延迟的 OpenTelemetry Protocol(OTLP)指标,日志和追踪按目的地选择加入。
- 上游路由:客户端对网关说 Anthropic Messages API,网关为每个上游做转换,不论是 Amazon Bedrock、Claude Platform on AWS、Google Cloud Agent Platform、Microsoft Foundry 还是 Anthropic API,并在它们之间故障转移。你可以更改区域、提供商或故障转移顺序,而开发者无需察觉或重新配置。
架构:Claude Code 客户端以及 Claude Desktop 的 Chat、Cowork 和 Code 标签页通过 HTTPS 带 bearer 令牌连接到你基础设施内的自托管 Claude apps gateway;网关对你的 IdP 做用户登录、把认证状态存在 PostgreSQL、把遥测转发给你的 OTLP 收集器,并把推理转发给 Amazon Bedrock、Claude Platform on AWS、Google Cloud、Microsoft Foundry 或 Anthropic API。
网关自己的数据平面不向 Anthropic 基础设施发送任何东西,除非 Anthropic API 是已配置的上游。你控制遥测、审计日志、托管设置和开发者的 IdP 身份去向何处,网关不把它们中的任何一个发给 Anthropic(CLI 进程还可能发送的其余流量以及如何关闭它,见「合规姿态」)。哪些 Claude Code 功能能经网关工作以及服务器本身支持什么,见下面的「可用性与限制」;成本、绕过、运行多个网关和无服务器平台这类决定,见部署指南。
其他网关实现
如果你已经运行满足需求的 LLM 网关或 API 网关,就继续使用它;「其他 LLM 网关」涵盖如何对它配置 Claude Code。网关兼容性指南记录了 Claude Code 对任何网关的期望:它调用的端点、要转发的头和请求体字段,以及它们被剥离时什么会停止工作。运行中的 Claude apps gateway 还在 GET /protocol 提供自己的协议参考,描述它向 Claude Code 客户端暴露的端点:SSO 登录、推理、托管设置交付、模型发现和遥测。可以从任何已部署的网关(如下面的快速开始产生的那个)用 curl https://claude-gateway.internal.example.com/protocol 获取它。协议的破坏性变更会提前宣布,但不保证无限期的向后兼容。
快速开始
这个快速开始走最小路径:在你的 IdP 里注册 OAuth 客户端、写一个 gateway.yaml、用 Docker Compose 把网关与 Postgres 一起运行,并端到端验证登录。它用 Amazon Bedrock 上游;Claude Platform on AWS、Google Cloud Agent Platform、Microsoft Foundry 和 Anthropic API 同样受支持,只要如配置参考所示替换 upstreams 块。结束时,你有一个开发者能 /login 的网关。
在你的私有网络上部署。 Claude Code 只连接地址为私有的网关。这是一道安全防护,因为受信任的网关可以推送在开发者机器上运行命令的设置。把网关放在内部负载均衡器或 VPN 后面,并给它一个只解析到私有 IP 的主机名。如果你的内部网络用的是你的组织拥有的公网 IPv4 空间编号,见「允许在你拥有的公网地址空间上的网关」。
前提条件
开始之前要备好这些:
| 你需要 | 细节 |
|---|---|
| Claude Code v2.1.195 或更高 | claude gateway 子命令和网关登录流程随 v2.1.195 发布,更早的公开构建不含它们。运行网关服务器的机器和每个开发者的机器都必须是 v2.1.195 或更高;运行 claude update 获取最新发布。Claude Platform on AWS 上游要求网关服务器上是 Claude Code v2.1.198 或更高 |
| OpenID Connect(OIDC)身份提供商 | Okta、Microsoft Entra ID、Google Workspace、Keycloak 或 Dex,或任何其他兼容 OIDC 的 IdP(如 PingFederate)。网关对它运行标准的 OIDC 发现和授权码流程。不支持 SAML 和 LDAP |
| PostgreSQL 14 或更高 | 支撑设备登录流程(浏览器回调写入、轮询的 CLI 读取)以及速率限制计数器。任何托管的 Postgres 都行,包括最小的层级。没有配置支出限额时,网关只存几 KB 短期的认证状态;有支出限额时,它还持有应该备份的持久的支出、审计和身份表。建议用 ?sslmode=require 启用 TLS |
| 模型上游 | Amazon Bedrock 凭据、Claude Platform on AWS 凭据、Google Cloud 凭据、Microsoft Foundry 资源或 Anthropic API key;支持带故障转移的多个上游 |
| HTTPS | 网关必须能从开发者笔记本以及用于登录的任何浏览器经 https:// 到达;网关在同一个监听器上提供设备验证页面。要么经 listen.tls 提供 TLS 证书,要么在终止 TLS 的入口后面运行,两种情况下都要把 listen.public_url 设为外部源。在 /login 处,Claude Code 只在网关主机是环回(localhost、127.0.0.1 或 ::1)时才接受纯 http:// 源 |
| 私有网络地址 | 在 /login 处,Claude Code 要求网关的主机名或 IP 地址只解析到私有地址:RFC 1918、链路本地、CGNAT 100.64.0.0/10、IPv6 ULA fc00::/7 或环回。对你托管的网关,你声明的块之外的任何公网地址都会被拒绝(见部署指南里的威胁模型)。如果开发者机器经企业代理走 HTTPS,登录还要求代理主机解析到私有地址;如果不是,把网关主机加入 NO_PROXY,使 CLI 直连。如果你的内部网络用的是你的组织拥有的公网 IPv4 空间编号,声明这些块,使 /login 接受那里的网关 |
| Linux 运行时 | 网关服务器只在原生 Linux 二进制上运行;macOS 可用于本地开发;Windows 不支持作为服务器平台 |
步骤
1. 在你的 IdP 里注册 OAuth 客户端。 先决定网关的主机名,因为重定向 URI 必须与它匹配。创建新的 OIDC web 应用并把重定向 URI 设为 https://claude-gateway.<your-domain>/oauth/callback,其中主机与你在第 3 步设为 listen.public_url 的值相同。记下 client_id 和 client_secret(每个 IdP 的说明见「身份提供商设置」)。
2. 准备 PostgreSQL 数据库。 任何 Postgres 14 或更高都行,包括最小的托管层级。网关在启动时运行自己的 schema 迁移,所以数据库角色需要创建和修改表的权限(见 store)。
3. 编写 gateway.yaml。 密钥通过 ${ENV_VAR} 展开读取,所以文件本身可以放在版本控制里。使用在你网络上解析到私有 IP 的 public_url 主机名,因为 /login 拒绝公网地址。最小配置有五个部分,其他每个字段都有默认值:
listen:
host: 0.0.0.0
port: 8080
# 除非 host 是环回地址,否则必需。用于 IdP 的
# redirect_uri 和发现文档。
public_url: https://claude-gateway.internal.example.com
oidc:
issuer: https://login.example.com # 必须提供 /.well-known/openid-configuration
client_id: 0oa1example2
client_secret: ${OIDC_CLIENT_SECRET}
allowed_email_domains: [example.com] # 拒绝你的组织之外的 id_token
userinfo_fallback: true # 用于 id_token 省略邮箱/组的 IdP;对其他无害
session:
jwt_secret: ${GATEWAY_JWT_SECRET} # openssl rand -base64 32
ttl_hours: 1 # 同时限定 IdP 取消预配时的撤销延迟
store:
postgres_url: ${GATEWAY_POSTGRES_URL} # 托管 Postgres 加 ?sslmode=require
upstreams:
- provider: bedrock
region: us-east-1
auth: {} # 空:AWS 默认凭据链
# (IRSA、EC2/ECS 任务角色、环境变量、~/.aws)
# 模型按上游自动转换。内置目录把 claude-opus-4-8 映射到
# us.anthropic.claude-opus-4-8,对每个 Bedrock 支持的 Claude 模型依此类推。
# 设为 false 并加一个 `models:` 列表可只暴露特定模型。
auto_include_builtin_models: true这份配置足以用默认的 Amazon Bedrock 模型目录得到一个可用的登录循环。运行起来之后,可以通过 managed.policies 添加按组 RBAC 和托管设置,通过 telemetry 添加遥测扇出,通过 models 添加多上游故障转移、预置吞吐量 ARN 或非美国区域。Amazon Bedrock 上游需要一个 AWS 主体,它在 inference-profile/us.anthropic.* ARN 和底层的 foundation-model/anthropic.* ARN 上都有 bedrock:InvokeModel 和 bedrock:InvokeModelWithResponseStream,还需要从 Bedrock 控制台的 Model catalog 为该账号提交过 Anthropic 的一次性用例表单。凭据要用 EKS 上的 IRSA、ECS 任务角色或 EC2 实例配置文件提供,而不是静态密钥(完整的 IAM 细节、跨云凭据矩阵以及其他提供商的 auth 块见 upstreams 参考)。
4. 运行它。 围绕满足镜像要求的 claude 二进制构建容器镜像,然后与 Postgres 一起运行。Compose 文件把镜像引用为 registry.example.com/claude-gateway:2.1.198;换成你自己的仓库和镜像标签:
services:
gateway:
image: registry.example.com/claude-gateway:2.1.198
ports: ["8080:8080"]
volumes: ["./gateway.yaml:/etc/claude/gateway.yaml:ro"]
environment:
OIDC_CLIENT_SECRET: ${OIDC_CLIENT_SECRET}
GATEWAY_JWT_SECRET: ${GATEWAY_JWT_SECRET}
GATEWAY_POSTGRES_URL: postgres://gw:pw@postgres/gateway
# AWS 凭据:生产里省略这些并使用实例角色。
# 本地 Compose 测试时,传入你自己的:
AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}
AWS_SESSION_TOKEN: ${AWS_SESSION_TOKEN}
depends_on:
postgres:
condition: service_healthy
postgres:
image: postgres:16-alpine
environment: { POSTGRES_USER: gw, POSTGRES_PASSWORD: pw, POSTGRES_DB: gateway }
healthcheck:
test: ["CMD-SHELL", "pg_isready -U gw"]
interval: 5s
volumes: ["pgdata:/var/lib/postgresql/data"]
volumes: { pgdata: }网关是单个 Linux 二进制:它读取配置、连接 Postgres 并应用 schema 迁移、对你的 IdP 运行 OIDC 发现、构建上游客户端,然后开始监听。启动对配置、Postgres 连接、OIDC 发现和上游客户端构造都是失败关闭的:如果其中任何一个不可达或配置错误,网关会带着错误退出,而不是以降级状态提供流量。成功启动并不验证推理路径,因为 Amazon Bedrock 和 Google Cloud Agent Platform 的实例凭据在第一个请求而不是启动时解析。
观察 stderr 里的启动序列。日志行格式为 [gateway] <timestamp> <level> <message>,审计事件是带 evt 字段的单行 JSON,迁移行与监听行之间会打印一个下面省略的启动横幅。全新的数据库对每个 schema 迁移打印一行 migration N applied,已迁移的数据库不打印。你应该按顺序看到:
{"ts":"2026-06-10T17:03:21.114Z","evt":"config.load","path":"/etc/claude/gateway.yaml","sha256":"…"}
[gateway] 2026-06-10T17:03:21.395Z info waiting for migration lock (another replica may be migrating; check pg_locks for key 6775156 if this persists)
[gateway] 2026-06-10T17:03:21.408Z info migration 1 applied
…
[gateway] 2026-06-10T17:03:21.431Z info migration 6 applied
[gateway] 2026-06-10T17:03:21.512Z info claude gateway listening on http://0.0.0.0:8080网关还会记录一条 access_control.allow_cidrs 为空的警告。这里这是预期的,因为在你设置允许列表之前,没有东西限制网关为哪些客户端地址服务(推荐的范围见 access_control 参考)。如果启动在 claude gateway listening on 行之前退出,stderr 的最后一行点名问题:不可达的 Postgres;没有 DDL 权限的 Postgres 角色;不可达或无效的 OIDC 发现文档;带有问题字段路径的配置 schema 违规。修复后重启。如果你已有终止 TLS 的入口,跳过 Compose,直接用 claude gateway --config gateway.yaml 运行二进制,把 public_url 设为入口的源,并把 listen 绑定到环回或集群内部地址。
5. 验证认证面。 在把网关分享给开发者之前,有三个检查确认它能认证真实用户。例子使用网关的公开 URL;对没有入口的本地 Compose 设置,在前两个检查里换成 http://localhost:8080。第三个检查打开 verification_uri_complete,它由 public_url 构建,所以对本地 Compose,要在 gateway.yaml 里设 public_url: http://localhost:8080,并把 http://localhost:8080/oauth/callback 添加为第 1 步 OAuth 客户端的第二个重定向 URI(因为网关用 public_url 构建 IdP 的 redirect_uri);验证链接随后在你本地浏览器里打开。在 Windows PowerShell 里运行 curl.exe:裸的 curl 是 Invoke-WebRequest 的别名,会拒绝这些标志。
第一,获取发现文档,它确认网关已启动、配置有效且所有启动检查都通过:
curl -s https://claude-gateway.internal.example.com/.well-known/oauth-authorization-server | jq{
"issuer": "https://claude-gateway.internal.example.com",
"device_authorization_endpoint": "…/oauth/device_authorization",
"token_endpoint": "…/oauth/token",
"grant_types_supported": ["urn:ietf:params:oauth:grant-type:device_code", "refresh_token"]
}响应还包含其他字段,如 response_types_supported 和 scopes_supported。第二,请求设备授权,它确认设备登录流程可用、Postgres 可达且可写:
curl -s -X POST https://claude-gateway.internal.example.com/oauth/device_authorization | jq{
"device_code": "…",
"user_code": "WDJB-MJHT",
"verification_uri": "https://claude-gateway.internal.example.com/device",
"verification_uri_complete": "https://claude-gateway.internal.example.com/device?user_code=WDJB-MJHT",
"expires_in": 600,
"interval": 5
}第三,通过在浏览器里打开 verification_uri_complete 并确认代码来测试浏览器这一段:你应该被重定向到 IdP 的登录页,登录后回到网关并看到已登录的确认。用第一个失败的检查来定位问题:第一个检查失败——启动没有完成,检查 stderr;第二个检查失败——Postgres 从网关不可达或角色无法写入,检查连接串和授权;第三个检查没有到达 IdP——检查 IdP 的重定向 URI 与 https://<gateway>/oauth/callback 完全匹配;第三个检查到达 IdP 但带着错误弹回——读网关的审计日志,它记录每次认证拒绝及原因,如 email domain not allowed。
6. 让开发者登录。 最后一步在开发者机器上进行,而不是服务器。在该机器的托管设置文件里把 forceLoginMethod 设为 "gateway"、forceLoginGatewayUrl 设为网关的 public_url,然后运行 /login,在 Cloud gateway 屏幕上按 Enter 并完成浏览器登录(把这两个键分发到每台开发者机器见下面的「设置网关 URL」)。
连接开发者
开发者从自己的笔记本用一次浏览器登录连接,使用他们的企业工作账号。他们不需要 claude.ai 账号、API key 或订阅,因为对模型的请求用组织的上游凭据经网关发出。连接由你经 MDM 推送的客户端托管设置驱动,所以开发者这边没有手动设置;本节涵盖管理员要配置什么。
CLI 在首次连接时对网关的 TLS 叶证书取指纹,并按主机名固定它。它在登录期间、静默会话刷新时和托管设置获取时再次检查该固定值,而推理请求使用不带该固定值的标准 TLS 验证;经 HTTPS 代理路由的请求跳过固定检查,所以把网关主机加入 NO_PROXY 使它们保持直连。把预期的 SHA-256 指纹与网关 URL 一起发布,让开发者有东西可以比对。/login 提示显示指纹的前 16 个字符,小写十六进制、不带冒号。要从证书文件打印该形式的完整指纹,运行:
openssl x509 -noout -fingerprint -sha256 -in cert.pem | cut -d= -f2 | tr -d : | tr 'A-F' 'a-f'证书轮换时,每个开发者都会再次看到信任提示,所以要把轮换当作有计划的事件,并重新发布指纹。如果你的网关策略含需要批准的设置,开发者在接受新证书之后还会再次看到该批准对话框,因为 Claude Code 把批准记忆与固定的证书关联。网关可以在令牌响应里返回可选的 email 字段,指明某次登录使用的账号;返回时,开发者在 Claude Code 保存凭据之前确认该账号,确认过的登录之后,/status 显示该账号。该确认需要开发者机器上是 Claude Code v2.1.275 或更高,低于该版本的客户端忽略该字段;claude 二进制里的网关服务器不返回该字段,所以它的登录无需确认就完成。开发者登录后,模型选择器显示他们 availableModels 允许列表里的模型。托管设置在启动时应用并每小时刷新,遥测路由到你的收集器。会话在 ttl_hours 到期之前静默刷新;IdP 取消预配之后刷新失败时,Claude Code 提示开发者重新登录。
设置网关 URL
三个键放进你经 MDM 或直接在磁盘上部署的每个操作系统的托管设置文件里。forceLoginMethod 和 forceLoginGatewayUrl 让 /login 直接打开 Cloud gateway 屏幕并填好 URL,parentSettingsBehavior: "merge" 让 Claude Desktop 把网关的出口允许列表交付给它启动的 Claude Code 会话(见「向 Claude Desktop 会话交付策略」):
{
"forceLoginMethod": "gateway",
"forceLoginGatewayUrl": "https://claude-gateway.internal.example.com",
"parentSettingsBehavior": "merge"
}开发者按 Enter 连接,首次连接的 TLS 指纹提示仍会出现。文件到达机器之后,没有完成网关登录的开发者会看到「管理员策略要求 Cloud 网关登录」下描述的消息之一。通过 CLAUDE_CODE_USE_BEDROCK 这样的环境变量选择云提供商的开发者不需要网关登录。开发者无法手动设置它:登录选择器里没有网关选项,开发者自己的设置文件里的 forceLoginGatewayUrl 被忽略;只有 forceLoginMethod 而没有 URL,会让开发者停在 "Contact your IT administrator" 消息上。登录键属于你推送到机器上的文件,不属于网关的 managed.policies[].cli 块,后者只到达已经连接的客户端。
允许在你拥有的公网地址空间上的网关
有些组织用自己拥有的公网 IPv4 块(如运营商自己的地址空间或遗留的 /8)给内部网络编号,所以它们的网关不能有私有地址。把这些块列在 gatewayInternalNetworks 托管设置里;/login 随后在开发者机器从同一块内的地址连接时,接受位于所列块内的网关。这需要开发者机器上是 Claude Code v2.1.268 或更高,更早的版本忽略该键并应用私有地址规则。
注意:gatewayInternalNetworks 用于碰巧用公网地址空间编号的内部网络;它不会让把网关暴露到互联网变得安全:受信任的网关可以推送在开发者机器上运行命令的设置。要用防火墙或负载均衡器规则让网关无法从你的网络之外到达;把网关的 access_control.allow_cidrs 设为你在这里声明的同样的块,使网关自己拒绝来自其他任何地方的客户端;在负载均衡器或入口后面,还要把 listen.trusted_proxies 设为该前端,否则网关会把 allow_cidrs 与前端自己的地址而不是开发者的地址匹配。
把该键加到与登录键相同的托管设置来源:托管设置文件、MDM 配置文件或注册表策略;Claude Code 在用户、项目和服务器托管设置里忽略它。这个例子声明一个块(把 203.0.113.0/24 换成你自己的块;它是文档用范围,Claude Code 会拒绝这些):
{
"gatewayInternalNetworks": ["203.0.113.0/24"]
}Claude Code 在 /login 联系任何网关之前验证该列表:
- 每个条目是一个 IPv4 块,写成它的第一个地址加
/8到/32的前缀。 - 列表最多持有四个块,且没有两个重叠。
- 没有块与私有地址空间重叠:
10.0.0.0/8、172.16.0.0/12、192.168.0.0/16、127.0.0.0/8、169.254.0.0/16和100.64.0.0/10(/login本来就接受那里的网关,不需要这个键)。 - 没有块与绝不是组织网络的空间重叠:
198.18.0.0/15和192.0.0.0/24(VPN 和 NAT64 客户端把它们当作本地地址);文档用范围192.0.2.0/24、198.51.100.0/24和203.0.113.0/24;以及保留范围0.0.0.0/8、192.88.99.0/24和多播224.0.0.0/4。你可以声明240.0.0.0/4之内的块,有些大型网络把它用作内部单播空间。
来自 managed-settings.json 及其 managed-settings.d/ drop-in 文件的块合并成一个列表,这些限制适用于合并后的列表。要收窄一个块,替换它的条目,而不是在 drop-in 里加第二个重叠的条目;/login 会拒绝重叠。如果某个条目违反规则,或值不是字符串列表,Claude Code 会拒绝该机器上的每个新网关登录并在消息里点名问题;私有地址上的网关登录也会失败,已有的登录继续工作。部署之前先在一台机器上试这个值。Claude Code 还会把类型错误的值列在它报告的无效托管设置里。有了有效列表,/login 对地址位于所列块内的网关应用三个检查:
- 网关主机名解析到的每个地址都在那一个块内;Claude Code 拒绝同时有块外记录(包括私有和 IPv6 地址)的名字。
- 开发者的机器从同一个块内连接;Claude Code 拒绝位于 NAT 后面、在容器或 WSL2 内、或在地址池位于该块之外的 VPN 上的机器,并点名机器连接所用的地址。
- 连接是直连的;如果
HTTPS_PROXY适用于网关主机,/login会拒绝并点名要添加的NO_PROXY条目。
三者都通过时,信任提示会多一行,点名机器的地址、网关的地址以及包含两者的已声明块。该键不改变其他网关的任何东西:对私有地址上网关的登录照常工作,对位于每个所列块之外的公网地址上网关的登录照常被拒绝。声明的块收窄谁能登录,但并不证明机器在哪里,所以只声明你的组织控制的地址空间;与其他租户共享的块(如云提供商的公网范围)会让其中的任何人通过同样的检查。
向 Claude Desktop 会话交付策略
Claude Desktop 在内嵌的 Claude Code 会话上运行它的 Cowork 和 Code 标签页(启用时还有 Chat 标签页),并把它们的模型请求经网关发送。它把策略传给每个这样的会话,策略由网关在 /user/bootstrap 提供给它的配置构成:从匹配策略的 cli 块推导出的模型允许列表、被禁用的工具和出口允许列表,加上 desktop 叠加层。其他 cli 键(如 hooks、env 和 Bash(npm *) 这样限定范围的权限规则)只到达经 /login 登录的客户端。Claude Desktop 从它自己的托管配置读取网关 URL,并用它自己的流程登录,与「设置网关 URL」里的 forceLoginMethod 和 forceLoginGatewayUrl 键分开。由启动进程传入的设置是父级设置。在有管理员部署的托管来源的任何机器上,Claude Code 忽略父级设置,除非交付策略的来源设了 parentSettingsBehavior: "merge"。
哪些机器需要选择加入。 只运行 Claude Desktop 的机器需要它:Claude Desktop 自己对内嵌会话应用模型列表和禁用工具列表,但出口允许列表只以父级设置的形式(WebFetch 域名规则和沙盒网络规则)到达它们;没有选择加入,这些会话在没有出口限制的情况下运行,而且没有任何警告(网关仍会拒绝对策略未授予的模型的推理请求)。插件市场允许列表也只以父级设置的形式到达内嵌会话:当你在 Claude Desktop 的托管配置里关闭用户添加的插件市场时,Claude Desktop 2.16120.0 或更高会隐藏你的组织没有预配的市场并拒绝从它们安装;为了阻止内嵌会话加载已经从这些市场安装的插件,它以父级设置的形式向它们发送 strictKnownMarketplaces 列表;没有选择加入,Claude Code 忽略该列表,这些插件继续加载。开发者经 /login 登录的机器不需要它:每个 Claude Code 会话从网关获取自己的策略。由 policyHelper 提供托管设置的机队无法使用它:在这些机队上 Claude Code 从不合并父级设置,因为它只从 helper 的输出读取托管设置。
设置选择加入。 部署「设置网关 URL」里的托管设置片段,把它镜像到任何优先级高于该文件的客户端来源,然后验证:
- 在托管设置文件里部署选择加入。 上面的片段已经包含
parentSettingsBehavior: "merge",所以你推送到机器上的文件携带了它。 - 把片段镜像到任何优先级高于该文件的来源。 Claude Code 只从被选中的来源读取
parentSettingsBehavior。往某个来源加任何策略键都可能使它成为被选中的来源,所以在客户端来源里要镜像整个片段,而不只是parentSettingsBehavior(经组策略或配置文件交付策略的机队见「客户端托管设置」)。macOS 上的 managed-preferences plist 或 Windows 上的 HKLM 策略优先于managed-settings.json文件,而网关自己的远程托管设置优先于两者,所以在登录网关的机器上,还要在网关策略的cli块里设parentSettingsBehavior。 - 检查选中了哪个来源。 在只运行 Claude Desktop 的机器上,调用 Agent SDK 的
resolveSettings(),并读取它sources列表里managed条目的policyOrigin。该值点名被选中的客户端来源(plist、hklm或file),即必须携带该片段的来源。Claude Desktop 的内嵌会话不获取网关策略,所以网关的cli块对它们从不算被选中的来源。
限制父级设置
一旦你部署了 parentSettingsBehavior: "merge",启动 Claude Code 的任何宿主进程都可以提供父级设置,不只是 Claude Desktop,还有 Agent SDK 应用或 IDE 扩展。Claude Code 按限制性键的允许列表过滤父级设置,但有些被允许的键可以授予访问而不是限制它。除非你设置 allowManaged*Only 锁,宿主提供的权限允许规则和沙盒允许列表仍然适用;你策略的拒绝和询问规则无论如何都保持有效,它们在任何允许规则之前评估。Claude Code 以去掉细节的形式转发父级提供的 sandbox.credentials 条目:
deny条目:只带它们的path或name和模式转发。- 带
mode: mask的文件条目:只以哨兵形式转发,作为injectHosts为空列表的整文件掩码,所以代理在任何平台上都不会为父级提供的条目替换真实值;所有结构化掩码字段也被丢弃,所以父级提供的提取模式无法取代另一个来源为同一路径设置的更严格掩码。 - 带
mode: mask的envVars条目:不转发;deny是父级通道能通过envVars条目表达的唯一限制。 awsPairs和sigv4:只以限制的形式转发。从sigv4只保留deny值,定义了sigv4块的父级会把三种请求形式streaming、presigned和sigv4a全部固定为deny;awsPairs的一对从不以能重新签名的形式转发;点名常规 AWS 变量之一的一对被替换为惰性条目,使AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY和AWS_SESSION_TOKEN的自动配对保持被抑制。
部署这些锁。 要让父级设置尽可能接近过滤器所支持的纯限制性,把五个 allowManaged*Only 锁以及它们所管辖的允许列表加到与合并选择加入相同的来源里:
{
"forceLoginMethod": "gateway",
"forceLoginGatewayUrl": "https://claude-gateway.internal.example.com",
"parentSettingsBehavior": "merge",
"allowManagedPermissionRulesOnly": true,
"allowManagedMcpServersOnly": true,
"allowManagedHooksOnly": true,
"allowedMcpServers": [{ "serverUrl": "https://mcp.internal.example.com/*" }],
"sandbox": {
"network": {
"allowManagedDomainsOnly": true,
"allowedDomains": ["github.com", "*.npmjs.org"]
},
"filesystem": {
"allowManagedReadPathsOnly": true,
"denyRead": ["~/"],
"allowRead": ["~/projects"]
}
}
}HKLM 注册表策略或 managed-preferences plist 这样的操作系统策略优先于这个文件,所以要经它交付整个片段,而不是经文件。网关的远程托管设置优先于操作系统策略和文件来源,但只到达已连接的客户端:把这些锁、允许列表和合并选择加入镜像到策略的 cli 块里,并保持这个文件已部署,因为从不连接的机器(包括只运行 Claude Desktop 的)只从文件得到它们的策略。
锁在各来源之间的行为。 设置一个锁不会限制其他的;每个键在设置参考里有记录。从获胜者之下的管理员来源,两个沙盒锁仍然适用,allowManagedPermissionRulesOnly 仍然阻止父级提供的允许规则和 additionalDirectories;在 Claude Code v2.1.273 及以上,MCP 服务器锁也适用于获胜者之下的来源,并且它开启时,托管的 allowedMcpServers 列表来自设置了它的最高优先级管理员来源。hooks 锁以及 allowManagedPermissionRulesOnly 对开发者自己规则的影响默认需要获胜的来源;在「Claude Code 如何合并托管来源」里的 managedSourcesBehavior 合并选择加入下,Claude Code 对每个锁应用任何来源设置的最严格的值;在 policyHelper 机队上,Claude Code 只从 helper 的输出读取这些锁。每个锁都让 Claude Code 忽略开发者自己对该设置的条目,所以要把你组织的允许列表与这些锁放在一起:
- 网络域名:用空的托管域名列表上锁会阻止所有沙盒出站流量。
- MCP 服务器:在任何管理员来源或父级提供的设置里都没有
allowedMcpServers就上锁,会加载deniedMcpServers没有阻止的每个服务器。 - 读取路径:
allowRead条目只重新允许denyRead区域内的路径,所以要把它们与托管的denyRead配对。
锁不覆盖的设置。 即使五个锁全设了,也有六个父级提供的设置能通过过滤器。在默认的先到先得设置下,管理员的值只有位于最高优先级管理员来源时才阻止父级的值,MCP 服务器锁开启时的 allowedMcpServers 除外;在 managedSourcesBehavior 合并选择加入下,改由「Claude Code 如何合并托管来源」说明哪个来源的值适用。
forceLoginOrgUUID:最高优先级管理员来源没有设置组织 UUID 时,Claude Code 采纳父级提供的值;网关登录不检查这个键;最高优先级管理员来源里的组织 UUID 阻止父级的值,并且是 Claude Code 强制的那个。allowedMcpServers:没有管理员列表生效时,Claude Code 采纳父级提供的允许列表;allowManagedMcpServersOnly不阻止它,因为该锁强制获胜的那个列表作为托管值,包括没有管理员来源提供列表时父级提供的那个;最高优先级管理员来源里的列表阻止父级的并且是 Claude Code 强制的列表,所以要在那里设置allowedMcpServers,放在锁旁边(v2.1.223 之前,任一键在任何管理员来源里的值都阻止父级的)。availableModels:获胜的托管来源没有设置模型列表时,Claude Code 采纳父级提供的模型列表;如果你的机队限制模型,在获胜来源里设availableModels。strictKnownMarketplaces:获胜的托管来源没有设置插件市场允许列表时,Claude Code 采纳父级提供的;Claude Desktop 2.16120.0 或更高在它的托管配置关闭用户添加的插件市场时发送一个;如果你的机队限制市场,在获胜来源里设strictKnownMarketplaces(需要 Claude Code v2.1.282 及以上)。blockedMarketplaces:父级提供的市场黑名单通过,并加到托管来源设置的任何黑名单上,因为黑名单只能进一步限制(需要 Claude Code v2.1.282 及以上)。strictPluginOnlyCustomization:这个键不论任何锁都通过过滤器,并且让 Claude Code 忽略开发者自己的自定义,包括保护性 hooks;没有锁能阻止它。
连接 Claude Desktop
Claude Desktop 通过另一个 MDM 键连接到同一个网关:在 Claude Desktop 的托管配置里把 bootstrapUrl 设为 <listen.public_url>/user/bootstrap,并用 desktop 键让用户的策略选择加入(两半都见「Claude Desktop 叠加层」;需要网关服务器上是 Claude Code v2.1.203 或更高)。Claude Desktop 用同样的浏览器 SSO 步骤通过网关的身份提供商让开发者登录,然后从网关而不是从 Anthropic 获取它的配置。模型访问和策略遵循与 CLI 相同的按组规则。同时使用 CLI 和 Claude Desktop 的开发者要分别登录每一个;网关会话在两者之间不共享。连接后,Claude Desktop 把每个启用的标签页的模型请求经网关发送。它默认显示 Cowork 和 Code 标签页;要同时打开 Chat 标签页,在 Claude Desktop 的托管配置里把 chatTabEnabled 设为 true,或在运行 Claude Code v2.1.227 及以上的网关上,在策略的 desktop 块里设置。
CI 流水线和远程机器
没有给无人值守流水线用的服务令牌流程。网关登录总是运行浏览器设备流程,所以没有开发者批准登录的 CI 作业无法认证;要对这些直接针对你的提供商配置。开发者登录之后,该机器上的每个 Claude Code 会话都使用网关会话,包括非交互的 claude -p 运行和 Agent SDK 启动的会话,Claude Code 对它们每一个都应用网关策略。设备流程把轮询的 CLI 与批准的浏览器分开,所以没有显示器的远程开发机也能用:开发者经 SSH 在远程机器上运行 /login,并在笔记本的浏览器里打开验证链接。
对开发者强制执行什么
这些保证适用于经 /login 登录的每个会话。Claude Desktop 启动的内嵌会话按「向 Claude Desktop 会话交付策略」所述得到它们的策略,遥测一条说明它们的导出去往哪里。
- 模型访问:对策略未授予的模型的请求返回 400,
/model选择器被过滤到策略的availableModels允许列表。在策略里设enforceAvailableModels: true,使 Default 选项解析到availableModels之内的模型,而不是 Claude Code 内置的默认模型;没有它,Default 仍可选择,如果该模型未被授予,就在请求时被拒绝。 - 遥测目的地:在经
/login登录的会话里,CLI 把它的 OTLP/HTTP 导出发给网关,而不是发给本地设置的OTEL_EXPORTER_OTLP_ENDPOINT,除非策略把你的收集器指定为端点;网关把它收到的导出转发到telemetry.forward_to里的目的地。在 Claude Desktop 启动的内嵌会话里,CLI 把导出发给配置的OTEL_EXPORTER_OTLP_ENDPOINT;只有该端点指向网关本身时,CLI 才把网关会话令牌附加到这些导出上。某个信号没有配置目的地时,网关接受并丢弃它。如果你已经直接收集 Claude Code 遥测,把你的收集器添加为forward_to目的地,或在策略里指明它以跳过转发。 - 凭据:网关令牌是会话唯一的凭据。登录期间 Anthropic profile 和任何较早的 claude.ai 登录被忽略,所以开发者不需要先退出 claude.ai。对已配置的
ANTHROPIC_API_KEY、ANTHROPIC_AUTH_TOKEN或apiKeyHelper凭据,或较早的 Claude Console 登录保存的 API key,见「管理员策略要求 Cloud 网关登录」。 - 托管设置:被锁定的键无法在本地覆盖。CLI 在启动时应用策略并在每次每小时轮询时应用变化,只在下次启动才应用的变化除外。
- 网关不可达时的启动:已登录的会话在启动时约 10 秒后带着错误退出,而不是不带它们的设置启动。
- 网关结束会话之后的启动:哪些启动以退出网关登录的状态打开,哪些在网关以
401应答时退出,见「强制失败关闭的启动」。 - 取消预配:IdP 里被禁用用户的会话,在下一次刷新失败时于
ttl_hours内过期。 - 退出登录:
/logout从开发者机器上删除网关凭据。当网关的发现文档在网关 URL 自己的协议、主机和端口上公布了revocation_endpoint时,/logout还会把存储的令牌发给该端点,使网关能在它那一侧结束会话;该请求是尽力而为的,所以不论端点是否应答,退出登录都会在开发者机器上完成(撤销需要开发者机器上是 Claude Code v2.1.275 或更高)。claude二进制里的网关服务器不公布这个端点,所以从它退出登录只在开发者机器上结束会话;要在服务端强制会话退出,见「JWT 密钥轮换」。
组织能看到什么
用量遥测把开发者的身份、token 计数、模型和延迟带到组织的收集器。网关不记录也不存储提示或补全内容。是否收集更丰富的遥测(如日志和追踪,它们可能包含命令和文件路径)是组织按目的地做的选择。
可用性与限制
下表涵盖开发者经网关连接时哪些 Claude Code 功能能工作,以及网关服务器本身支持什么;某项不受支持时,备注列给出替代办法。网关把 CLI 发送的 anthropic-beta 值交付给每个上游,所以运营者不必维护 beta 允许列表;对忽略该头的 Amazon Bedrock,网关把这些值移进请求体的 anthropic_beta 字段,其他上游按发送的原样收到该头。
| 功能 | 状态 | 备注 |
|---|---|---|
| 推理转发(Amazon Bedrock、Claude Platform on AWS、Google Cloud Agent Platform、Microsoft Foundry、Anthropic) | 可用 | 带按上游的模型转换和故障转移。Amazon Bedrock 上游使用 bedrock-runtime 端点和 AWS 默认凭据链;Amazon Bedrock Mantle 端点不是受支持的上游。Claude Platform on AWS 上游要求网关服务器上是 Claude Code v2.1.198 或更高 |
| 按 IdP 组的模型访问和托管设置 | 可用 | 模型访问在服务端强制;托管设置按 IdP 组交付并由 CLI 在托管设置层应用 |
| Claude Desktop | 选择加入后可用 | 一旦策略以 desktop 键选择加入,网关就在 /user/bootstrap 提供 Claude Desktop 的配置,Claude Desktop 把它 Cowork 和 Code 标签页(启用时还有 Chat 标签页)的模型请求经网关发送(打开 Chat 标签页见「连接 Claude Desktop」);需要网关服务器上是 Claude Code v2.1.203 或更高 |
| 遥测扇出(OTLP/HTTP) | 可用 | 每次导出都打上身份标记;protobuf 和 JSON 两种编码都支持 |
| OIDC 身份提供商 | 可用 | 任何兼容 OIDC 的 IdP;网关运行标准的 OIDC 发现和授权码流程(每个 IdP 的配置见「身份提供商设置」) |
| 按用户和按组的支出限额 | 可用 | 见「支出限额」 |
| 服务端网页搜索 | 不可用 | CLI 看不到网关路由到哪个上游提供商,所以无法验证网页搜索支持,并在网关会话上禁用 WebSearch |
| Remote Control | 不可用 | CLI 显示点名网关的错误 |
/design-sync 和 /design-login | 不可用 | 两者都需要 claude.ai,而 CLI 在网关会话上不联系它,所以两个命令都不出现在那里 |
需要功能标志获取的功能,如 /import 和 claude import | 不可用 | CLI 在网关会话上跳过标志获取(关闭了哪些功能见「需要功能标志获取的功能」) |
| 标准提示缓存 | 可用 | 网关把 cache_control 断点转发给每个上游(CLI 标记哪些块,包括它在对话中途追加的系统上下文,见「缓存在哪里」) |
| 1 小时缓存 TTL | 不可用 | CLI 在网关会话上省略 extended-cache-ttl beta,因为不是网关能路由到的每个上游都支持 1 小时 TTL,所以经网关的提示缓存使用 5 分钟 TTL(见上面的 beta 头说明) |
| Auto 模式 | 可用 | 遵循第三方提供商规则:只有在第三方提供商上有资格的模型才能使用它(v2.1.207 之前,网关会话上的 auto 模式需要设置 CLAUDE_CODE_ENABLE_AUTO_MODE=1,可经托管策略的 env 块交付) |
| 仅限第一方的优化,如全局缓存范围和 token 高效工具 | 不可用 | CLI 在网关会话上不启用它们(见上面的 beta 头说明) |
| OTLP/gRPC | 不支持 | 只支持基于 HTTP 的 OTLP |
| SAML、LDAP 和其他非 OIDC 认证 | 不支持 | 只支持 OIDC;需要时在前面放 OIDC 桥 |
| 多租户(多个 OIDC issuer) | 不支持 | 每个网关一个 issuer;运行单独的实例 |
| Windows 服务器 | 不支持 | 部署在 Linux 上;macOS 只用于本地开发 |
| Helm chart | 不可用 | 网关作为标准的无状态 Deployment 运行(见部署指南) |
| 管理界面 | 不可用 | 配置就是 YAML 文件;改配置要重新部署 |
下一步
快速开始让你得到一个在 Docker Compose 下运行的最小配置。要更进一步:
- 把
gateway.yaml扩展到最小配置之外,例如添加按组 RBAC、多上游故障转移或遥测目的地(每个选项见配置参考)。 - 从 Compose 迁移到 Kubernetes 或 Cloud Run 上的生产部署,正确设置你的 IdP,并审查安全模型(每个 IdP 的设置、容器镜像要求、健康探针和排障见部署与运维指南)。
- 给单个开发者或组设支出上限,使失控的工作负载无法耗尽你的整个承诺(管理 API 和强制执行如何工作见「支出限额」)。
- AWS 上的完整工作示例(ECS Fargate 或 EKS、Amazon RDS 和 Secrets Manager)见「在 AWS 上部署」。
- Google Cloud 上的完整工作示例(Cloud Run、Cloud SQL 和 Secret Manager)见「在 Google Cloud 上部署」。