gateway.yaml. Файл определяет всё, что делает gateway: где он слушает, как разработчики входят в систему, куда идёт вывод, и какие политики и телеметрия применяются. Эта страница — справочник по каждому параметру в этом файле.
Чтобы написать свой первый файл, начните с quickstart, который создаёт минимальную рабочую конфигурацию и запускает её. Когда у вас будет конфигурация, которой вы довольны, руководство по развёртыванию охватывает контейнеризацию и размещение на Kubernetes, Cloud Run или вашей собственной платформе.
Gateway читает файл один раз при запуске с помощью claude gateway --config /path/to/gateway.yaml. Каждый параметр проверяется по схеме при загрузке, поэтому неправильная конфигурация не запускается с ошибкой на уровне поля, а не при первом использовании.
Полный пример в конце этой страницы охватывает каждый раздел.
Структура файла
Пять разделов обязательны. Все остальные разделы опциональны, и пропущенный раздел принимает значения по умолчанию. Неизвестные ключи приводят к сбою при загрузке, поэтому опечатка выявляется как именованная ошибка, а не как молча игнорируемый параметр. Обязательные разделы:listen: адрес привязки, публичный URL, завершение TLSoidc: ваш поставщик идентификации (IdP), включая издателя, клиента, сопоставление утверждений и кто может входитьsession: токены-носители, которые выпускает gateway, с секретом и временем жизниstore: PostgreSQL для грантов устройств и счётчиков ограничения скоростиupstreams: куда идёт вывод, будь то Anthropic, Amazon Bedrock, Claude Platform на AWS, Agent Platform Google Cloud или Microsoft Foundry
login_notice: уведомление, которое разработчики видят при входеadmin: аутентификация Admin API и сохранение лимитов расходовenforcement: поведение лимитов расходов при сбое — пропускать запросы (fail-open) или блокировать (fail-closed)pricing: договорные ставки и множитель для счётчика расходов и для цифр стоимости, которые видят разработчикиmodelsиauto_include_builtin_models: кураторский список моделей администратором и ID для каждого upstreammanaged: управляемые политики параметров по группам IdPtelemetry: пересылка OTLP на ваш стек наблюдаемостиaccess_control,limits,timeouts,rate_limits: разрешение/запрет IP, ограничения размера запроса, время до первого байта upstream и лимиты входа по IPload_test_mode: нагрузочное тестирование gateway без вызова поставщика модели
Расширение секретов
Не пишите секреты, такие какclient_secret, jwt_secret или postgres_url, прямо в gateway.yaml. Ссылайтесь на них одной из форм ниже, и gateway разрешит значение при загрузке из переменной окружения или файла:
Обязательные разделы
listen
Блок listen определяет, где шлюз принимает запросы: адрес и порт привязки, видимый извне origin и необязательное завершение TLS.
Указывайте фронтенд в
trusted_proxies, только если последняя запись X-Forwarded-For, которую он передаёт дальше, не написана ни одним разработчиком. Не указывайте ни одного адреса или диапазона, с которых подключаются разработчики. Фронтенд, который добавляет адрес каждого получаемого соединения, подходит. Фронтенд, который передаёт заголовок дальше в том виде, в каком его отправляют разработчики, — нет.
Записи X-Forwarded-For в форме ipv4:port или [ipv6]:port, как их записывают некоторые балансировщики нагрузки, читаются без порта. IPv6-адрес с добавленным портом без квадратных скобок может быть прочитан как другой адрес или не прочитан вовсе. Отключите опцию порта на любом прокси, который записывает такую форму.
oidc
Блок oidc подключает шлюз к вашему поставщику идентификации и определяет, кто может входить. В нём указываются издатель и OAuth-клиент, задаются claims, содержащие email и группы, и вход ограничивается по домену email или по группе.
OpenID Connect (OIDC) — это протокол SSO, который шлюз использует для работы с вашим поставщиком идентификации; что нужно зарегистрировать на стороне IdP, см. в разделе Настройка поставщика идентификации.
Аутентификация клиента по сертификату
Если ваш поставщик идентификации аутентифицирует OAuth-клиентов по сертификату вместо секрета клиента, как это делает Microsoft Entra с учётными данными-сертификатами, задайтеtoken_endpoint_auth_method: private_key_jwt. Требует Claude Code v2.1.284 или новее на сервере шлюза.
В этой конфигурации шлюз не отправляет секрет. Он аутентифицируется на эндпоинте токенов IdP с помощью короткоживущего JWT, подписанного закрытым ключом сертификата, когда разработчик входит в систему и каждый раз, когда шлюз обновляет его сессию. JWT подписывается алгоритмом RS256 и идентифицирует сертификат заголовками отпечатков x5t и x5t#S256, а не kid. Ваш IdP должен уметь находить зарегистрированный сертификат по отпечатку.
1
Создайте ключ и сертификат
Создайте незашифрованный закрытый ключ RSA длиной не менее 2048 бит в формате PEM PKCS#8 или PKCS#1 и сертификат для него. Шлюз отказывается запускаться с ключом, который не соответствует этим условиям. Эта команда Она записывает
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 через прямой прокси
Upstream для инференса учитываютHTTPS_PROXY и HTTP_PROXY во всех версиях. Собственные запросы шлюза к IdP — обнаружение, JWKS, токены и userinfo — идут напрямую, если вы не зададите oidc.use_proxy: true, что требует v2.1.227 или новее. Если задана переменная прокси, use_proxy не задан, а издатель не входит в NO_PROXY, шлюз оставляет эти запросы прямыми и при загрузке записывает в лог уведомление с просьбой сделать выбор; use_proxy: false оставляет их прямыми и отключает уведомление.
С use_proxy: true под сам разрешает имя хоста каждого эндпоинта IdP и просит прокси выполнить CONNECT к полученному IP-адресу, поэтому прокси должен разрешать CONNECT к IP-адресу каждого хоста, указанного в документе обнаружения, а не только издателя. Используйте URL прокси http://. ca_cert_pem и защита от SSRF действуют и на пути через прокси.
Исходящий трафик только через прокси меняет оба этих момента: пока он активен, запросы к IdP идут через прокси, если вы не зададите use_proxy: false, а шлюз передаёт прокси каждое имя хоста IdP, не разрешая его предварительно.
Исходящий трафик только через прокси
ЗадайтеCLAUDE_GATEWAY_PROXY_IS_EGRESS_BOUNDARY=1 в окружении шлюза рядом с HTTPS_PROXY, если под обращается к другим хостам только через этот прямой прокси и не может сам разрешать публичные DNS-имена, или если прокси отклоняет CONNECT к IP-адресу. Требует v2.1.277 или новее. Это переменная окружения, а не ключ gateway.yaml, чтобы ничто в файле конфигурации не могло ослабить проверку адресов шлюзом.
network:.
Каждая строка ниже — это один класс исходящих запросов шлюза с заданным HTTPS_PROXY: по умолчанию и при активном исходящем трафике только через прокси.
Исходящий трафик только через прокси остаётся выключенным, если окружение шлюза не удовлетворяет всем трём условиям:
- Задан
HTTPS_PROXYилиHTTP_PROXY. NO_PROXYиno_proxyпусты. Если ваша платформа внедряет любую из них в поды, задайте обеим пустое значение в контейнере шлюза. Если указать сборщик телеметрии вNO_PROXY, исходящий трафик только через прокси останется выключенным.CLAUDE_GATEWAY_ALLOW_LOOPBACKне включена. Сборщик или IdP на собственном loopback пода нельзя сочетать с исходящим трафиком только через прокси, потому что loopback-адрес, переданный прокси, указывал бы на сам хост прокси, поэтому дайте этим сервисам адрес, доступный для прокси. По той же причине, пока исходящий трафик только через прокси активен, шлюз полностью отклоняет имена видаlocalhost.
oidc.use_proxy: false.
session
Блок session определяет Bearer-токены, которые шлюз выпускает после входа: секрет, которым они подписываются, и срок их жизни.
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 или таймауте шлюз переключается на следующий upstream; при других 4xx — нет, потому что такие ошибки связаны с запросом, а не с upstream. 401 или 403 означает, что upstream отклонил учётные данные, которые использовал шлюз, или отказал ему в доступе, например к запрошенной модели. 404 означает, что этот upstream не обслуживает запрошенную модель, поэтому её может обслужить следующий upstream в списке.
Если вы задали forward_user_identity: true для upstream, ответ 429 от него на запрос, содержащий email разработчика, не приводит к переключению. См. как отказ по лимиту для отдельного пользователя доходит до разработчика.
Переключение при 404 требует шлюза v2.1.198 или новее. Более ранние выпуски возвращали клиенту первый 404, даже если модель обслуживал следующий upstream в списке.
Несколько upstream одного поставщика должны иметь разные name:.
Клиенты Amazon Bedrock, Claude Platform on AWS, Google Cloud’s Agent Platform и Microsoft Foundry создаются один раз при запуске, а их SDK обновляют учётные данные самостоятельно, поэтому ротация облачных учётных данных не требует перезапуска. Статические API-ключи и Bearer-токены Anthropic читаются при запуске; см. Anthropic API.
Сообщения об ошибках upstream
В зависимости от того, как ответили upstream, шлюз возвращает ответ с ошибкой от одного из них или собственный502:
- Upstream вернул статус, при котором шлюз не переключается: ответ этого upstream. Другие upstream шлюз больше не пробует.
- Все вышестоящие серверы, которые пробовал шлюз, завершились ошибкой, при которой он переключается: последний
429. Если ни один не вернул429, шлюз предпочитает по порядку последний401или403, последний404и последний501. Если ни один не вернул ничего из этого — собственный502шлюза,all upstreams failed (N attempted). N — это число ваших записейupstreams, включая пропущенные, за вычетом тех, списокgroupsкоторых не включает разработчика.
400или413в стандартной обёртке ошибок Anthropic: собственное сообщение upstream, напримерprompt is too long. Claude Platform on AWS, Agent Platform и Microsoft Foundry возвращают такую обёртку при отклонениях API модели.400или413в собственном формате поставщика: токенcapability_rejected:. Если шлюз не может классифицировать отклонение —upstream rejected the requestдля400илиrequest too large for this upstreamдля413.- Любой другой статус: общий текст для каждого статуса, например
upstream rate limit exceededдля429.
Input is too long for requested model. на capability_rejected: prompt_too_long. На этот токен Claude Code автоматически выполняет сжатие, так же как на prompt is too long.
Сохранение сообщения 400 или 413 облачного upstream или его замена токеном capability_rejected: требует шлюза v2.1.233 или новее.
Anthropic API
Минимальный upstream Anthropic — это API-ключ из Claude Console:api_key: отправляетx-api-key. Выполняйте ротацию в Claude Console и обновляйте переменную окружения.oauth_token: отправляетAuthorization: Bearer. Используйте Bearer-форму, если ваша организация выдаёт короткоживущие токены вместо долгоживущих API-ключей. Bearer-токен читается один раз при запуске, поэтому для обновления перемонтируйте секрет и перезапустите шлюз.
Заголовки идентификации пользователя для вашего прокси
Вы можете указать вbase_url upstream provider: anthropic свой прокси вместо Anthropic API. Чтобы сообщать этому прокси, какой разработчик отправил каждый запрос, задайте forward_user_identity: true для этого upstream. Тогда прокси сможет учитывать расходы по разработчикам. Требует шлюза на Claude Code v2.1.233 или новее.
Например, для прокси по адресу upstream-gateway.internal.example.com:
Если токен IdP не содержит email, шлюз отправляет только
x-claude-gateway-user-id и опускает два заголовка с email. Если ваш IdP передаёт email в другом claim, укажите этот claim в oidc.email_claim.
Ваш прокси не получает заголовки x-claude-code-*, которые отправляет Claude Code, например x-claude-code-session-id. Шлюз не передаёт их ни одному upstream, поэтому группируйте запросы по разработчикам с помощью заголовков из таблицы выше.
Когда ваш прокси отвечает 429 на запрос, содержащий email разработчика, шлюз возвращает этот ответ разработчику как есть, а не переключается на следующий upstream, поэтому бюджет или ограничение частоты запросов для отдельного пользователя в вашем прокси соблюдается. Остальные ответы прокси подчиняются обычным правилам переключения. Если токен IdP разработчика не содержит email, шлюз пересылает его запросы без заголовков с email, поэтому 429 на такой запрос считается нехваткой мощности upstream и приводит к переключению. До v2.1.267 на сервере шлюза каждый 429 приводил к переключению.
Задавайте forward_user_identity только для upstream, base_url которого — прокси под вашим управлением. Шлюз отправляет email разработчиков на любой сервер, указанный в этом base_url. Если base_url указывает на Anthropic API, что является значением по умолчанию, шлюз отказывается запускаться.
Если задать
forward_user_identity для upstream Amazon Bedrock, шлюз завершает работу при запуске с ошибкой Unrecognized key(s) in object: 'forward_user_identity'. Если ваш прокси стоит перед Bedrock, укажите его как upstream provider: anthropic. Шлюз отправляет этому upstream запросы в формате Anthropic Messages, поэтому ваш прокси должен преобразовывать запросы для Bedrock. Чтобы вместо этого сообщать AWS, какой разработчик отправил запрос, см. Учёт затрат AWS по разработчикам.Amazon Bedrock
О клиентском развёртывании Amazon Bedrock, которое шлюз заменяет или перед которым стоит, см. Claude Code на Amazon Bedrock. Upstream на стороне шлюза:auth использует цепочку учётных данных AWS SDK по умолчанию: переменные окружения, ~/.aws/credentials, роль задачи ECS, метаданные экземпляра EC2 или IRSA на EKS. В production назначьте поду шлюза IAM-роль вместо встраивания статических ключей в образ контейнера.
Явные учётные данные должны быть полными: шлюз не запускается, если aws_access_key_id и aws_secret_access_key заданы не вместе или если aws_session_token задан без них. До v2.1.207 частичный блок auth: проходил проверку.
Применение guardrail Amazon Bedrock
Чтобы применить guardrail Amazon Bedrock ко всем запросам инференса, которые шлюз отправляет через upstream Bedrock, добавьте в этот upstream блокguardrail. Требует Claude Code v2.1.281 или новее на сервере шлюза.
bedrock:ApplyGuardrail на этот guardrail принципалу, который подписывает запросы этого upstream: принципалу AWS шлюза или, при использовании assume_role, роли, указанной в role_arn.
Задайте guardrail либо для каждого upstream bedrock, либо ни для одного. При смешанной конфигурации шлюз отказывается запускаться, потому что иначе переключение могло бы отправить запрос в upstream Bedrock без guardrail.
Guardrail действует только для upstream Bedrock. Если вы укажете в upstreams другого поставщика, шлюз будет отправлять ему запросы без guardrail, а если этот поставщик — mantle, откажется запускаться.
Когда запрос /v1/messages, тело которого содержит поле amazon-bedrock-*, например amazon-bedrock-guardrailConfig, попадает в upstream Bedrock с заданным guardrail, шлюз отвечает 400 вместо того, чтобы переслать его.
Добавление входных тегов guardrail
Чтобы шлюз добавлял входные теги, которые нужны фильтру атак на промпты guardrail Amazon Bedrock, задайтеinput_tagging в блоке guardrail и перезапустите шлюз. Задайте одно и то же значение на каждом вышестоящем сервере bedrock, иначе шлюз не запустится. Требуется Claude Code v2.1.316 или новее на сервере шлюза. Шлюз версии, в которой нет этого ключа, завершается при запуске с ошибкой Unrecognized key(s) in object: 'input_tagging'.
input_tagging принимает одно из следующих значений:
При
last_message, если в сообщениях user после последнего ответа Claude нет текста для пометки, шлюз вместо этого помечает системные сообщения посреди диалога, появившиеся после этого ответа. Вызов инструмента считается ответом.
Рекомендация Amazon Bedrock для фильтра атак на промпты — помечать пользовательский ввод так, чтобы системный промпт был исключён. Если вы зададите all_messages_and_system, фильтр, срабатывающий на собственный системный промпт Claude Code, может блокировать запросы.
В примере ниже помечается текст в каждом сообщении user:
user могут также содержать текст, который добавляет Claude Code, например системные напоминания, поэтому проверьте на тестовом шлюзе, что обычные запросы не блокируются.
В тестах Anthropic помеченная сессия сохраняла чтение из кэша промптов от одного промпта к другому, а теги не добавляли входных токенов.
Что не покрывают входные теги
Ни одно значениеinput_tagging не остановит разработчика, который намеренно помещает текст туда, куда тег не ставится. Не рассчитывайте, что guardrail будет оценивать следующие части запроса:
- Содержимое, которое шлюз не помечает: сообщения, не охваченные вашим значением
input_tagging, определения инструментов, входные данные вызовов инструментов, изображения и PDF, среди прочего. Если не заданоall_messages_and_system, системный промпт тоже не помечается. - Результаты инструментов: они содержат то, что возвращают инструменты Claude, например содержимое файлов и веб-страницы. В тестах Anthropic фильтр слов не оценивал их ни с тегами, ни без них.
Запись в лог сработавшего фильтра guardrail
Чтобы выяснить, какой фильтр guardrail Amazon Bedrock заблокировал запрос разработчика, задайтеguardrail_trace: true для вышестоящего сервера Bedrock, перезапустите шлюз и попросите разработчика отправить запрос снова. Затем найдите событие guardrail.trace этого запроса в журнале аудита. Требует Claude Code v2.1.314 или новее на сервере шлюза. Более ранний шлюз отказывается запускаться, обнаружив guardrail_trace.
guardrail.trace без совпавшего текста, когда сработал фильтр или действие guardrail равно INTERVENED. Ищите события разработчика по email или sub. Один запрос с потоковой передачей может породить несколько событий, и у одного из них список filters может быть пустым, поэтому читайте все события с одинаковым request_id:
Событие не содержит текста, совпавшего с фильтром, включая поле
match трассировки Bedrock. Разработчики не получают данные трассировки Bedrock, поскольку шлюз удаляет их из каждого ответа, потокового или нет.
Если клиент отправляет поле amazon-bedrock-* в теле запроса /v1/messages, шлюз отвечает 400 на вышестоящем сервере, для которого задан guardrail_trace.
Bedrock в другом аккаунте AWS
Если задатьassume_role для upstream Bedrock, шлюз использует собственную идентичность AWS только для вызова sts:AssumeRole на указанную вами роль, которая может находиться в другом аккаунте AWS, чем шлюз. Каждый запрос Bedrock от этого upstream подписывается одночасовыми учётными данными, которые возвращает STS, поэтому ни один долгоживущий ключ доступа не пересекает границы аккаунтов.
Требует шлюза на Claude Code v2.1.281 или новее. Более ранний шлюз отказывается запускаться, обнаружив этот ключ.
assume_role принимает три ключа:
Политика доверия роли указывает собственный принципал шлюза, например его роль IRSA или роль задачи ECS. Этому принципалу нужно
sts:AssumeRole на роль и не нужны собственные разрешения Bedrock. Удалите Condition, если не задаёте external_id.
- Если STS отклоняет вызов или недоступен, шлюз не отправляет запрос с собственными учётными данными upstream. Он записывает в лог ошибку STS с указанием, что проверить, затем пробует следующий указанный вами upstream. Что получает клиент, если ни один upstream не справился, описано в разделе Сообщения об ошибках upstream. Следующий upstream без
assume_roleобслужит запрос со своими учётными данными, поэтому указывайте такой upstream, только если вам нужно именно это. - Шлюз вызывает региональный эндпоинт STS
sts.<region>.amazonaws.com, который должен быть доступен из его сети. Для эндпоинта FIPS задайтеAWS_USE_FIPS_ENDPOINT=trueв окружении шлюза, а неuse_fips_endpointв файле конфигурации AWS. assume_roleтребует исходных учётных данных SigV4: шлюз не запустится, если он задан вместе сaws_bearer_token.- Без списка
groupsэтот вышестоящий сервер может использовать каждый разработчик, которого допускает шлюз. Чтобы ограничить, какие модели может использовать разработчик, задайтеavailableModelsв политикеmanaged. - Чтобы модель, обслуживаемая через роль, не обслуживалась также из другого аккаунта, дайте ей пользовательский id, карта
upstream_modelкоторого содержит только имя этого вышестоящего сервера. Для такого id шлюз пропускает все остальные вышестоящие серверы, поэтому ни сам запрос, ни подсчёт токенов для прерванного запроса не могут переключиться на другой аккаунт. - Запрос встроенного имени модели всё равно может дойти до этого вышестоящего сервера, и шлюз подписывает его той же ролью. Указывайте этот вышестоящий сервер последним, если его аккаунт не должен также обслуживать эти модели.
Учёт затрат AWS по разработчикам
По умолчанию шлюз подписывает каждый запрос Bedrock одними учётными данными, поэтому AWS видит запросы всех разработчиков под одним IAM-принципалом. Добавьтеsession_name: email в assume_role, и шлюз будет вызывать sts:AssumeRole раз в час для каждого разработчика с именем сессии, равным email этого разработчика, и подписывать его запросы полученными учётными данными, так что запросы каждого разработчика поступают в AWS в рамках его собственной сессии принятой роли. Роль может находиться в собственном аккаунте шлюза.
Требует шлюза на Claude Code v2.1.281 или новее. IAM-роль и то, где биллинг AWS показывает сессии, описаны в разделе Учёт затрат в AWS.
session_name выбирает, какой проверенный claim становится AWS RoleSessionName: email или sub. Любой символ, кроме латинских букв ASCII, цифр и _+,.@-, шлюз записывает как =XX в hex для каждого байта UTF-8, а результат длиннее 64 символов сокращает до префикса и хеша, поэтому имя сессии каждого разработчика остаётся допустимым и уникальным. Запрос от разработчика, токен которого не содержит нужного claim, не отправляется через этот upstream, а в логе оператора появляется совет переключиться на sub или задать oidc.email_claim.
Активный разработчик обходится в один вызов STS в час на каждую реплику шлюза, а одновременные первые запросы используют один общий вызов.
Шлюз также выполняет на этой роли один собственный вызов: подсчёт токенов для запроса, прерванного клиентом, чтобы лимиты расходов оставались точными. Этот подсчёт и его резервный запрос на один токен подписываются общей сессией claude-apps-gateway, поэтому AWS относит резервный запрос к claude-apps-gateway, а не к разработчику.
Для строгого учёта по разработчикам задайте assume_role с session_name для каждого указанного upstream Bedrock. Upstream без этой настройки подписывает обслуживаемые им запросы собственными учётными данными.
Эндпоинт Amazon Bedrock Mantle
Поставщикmantle отправляет запросы инференса на эндпоинт Mantle Amazon Bedrock. Требует Claude Code v2.1.283 или новее на сервере шлюза. Более ранние выпуски шлюза отклоняют его при загрузке, поэтому обновите все реплики, прежде чем добавлять его.
В примере ниже Mantle стоит первым, а за ним следует upstream Amazon Bedrock, обслуживающий все модели, не указанные в поле models:
mantle.
Предоставьте идентичности AWS этого upstream собственные IAM-действия Mantle для инференса и подсчёта токенов, перечисленные в разделе Использование эндпоинта Mantle.
Для ID модели Mantle, который шлюзу неизвестен, добавьте запись в блок верхнего уровня
models:, в upstream_model которой имя этого upstream сопоставлено с этим ID. Затем укажите id этой записи также в поле models этого upstream.
Настройки guardrail и assume_role upstream bedrock не распространяются на запросы, которые обслуживает Mantle:
guardrail: шлюз не применяет guardrail Bedrock к запросам, которые отправляет в Mantle, поэтому отказывается запускаться, если указан upstreammantle, а для какого-либо upstreambedrockзаданguardrail.assume_role: задайте его для самого вышестоящего сервисаmantle. Без него запросы, обслуживаемые Mantle, отправляются с собственными учётными даннымиauthвышестоящего сервисаmantle.
Claude Platform on AWS
Claude Platform on AWS предоставляет собственный API Anthropic на инфраструктуре AWS по адресуaws-external-anthropic.<region>.api.aws. Он использует собственные ID моделей Anthropic, учитывает заголовки anthropic-beta в том виде, в каком они отправлены, и обслуживает count_tokens, поэтому никакие преобразования, специфичные для Bedrock, не применяются. Поставщик anthropicAws требует Claude Code v2.1.198 или новее; более ранние выпуски шлюза отклоняют его при загрузке.
О клиентском развёртывании той же платформы см. Claude Code на Claude Platform on AWS. Upstream на стороне шлюза:
aws-external-anthropic, поэтому IAM-роль, ограниченная Bedrock, не даёт к ней доступа. API-ключ в auth.api_key имеет приоритет, если также заданы учётные данные SigV4. Пустой блок auth использует цепочку учётных данных AWS SDK по умолчанию — ту же, что и upstream Amazon Bedrock.
Поскольку платформа разрешает собственные ID моделей Anthropic, встроенный каталог направляет запросы к ней без блока
models:. Если вы составляете собственный список models:, задайте для записи ключ anthropicAws: с собственным ID Anthropic.
Google Cloud Agent Platform
Об аналогичной клиентской настройке см. Claude Code на Google Cloud. Upstream на стороне шлюза:auth использует Application Default Credentials: GOOGLE_APPLICATION_CREDENTIALS, метаданные GCE или Workload Identity GKE. JSON-файлы ключей сервисного аккаунта поддерживаются, но не рекомендуются; используйте Workload Identity или привяжите сервисный аккаунт к экземпляру GCE или Cloud Run.
Задайте region: global, чтобы использовать глобальный эндпоинт Google Cloud’s Agent Platform вместо регионального. Тогда Google направляет каждый запрос в доступный регион, и вам не нужно отслеживать доступность моделей по регионам. Указание конкретного региона закрепляет за ним все запросы.
Microsoft Foundry
О клиентском развёртывании Microsoft Foundry см. Claude Code на Microsoft Foundry. Upstream на стороне шлюза:use_azure_ad: true получает учётные данные через DefaultAzureCredential: Managed Identity на AKS, ACI или App Service, Azure CLI или учётные данные из окружения. API-ключи работают, но действуют на уровне всего проекта и не ротируются автоматически. Эндпоинт Microsoft Foundry выводится из resource:; задайте необязательный base_url, чтобы переопределить его для суверенных облаков, таких как Azure Government.
Статические заголовки в запросах к upstream
Чтобы добавлять фиксированные заголовки к запросам, которые шлюз отправляет одному upstream, задайте для этого upstreamheaders:. Используйте это, если ваш прокси перед поставщиком маршрутизирует или учитывает трафик по заголовку.
headers: требует Claude Code v2.1.277 или новее на сервере шлюза. Более ранний шлюз отказывается запускаться, обнаружив этот ключ. Обновите все реплики, прежде чем добавлять ключ, и удалите ключ перед откатом на более раннюю версию.
Заголовки отправляются на сервер, указанный в base_url, или на собственный эндпоинт поставщика, если base_url не задан. Поставщик тоже получает их, если ваш прокси их не удаляет.
В этом примере upstream provider: vertex доступен через прокси по адресу upstream-proxy.internal.example.com. Задаётся заголовок x-source, который читает прокси, и токен из переменной окружения PROXY_TOKEN отправляется как x-proxy-token:
true и false, чтобы YAML читал их как текст.
Чтобы не хранить секрет в файле конфигурации, используйте подстановку секретов и загружайте значение из переменной окружения через ${VAR} или из файла через ${file:/path}. Если ${VAR} разрешается в пустое значение, шлюз не запустится.
headers: работает для всех поставщиков, и каждый upstream отправляет только свои заголовки.
Не все запросы, которые шлюз отправляет upstream, содержат их:
Для upstream Amazon Bedrock или Claude Platform on AWS, который подписывает запросы с помощью AWS SigV4, эти заголовки входят в подпись, поэтому ваш прокси должен передавать их без изменений.
Если вы используете имя, зарезервированное шлюзом, он отказывается запускаться, и ошибка запуска указывает этот заголовок. К зарезервированным относятся:
authorizationиx-api-keyhost,content-typeиuser-agent- Любое имя, начинающееся с
anthropic-,x-goog-,x-amz-илиx-amzn-
Несколько upstream
Один и тот же поставщик может встречаться несколько раз с разнымиname:. Это позволяет использовать разные регионы, разные аккаунты через разные цепочки учётных данных, выделенную пропускную способность наряду с оплатой по запросу, а также резервный вариант у другого поставщика.
Шлюз пробует upstream по порядку. При 5xx, 429, 401, 403, 404, таймаутах и отсутствии эндпоинта (501) происходит переключение; при других 4xx — нет.
429 означает нехватку мощности конкретного upstream, поэтому при исчерпании выделенной пропускной способности (PT) запросы переключаются на оплату по запросу. Если вы задали forward_user_identity: true для upstream, 429 на запрос, содержащий email разработчика, считается отказом для отдельного пользователя и не приводит к переключению.
Запрос переходит к следующему вышестоящему провайдеру только в следующих случаях:
- Вышестоящий провайдер вернул ошибку
- Вышестоящий провайдер не обслуживает запрошенную модель
- У вышестоящего провайдера есть список
groups, в который разработчик не входит
- Upstream
provider: anthropic:timeouts.upstream_ttfb_ms, по умолчанию 120 секунд - Другие поставщики: до одного часа. Чтобы сократить это ожидание для потоковых запросов, задайте
timeouts.upstream_ttfb_msна шлюзе v2.1.295 или новее. Непотоковые запросы к модели в любом случае ждут до одного часа
404 означает недоступность модели в конкретном upstream, поэтому upstream, в котором модель не включена, не блокирует следующий upstream, который её обслуживает. Upstream, который не может разрешить запрошенную модель, пропускается без сетевого обращения.
В этом примере запросы сначала направляются в выделенную пропускную способность Amazon Bedrock, при переполнении — в режим оплаты по запросу и во второй аккаунт, а в последнюю очередь — в Anthropic API:
Переключение между облачными поставщиками или на Anthropic API напрямую меняет соглашение, географию и другие условия, которым подчиняется запрос.
CLI применяет одинаковые ограничения функций к шлюзам независимо от того, какой upstream обслуживает конкретный запрос, поэтому по умолчанию переключение не приводит к отправке поля тела, которое upstream отклонил бы. Если вы задаёте в политике одночасовой TTL кэша, он отправляется каждому upstream в списке, поэтому задавайте его, только если все они его принимают.
Направление каждой команды к своему вышестоящему провайдеру
Чтобы направлять запросы каждой команды в её собственный аккаунт AWS или проект Google Cloud, укажите по одному вышестоящему провайдеру на команду и задайте каждому списокgroups. К такому провайдеру обращаются только разработчики из перечисленных групп IdP — как при первой попытке, так и при переключении. groups поддерживается всеми провайдерами. Требуется Claude Code v2.1.314 или новее на сервере шлюза.
В этом примере группы payments-eng и search-eng получают по аккаунту AWS, а также добавлен вышестоящий провайдер без списка groups, доступный всем разработчикам:
Когда вышестоящий провайдер команды отклоняет запрошенную модель с кодом
403, шлюз пробует следующего провайдера в строке этой команды, который обслуживает модель. Чтобы закрепить команду за одним провайдером, задайте список groups каждому вышестоящему провайдеру и убедитесь, что ни один другой провайдер не перечисляет группу, в которую входят разработчики команды. Тогда у этой команды не будет переключения, а запросы разработчиков, не входящих ни в одну из перечисленных групп, завершатся ошибкой 400.
Чтобы каждый разработчик попадал к нужному вышестоящему провайдеру, записывайте точно совпадающие значения и размещайте открытых провайдеров последними:
- Значения: записывайте каждую группу точно так, как ваш IdP передаёт её в claim групп, который также читает
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, который повторяет публичный Admin API Anthropic, и применение лимитов расходов для каждого разработчика на /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 сообщает счётчику расходов, какие цены использовать вместо прейскурантных в USD, чтобы лимиты и /effective отражали ваши договорные тарифы. Суммы остаются в USD и являются оценкой, а не счётом. Два предварительных требования:
- 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, отправленным клиентом, или со строкой, отправленной в upstream. - Если строки пересекаются, счётчик выбирает самую конкретную строку, а не первую: строку, чей
modelточно совпадает со строкой модели, отправленной в upstream, затем строку, совпадающую с точным ID, отправленным клиентом, затем строку, называющую встроенную модель. - Неизвестное имя upstream приводит к ошибке при запуске, как и две строки для одного upstream с одной и той же моделью, включая два написания одной встроенной модели. Шлюз выдаёт предупреждение при запуске о строке, которую не может использовать ни одна запрашиваемая модель.
- Запросы веб-поиска остаются по прейскурантной цене $0.01; множитель к ним всё равно применяется.
Наценка на цены
С v2.1.271 или новее на сервере шлюза вы можете установитьmultiplier выше 1, вплоть до 10, чтобы учитывать больше, чем взимает провайдер, например по внутреннему тарифу перевыставления затрат. В этом примере каждый запрос учитывается по 120% цены:
admin: наценка применяется и к лимитам расходов. Счётчик учитывает 120% цены, поэтому разработчики достигают своих лимитов раньше. Шлюз записывает в лог предупреждение об этом при запуске.
Множитель не меняет того, что upstream-провайдер взимает за запросы.
Если шлюз также отправляет тарифы клиентам, вошедшим в систему, разработчикам нужен Claude Code v2.1.271 или новее, чтобы видеть наценку. Более ранние клиенты игнорируют multiplier выше 1 и показывают затраты без него.
Сервер шлюза версии ниже v2.1.271 отказывается запускаться, если вы установили multiplier выше 1.
Отправка тарифов клиентам, вошедшим в систему
С v2.1.268 или новее на сервере шлюза шлюз также помещает ставки изpricing в обслуживаемые им политики managed в виде управляемой настройки modelPricing.
Разработчики, подпадающие под политику, затем видят ставки pricing в /usage, строке состояния и OpenTelemetry. Разработчик, не подпадающий ни под одну политику, не получает управляемых настроек, поэтому его показатели остаются по прейскурантной цене. Клиенты применяют эту настройку в Claude Code v2.1.242 или новее.
- Что добавляет шлюз: если блок
cliполитики ещё не задаётmodelPricing, шлюз добавляетmultiplierи, для каждого ID модели, который может запросить клиент, строку переопределения первого upstream, обслуживающего этот ID. Тариф, который взимает только резервный upstream, остаётся на шлюзе. - Upstream со списком
groups: если такой upstream — первый, обслуживающий ID модели, шлюз не добавляет строку для этого ID. Тогда разработчики видят собственную ставку Claude Code для этого ID — стандартную ставку модели, если Claude Code распознаёт ID, — умноженную наmultiplier. - Исключение отдельной политики: установите
modelPricingв{}в блокеcliэтой политики, и её разработчики останутся на прейскурантных ценах. - Сохранение собственных тарифов политики: политика, блок
cliкоторой задаётmodelPricingс собственнымиmultiplierилиoverrides, сохраняет этотmodelPricingцеликом, и шлюз не добавляет в него свои тарифы.
models
Блок models — необязательный список моделей, курируемый администратором; он отдаётся на /v1/models и используется для преобразования ID моделей для каждого upstream. Он обязателен для регионов Amazon Bedrock за пределами США, ARN provisioned throughput в Amazon Bedrock и имён развёртываний Microsoft Foundry.
upstream_model должен совпадать с name настроенного upstream, которое по умолчанию равно имени провайдера. Ключ, не совпадающий ни с одним upstream, приводит к ошибке при запуске, поэтому опустите строки для провайдеров, которые вы не используете.
Чтобы разработчики могли использовать псевдоним fable при auto_include_builtin_models: false, добавьте запись claude-fable-5 в models. Это ID, в который псевдоним fable разрешается для разработчиков, вошедших через шлюз. Без неё их сообщения завершаются ошибкой, начинающейся с API Error: 400 model claude-fable-5 is not in the operator's model allowlist.
managed
Блок managed определяет политики доступа на основе ролей, привязанные к группам IdP или домену email. Политики оцениваются по порядку; по умолчанию выбирается первое совпадение, которое затем объединяется с базовой политикой match: {}, охватывающей всех. Пользователь, подпадающий под две ролевые политики, получает только первую, поэтому правила запрета второй политики не применяются, если вы не примените все подходящие политики. Политики обслуживаются для каждого пользователя по адресу GET /managed/settings с кэшированием ETag/304.
match: {}, которую по соглашению указывают последней, рассматривается как базовый слой. Любая другая политика наследует от неё каждый ключ, который сама не задаёт, поэтому в ролевых записях нужно перечислять только то, что отличается от значений по умолчанию для организации. Правила объединения зависят от типа ключа:
- Списки разрешённых:
availableModelsиpermissions.allow. Список конкретной политики полностью заменяет базовый. - Списки запрещённых и массивы хуков: берётся объединение базовой и конкретной политики:
permissions.denyиpermissions.askdisabledMcpjsonServersиdeniedMcpServersblockedMarketplacesиdeniedModels- Массивы типов событий
hooks
- Ключи типа record:
env,modelOverridesиskillOverrides. Они объединяются поверхностно, поэтому ролевой блокenvпереопределяет заданные в нём ключи, а остальные наследует от базы.
availableModels также применяется на стороне сервера на /v1/messages, поэтому запрещённая модель возвращает 400 независимо от того, что отправляет клиент. Пустой список запрещает все модели. Проверка также охватывает модель, с которой сессия начинается до того, как разработчик выберет модель, поэтому запускайте сессии на модели, разрешённой политикой.
Шлюз сам проверяет значение model, прежде чем передать запрос, поэтому некорректное значение никогда не достигает upstream. Он отклоняет запрос с 400 в двух случаях:
- Когда значение отсутствует или пустое, шлюз отклоняет запрос с сообщением
model is required. Для этой проверки нужен шлюз с Claude Code v2.1.228 или новее. - Когда значение присутствует, но не является строкой, шлюз отклоняет запрос с сообщением
model must be a string. Требуется шлюз с Claude Code v2.1.221 или новее.
Аутентифицированный пользователь, не подпадающий ни под одну политику, получает значения шлюза по умолчанию, то есть все модели из каталога и никаких управляемых настроек. Добавьте последней универсальную политику
match: {}, если вам нужна гарантированная политика по умолчанию.
Размещайте правила запрета на уровне организации в политике match: {}, потому что правила групповой политики применяются только пока токен пользователя содержит эту группу.
Шлюз не хранит собственного каталога пользователей. Он авторизует каждый запрос по токену IdP пользователя, считывая членство в группах из claim
groups токена и вычисляя политики по нему. Нет списка пользователей для перечисления и нет учётных записей для предварительного создания, а значит, нет и эндпоинта SCIM, потому что SCIM нечего синхронизировать.Управляйте жизненным циклом пользователей и групп в источнике истины — через встроенную подготовку SCIM вашего IdP или специализированную платформу управления учётными данными. Членство и отзыв доступа, управляемые там, автоматически попадают в шлюз через токен. Если вам нужна подготовка учётных записей Claude через SCIM, это возможность Claude for Enterprise.Действуют два срока распространения изменений:- Содержимое политики: изменение политики и повторное развёртывание доходят до подключённых клиентов Claude Code при их следующем опросе управляемых настроек, в течение часа, за исключением изменений, которые применяются только при следующем запуске
- Членство в группах: изменение членства пользователя в группах меняет то, какая политика с ним совпадает. Это вступает в силу при следующем перевыпуске сессии, то есть при следующем фоновом обновлении, не позднее
session.ttl_hours.
Применение всех подходящих политик
Пользователь, подпадающий под несколько ролевых политик, получает только первую, если вы не зададитеpolicy_mode: layered рядом с policies. С layered применяется каждая политика, под которую подпадает пользователь, вплоть до первой политики match: {}.
policy_mode требует Claude Code v2.1.316 или новее на сервере шлюза. Шлюз версии без поддержки этого ключа отказывается запускаться, обнаружив его. Обновите все реплики, прежде чем добавлять ключ, и удалите ключ перед откатом на более раннюю версию. В этом примере одна группа теряет WebFetch, а другая получает Opus:
no-web, и в opus-users, при режиме по умолчанию, first_match, и при layered.
Шлюз объединяет каждую подходящую политику с политиками, указанными ниже неё, по тем же правилам объединения, что и для базового слоя:
- Списки разрешённых, одиночные значения и блоки, такие как
sandbox: каждый берётся целиком из первой по порядку подходящей политики, которая его задаёт, поэтому спискиavailableModelsдвух групп не суммируются. - Списки запрещённых и массивы хуков: суммируются по всем подходящим политикам, поэтому пользователь в двух группах получает правила запрета обеих групп.
env,modelOverridesиskillOverrides: записи объединяются по имени, и значение для имени берётся из первой по порядку подходящей политики, которая его задаёт.- Ключи
desktop: объединяются по правилам для базового блокаdesktop.
layered шлюз отказывается запускаться при некоторых настройках, в том числе таких:
- Шаблон с
!: отрицание!в правилеReadилиEditв спискеpermissions.denyилиpermissions.askлюбой политики, включая политикуmatch: {} - Ограничение хуков вне политики, охватывающей всех:
disableAllHooks,allowedHttpHookUrlsилиhttpHookAllowedEnvVarsв любой политике, кромеmatch: {}
Запуск сессий на модели, разрешённой политикой
ЕслиavailableModels не включает модель Claude Code по умолчанию, сессии получают ответы 400, пока разработчик не выберет модель из списка, например с помощью /model. В сессиях через шлюз моделью по умолчанию является модель Opus, на которую указывает псевдоним opus, и availableModels сам по себе её не меняет.
Чтобы это исправить, установите enforceAvailableModels: true в том же блоке cli, а затем проверьте, какого рода записи содержит список:
- Псевдоним, например
sonnet, или встроенный ID, напримерclaude-sonnet-4-6: сессии запускаются на одной из этих моделей, и вариант Default в/modelуказывает на неё - В списке нет ни псевдонима, ни встроенного ID: сессии могут продолжать запускаться на встроенной модели по умолчанию, поэтому также установите
modelв один из перечисленных ID в блокеcliэтой политики
models, и запускает сессии на этом ID:
Значения matcher, которые останавливают шлюз при запуске
При запуске шлюз проверяет блокmatch каждой политики и список admin_groups. Любое из этих значений останавливает шлюз с ошибкой, в которой названо поле:
- Пустой список
groups - Пустой элемент в
groupsили вadmin_groups - Пустой
email_domain email_domain, содержащий@, пробельный символ или запятую. Перед этой проверкой шлюз обрезает значение и удаляет один начальный@. Укажите один домен без лишних символов, напримерexample.com.
- Пустой
email_domain: шлюз пропускал проверку домена, поэтому политика с пустымemail_domainи без спискаgroupsсовпадала с любым аутентифицированным пользователем - Пустой список
groups: политика не совпадала ни с кем email_domain, содержащий@, пробельный символ или запятую: политика не совпадала ни с кем- Пустой элемент в
groupsили вadmin_groups: элемент совпадал с пользователем, только если claimgroupsэтого пользователя в IdP тоже содержал пустой элемент. Вadmin_groupsтакое совпадение давало доступ администратора. Если ваш списокadmin_groupsникогда не содержал пустого элемента, никто не получил доступ администратора таким образом.
Выбор между cli и code
Настройки Claude Code для политики, например правило, запрещающее чтение файлов .env, помещаются в блок под ключом cli или code. code — рекомендуемый ключ, а cli — устаревший. Оба ключа принимают одинаковое содержимое. Ключ определяет, где применяются настройки:
cli: терминал, расширения VS Code и JetBrains, а также Agent SDK. Приcliвкладка Code в Claude Desktop получает производные настройки, поэтому ограниченное правило, напримерRead(./.env), не останавливает там пользователя.code: те же места, и при этом может быть охвачена вкладка Code в Claude Desktop.
cli, работает как раньше, а шлюз, обнаруживший cli в политике с ключом desktop, выдаёт предупреждение при запуске и всё равно запускается. Перейдите на code, чтобы настройки могли охватывать и вкладку Code.
Прежде чем переходить, прочитайте раздел Применение настроек code во вкладке Code. Политике нужен ключ desktop, а машины пользователей требуют настройки, прежде чем настройки начнут там действовать, и в Claude Desktop отключается веб-поиск.
Эта политика помещает правило запрета под code с пустым ключом desktop:
serve_to_desktop в той же правке, в которой переименовываете блоки. Там, где в инструкции упоминается блок cli, используйте ваш блок code.
serve_to_desktop: true — устаревший способ предложить настройки cli политики вкладке Code. Он не действует, когда Claude Desktop подключается через bootstrapUrl. Пока ваши политики используют cli, предупреждение при запуске, упоминающее этот ключ, означает, что эти настройки не доходят до вкладки Code:
- Чтобы охватить вкладку Code: перейдите на
code, как только машины пользователей будут соответствовать условиям из раздела Применение настроекcodeво вкладке Code - Чтобы остаться на
cli: установитеserve_to_desktop: falseрядом сcliв политике, чтобы убрать предупреждение
Что помещать в cli
Каждое значение code или cli — это полный документ managed-settings.json Claude Code, с той же схемой, которую вы развёртывали бы через MDM или /etc/claude-code/managed-settings.json, но записанный здесь в формате YAML. CLI применяет доставленный документ на управляемом уровне, выше пользовательских и проектных настроек, вместо управляемых настроек сервера. Поэтому он игнорирует настройки, доступные только из источников политик уровня ОС, такие как policyHelper и wslInheritsWindowsSettings.
Шлюз проверяет каждый документ по схеме настроек CLI при запуске, поэтому нераспознанный ключ верхнего уровня приводит к ошибке запуска с перечислением всех некорректных ключей. Намеренно открытые части схемы по-прежнему принимают произвольные значения, поскольку более новые клиенты могут распознавать записи, которых нет в схеме шлюза. К таким открытым ключам относятся env, pluginConfigs и ключи, вложенные в permissions.
Поскольку проверка использует схему, поставляемую с установленной версией шлюза, чтобы поместить в управляемую конфигурацию ключ настроек верхнего уровня, появившийся в более новом выпуске Claude Code, сначала нужно обновить шлюз. Проверьте новую политику на одном клиенте, прежде чем развёртывать её.
Полный справочник ключей находится в разделе Настройки Claude Code. Ключи, к которым операторы обращаются в первую очередь:
Поскольку эти настройки приходят по сети, CLI показывает каждому разработчику диалоговое окно подтверждения безопасности, прежде чем применить перечисленные ниже настройки:
hooks- переменные
env, требующие подтверждения разработчика, например переменные прокси и базового URL - настройки выполнения команд оболочки, такие как
apiKeyHelperиstatusLine - настройки бинарных файлов песочницы
sandbox.bwrapPath,sandbox.socatPathиsandbox.ripgrep - Настройки песочницы, которые перехватывают трафик, внедряют учётные данные или ослабляют изоляцию, например
sandbox.network.tlsTerminateи настройки портов прокси. Полный список приведён в разделе Диалоговые окна подтверждения безопасности.
env, например настройки выбора модели и числовые ограничения, Claude Code применяет, не показывая разработчику диалоговое окно подтверждения. Другие доставленные переменные могут требовать подтверждения разработчика; непустое значение прокси, базового URL или OTEL_EXPORTER_OTLP_ENDPOINT требует его всегда. Когда доставленная переменная требует подтверждения, она указывается в диалоговом окне. Подробности, включая четыре переключателя конфиденциальности, для которых необходимость подтверждения зависит от доставленного значения, приведены в разделе Переменные окружения и диалоговое окно подтверждения.
Конфигурация телеметрии шлюза передаёт OTEL_EXPORTER_OTLP_ENDPOINT, поэтому установка telemetry.forward_to вызывает диалоговое окно на каждом интерактивном клиенте. Диалоговое окно защищает машину разработчика от скомпрометированного или враждебного шлюза, а не организацию от разработчика.
Неинтерактивный запуск, например claude -p, сессия Agent SDK или сессия во вкладке Code в Claude Desktop, не может показать диалоговое окно. Он применяет переданные настройки только для этого запуска и не записывает их как подтверждённые, поэтому следующая интерактивная сессия разработчика всё равно покажет диалоговое окно.
Если разработчик отказывается, Claude Code завершает эту сессию, а не применяет политику. Поэтому, когда вы передаёте новый хук или любую переменную окружения, вызывающую диалоговое окно, в широкую политику, каждый подпадающий разработчик увидит диалоговое окно в своих интерактивных сессиях. Работающая интерактивная сессия показывает его при следующем ежечасном опросе, а в остальных случаях оно появляется при следующем интерактивном запуске у разработчика.
В более ранних выпусках ключ cli назывался settings, и шлюз по-прежнему принимает это написание как псевдоним. Для новых развёртываний используйте code.
Проверка политики перед развёртыванием
Чтобы проверить изменение политики, запустите шлюз с временной базой данных Postgres. Шлюз подключается к Postgres и применяет миграции схемы, прежде чем проверять содержимое блоковcli, code и desktop. Если база данных недоступна, запуск останавливается на could not connect to Postgres и ничего не сообщает об их содержимом.
Контекстное окно в сессиях терминала
Сессии терминала, выполненные со входом через/login, используют контекстное окно 1M для Opus 4.7 и новее, Sonnet 5 и новее, а также моделей Fable. ID модели не требует суффикса [1m], и сессии сжимаются при достижении примерно 967K токенов. До Claude Code v2.1.287 на машине разработчика Claude Code считал, что у моделей Opus и Fable окно 200K, если ID модели не заканчивался на [1m].
Чтобы сессии терминала вместо этого сжимались на границе 200K, задайте окно автосжатия в env политики:
[1m].
Чтобы вместо этого отключить контекст 1M, установите CLAUDE_CODE_DISABLE_1M_CONTEXT: "1" в том же блоке env. Тогда Claude Code считает, что у каждой модели окно 200K. В интерактивных сессиях каждый разработчик подтверждает эту переменную в диалоговом окне подтверждения, прежде чем она вступит в силу.
Часовой кэш промптов
Чтобы запрашивать часовой TTL кэша промптов вместо пятиминутного по умолчанию, добавьте эти ключи в существующий блокcode, cli или settings политики и перезапустите шлюз. Ключам нужен Claude Code v2.1.242 или новее на сервере шлюза и на клиентах.
promptCacheTtl охватывает основной диалог. subagentPromptCacheTtl необязателен и охватывает субагентов, workflows и фоновые запросы. В этом примере оба ключа добавляются в политику match: {} с ключом cli:
promptCacheTtl, войдите в шлюз как пользователь, подпадающий под политику, и проверьте, какой TTL использовали ваши записи в кэш. Передайте --model, чтобы повторить проверку для каждой модели, которую обслуживает шлюз.
Часовые записи в кэш стоят дороже, чем пятиминутные. Чтобы лимиты расходов учитывали этот повышенный тариф, нужна v2.1.286 или новее на сервере шлюза.
MCP-серверы в политике
Чтобы предоставить MCP-серверы клиентам Claude Code, подпадающим под политику, задайтеmanagedMcpServers в блоке cli этой политики. Нужен Claude Code v2.1.259 или новее на сервере шлюза и на клиентах.
Шлюз проверяет каждую запись при запуске по тем же правилам, которые Claude Code применяет на клиенте, и если запись не проходит проверку, шлюз отказывается запускаться и называет эту запись.
Если вы пишете ссылку ${VAR} в gateway.yaml, шлюз разрешает её из своего окружения при запуске через подстановку секретов до проверки записей, поэтому каждый подпадающий клиент получает буквальное значение и может его прочитать. Рекомендации по заголовкам для предоставляемых серверов относятся к подставленному значению.
Шлюз отклоняет написание mcpServers из .mcp.json в блоке cli, и в его ошибке запуска в качестве нужного ключа указан managedMcpServers. До v2.1.259 шлюз отклонял любое определение MCP-сервера в блоке cli.
Наложение для Claude Desktop
Если ваша организация также развёртывает Claude Desktop, один и тот же шлюз обслуживает оба клиента. НаправьтеbootstrapUrl в управляемой конфигурации Claude Desktop на <listen.public_url>/user/bootstrap. Claude Desktop выводит издателя OAuth из этого URL, выполняет тот же вход по коду устройства через этот шлюз и получает свою конфигурацию из ответа.
Требует Claude Code v2.1.203 или новее на сервере шлюза и явного включения:
/user/bootstrap возвращает 404, если политика, под которую подпадает пользователь, не содержит ключа desktop. Пустой desktop: {} включает политику, а ключ desktop в базовом слое match: {} включает каждую политику, которая его наследует. Журнал аудита записывает каждый запрос как desktop_bootstrap.serve или desktop_bootstrap.denied.desktop в своих политиках; тогда шлюз возвращает 404 на /user/bootstrap для каждого пользователя.
Настройки, которые шлюз выводит для Claude Desktop
Шлюз выводит бо́льшую часть ответа bootstrap из блокаcli или code совпавшей политики и из конфигурации шлюза верхнего уровня:
-
Список моделей — из
availableModels. В список не входят модели, которые политика блокирует с помощьюdeniedModelsилиavailableModelsMatch: exact. Этот фильтр требует Claude Code v2.1.299 или новее на сервере шлюза. Вариант контекста 1M для каждой модели описан в разделе Расширенный контекст в Claude Desktop -
Отключённые инструменты — из записей
permissions.deny, содержащих только имя инструмента. Если вы задаётеdisabledBuiltinToolsв блокеdesktopполитики, шлюз отдаёт объединение вашего значения и выведенного списка, поэтому так можно отключить больше инструментов, но нельзя снова включить инструмент, отключённый черезpermissions.deny -
Список разрешённых адресов для исходящего трафика — из
sandbox.network.allowedDomains. Если вы задаётеcoworkEgressAllowedHostsв блокеdesktopполитики, шлюз использует это значение вместо выведенного списка. Если список разрешённых, который отдаёт шлюз, включает*и шлюз при этом не отдаётallowedWorkspaceFoldersдля Claude Desktop, Claude Desktop не включает песочницу Bash во вкладке Code -
Эндпоинт OTLP, указывающий на сам шлюз, и атрибуты идентичности вошедшего пользователя. Шлюз пересылает экспорты, полученные на этом эндпоинте, в ваши назначения
forward_to. Он включает эндпоинт и атрибуты, когда вы задаёте иtelemetry.forward_to, иlisten.public_url. Claude Desktop экспортирует все сигналы в одной кодировке:http/protobufилиhttp/json, если вы установилиOTEL_EXPORTER_OTLP_PROTOCOLили один из его вариантов для отдельных сигналов вhttp/jsonвenvполитики. До Claude Code v2.1.261 на сервере шлюза ответ в любом случае задавалhttp/json, поэтому коллектор, принимающий только protobuf, отклонял экспорты Claude Desktop
disabledBuiltinTools, coworkEgressAllowedHosts или собственную настройку managedMcpServers Claude Desktop в блоке desktop политики, нужен Claude Code v2.1.232 или новее на сервере шлюза. managedMcpServers в Claude Desktop принимает значение-массив, а не объект.
Шлюз не включает в ответ bootstrap ключи, не имеющие эквивалента в Claude Desktop, например hooks и ограниченные правила разрешений вроде Bash(npm *).
Применение настроек code во вкладке Code
Настройки Claude Code, которые политика содержит под ключом code, применяются во вкладке Code в Claude Desktop, когда выполняются все следующие условия:
- У политики также есть ключ
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: вкладка Code запускается без ваших настроек
code, независимо от версии, с которой поставляется Claude Desktop
/managed/settings собственным 404, вкладка Code также запускается без ваших настроек code, в том числе на машине, соответствующей всем четырём условиям.
В политике с ключом desktop блок code, содержащий настройки, отключает инструмент WebSearch в Cowork, Chat и вкладке Code. О MCP-серверах см. Где применяется managedMcpServers.
Прямое задание настроек Claude Desktop
Добавьте необязательный блокdesktop рядом с cli, чтобы задавать настройки Claude Desktop напрямую. Указывайте настройки из справочника управляемой конфигурации Claude Desktop в виде плоских имён ключей. Не указывайте ключи, которые Claude Desktop читает только из MDM или локальных файлов, например bootstrapUrl; шлюз отклоняет их при запуске.
В этом примере для группы eng-contractors задаются три ключа Claude Desktop наряду с её настройками cli:
Что шлюз отклоняет при запуске
Шлюз проверяет каждый блокdesktop при запуске по той же схеме конфигурации, которую использует сам Claude Desktop, поэтому ошибка проявляется при запуске шлюза в виде сообщения с именем ключа, а не доходит до каждого подключённого десктопа. Запуск шлюза завершается ошибкой, когда блок содержит:
- Неизвестный ключ
- Распознанный ключ, значение которого Claude Desktop отклонил бы или молча отбросил, например пустое значение или подключ с опечаткой внутри вложенной записи. До v2.1.260 шлюз молча отбрасывал поле с опечаткой внутри вложенного объекта записи
managedMcpServersилиorgPluginSettings, вместо того чтобы завершаться ошибкой при запуске. - Ключ, который шлюз вычисляет сам: подключение для инференса, список моделей и ретрансляция OTLP. Настраивайте их через
upstreams,modelsиforward_toв разделеtelemetry. - Устаревший псевдоним текущего ключа. В ошибке запуска шлюз называет канонический ключ, который нужно указать.
managedMcpServers без transport, шлюз запускается и записывает в лог предупреждение с названием замены.
До v2.1.232 шлюз принимал фиксированный список из 11 ключей-флагов функций, например chatTabEnabled и disableAutoUpdates, и отклонял все остальные ключи при запуске. До v2.1.227 шлюз также отклонял при запуске chatTabEnabled и chatAdvancedFileAnalysisEnabled.
Ключи, требующие более новой версии шлюза или Claude Desktop
Шлюз проверяет блок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 или новее на сервере шлюза. То же относится к значению required для microsoftAuthBroker и полю continuousAccessEvaluation записи managedMcpServers для Microsoft 365. Выпуски Claude Desktop, вышедшие до появления значения required, читают его как disabled, поэтому задавайте required только после того, как Claude Desktop у каждого участника будет его поддерживать. В справочнике управляемой конфигурации Claude Desktop указан выпуск, который первым читает каждый ключ.
sshTransport требует Claude Code v2.1.293 или новее на сервере шлюза.orgPluginSettings в блоке desktop политики, шлюз отдаёт его в форме массива, которую читает Claude Desktop 1.15200.0 и новее. Более старые десктопы игнорируют массив и не применяют никакой политики инструментов плагинов, поэтому обновите участников до 1.15200.0 или новее, прежде чем на это полагаться.
Как ролевая политика наследует базовый блок desktop
Шлюз заполняет ключи, которые блок desktop политики не задаёт, из блока desktop универсальной политики match: {}, так же как он заполняет блок 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 минут бездействия
relaunchEnforcementHours в блоке desktop политики. Нужен 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, когда:
- Upstream, способный обслуживать запись, сопоставляет её с моделью без поддержки 1M, включая upstream, к которому шлюз обращается только при отказе основного
- Ни её
id, ни одно из значенийupstream_modelне называет модель Claude, например пользовательский псевдоним, направленный на ARN профиля инференса приложения
- Запуск пользователей на варианте 1M: установите
modelPrefer1mContext: trueв блокеdesktopполитики. Пользователи, ещё не выбравшие модель, начинают с варианта 1M, если он есть у первой указанной модели. Пользователи, уже выбравшие модель, сохраняют свой выбор. - Ручное предложение варианта: сделайте это, если сервер шлюза работает на версии старше v2.1.284 или запись не называет модель Claude. Укажите модель в
modelsдважды: один раз с простым ID и один раз с добавленным[1m], оба раза с одной и той же картойupstream_model. Claude Desktop показывает пару как одну модель с вариантом 1M. Шлюз отдаёт запись[1m]без проверки, поэтому добавляйте её только для модели, которую ваши upstream обслуживают с 1M.
Удаление варианта 1M
Чтобы убрать этот вариант из окна выбора, установитеCLAUDE_CODE_DISABLE_1M_CONTEXT: "1" в блоке env под ключом cli политики. Если вы также указали запись, id которой заканчивается на [1m], шлюз по-прежнему её отдаёт, поэтому удалите и эту запись.
Переменная также доходит до сессий терминала разработчиков, подпадающих под политику. О том, что она там меняет, см. Расширенный контекст.
Приоритет относительно других управляемых источников
Если на устройстве также есть политика, доставленная через MDM, или локальныйmanaged-settings.json, настройки, доставленные шлюзом, имеют наивысший приоритет. Раздел Приоритет внутри управляемого уровня на странице управляемых настроек объясняет, когда применяются локальные источники, и содержит ключи, которые Claude Code читает из каждого административного источника независимо от того, какой источник он выбрал, например ключи блокировки песочницы, forceRemoteSettingsRefresh и объединение env по отдельным переменным. policyHelper, настроенный в профиле MDM или файле управляемых настроек, выполняется, только когда шлюз не доставляет никаких настроек; в его описании указано, что заменяет его вывод.
Встраивающие хосты, такие как Claude Desktop, могут передавать политику через параметр SDK managedSettings. Раздел Родительские настройки от встраивающих хостов объясняет, когда Claude Code её применяет, а в разделе Ограничение родительских настроек перечислено, какие разрешающие настройки по-прежнему применяются без блокировок allowManaged*Only.
Политики шлюза применяются к каждому вызову Claude Code на машине, включая неинтерактивные запуски claude -p и сессии, порождённые Agent SDK. Если шлюз недоступен при запуске, сессии с выполненным входом завершаются с ошибкой, а не работают без своей политики.
telemetry
CLI отправляет метрики, логи и, если включено, трассировки на шлюз, который дословно пересылает их в каждое настроенное назначение. Экспорт использует OpenTelemetry Protocol (OTLP) поверх HTTP. Чтобы обойти ретрансляцию и экспортировать данные сессий напрямую в ваш коллектор, укажите коллектор в политике. Метрики и события, которые генерирует CLI, описаны в разделе Мониторинг использования.
В сессиях с выполненным входом через /login CLI помечает каждый экспорт идентичностью аутентифицированного пользователя, считанной из JWT, выданного шлюзом: атрибутами user.id, user.email и user.groups. Поэтому учёт затрат и использования по разработчикам работает без какой-либо настройки на стороне разработчика. События, которые Claude Code записывает в лог до входа разработчика, не содержат этой идентичности. О том, какой атрибут отражает изменение групп разработчика, см. Изменение групп во время открытой сессии.
Сессии Claude Desktop и Cowork с выполненным входом через шлюз помечают свою телеметрию атрибутами user.email и user.groups наряду с enduser.id, поэтому вы можете охватить использование терминала, Desktop и Cowork одним запросом по user.email или user.groups. user.groups — список групп IdP, разделённый запятыми.
Телеметрия Desktop и Cowork также содержит enduser.sub — claim sub, который ваш провайдер идентификации выдаёт пользователю и который не меняется при смене email пользователя. Сессии терминала помечают то же значение как user.id, поэтому запрос, сопоставляющий enduser.sub с user.id терминала, охватывает использование терминала, Desktop и Cowork одним пользователем вместе. В экспортах Desktop и Cowork user.id — анонимный идентификатор, а не субъект.
Как и все данные OpenTelemetry из Claude Code, эти атрибуты отправляются только в назначения, настроенные вашей организацией, и никогда не отправляются в Anthropic.
Если список групп пользователя длиннее 255 символов после процентного кодирования или имя группы содержит запятую или знак равенства, шлюз не включает user.groups в телеметрию Desktop и Cowork этого пользователя, а не обрезает список. Сессии терминала этого пользователя по-прежнему содержат полный список.
Шлюз не включает enduser.sub, если субъект длиннее 255 символов после процентного кодирования или содержит пробел, символ вне печатаемого ASCII или один из символов , ; = \ " %. Телеметрия Desktop и Cowork этого пользователя сохраняет остальные атрибуты.
Для user.email и user.groups в телеметрии Desktop и Cowork нужен Claude Code v2.1.265 или новее на сервере шлюза, а для user.groups — Claude Desktop 1.24012 или новее на машине каждого разработчика.
Для enduser.sub нужен Claude Code v2.1.274 или новее на сервере шлюза.
forward_to должен использовать https://, за одним исключением — для коллектора на собственном loopback-интерфейсе шлюза:
http://localhost:<port>проходит проверку конфигурации, но защита от SSRF блокирует каждый экспорт сECONNREFUSED_SSRF, если вы не установитеCLAUDE_GATEWAY_ALLOW_LOOPBACK=1в окружении шлюзаhttp://127.0.0.1:<port>илиhttp://[::1]:<port>приводят к ошибке запуска, если эта переменная не установлена
HTTPS_PROXY, шлюз отправляет экспорты через этот прокси.
Чтобы обращаться к внутреннему коллектору напрямую, добавьте его в NO_PROXY по имени хоста или по домену с начальной точкой, например .internal.example.com, что требует 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, каждая из которых имеет значениеotlp, если хотя бы одно назначениеforward_toвключает этот сигнал, иnoneв противном случаеOTEL_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 в политике этой группы.
Пересылаются обе кодировки OTLP — protobuf и JSON, и в качестве назначения подходит любой бэкенд, совместимый с OpenTelemetry.
Отправка кумулятивных метрик
Если ваш коллектор принимает только кумулятивные метрики, установитеOTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE в cumulative. По умолчанию Claude Code отправляет дельта-метрики, а шлюз пересылает их без преобразования. Задайте переменную там, где её читает каждый вид сессий:
- Сессии терминала: в блоке
envпод ключомcliилиcodeполитики - Сессии Cowork, которые выполняются на машине пользователя: в блоке
envуправляемых настроек на стороне клиента на этой машине - Сессии вкладки Code под политикой
code: в блокеenvполитики, как только вы выполните условия применения настроекcode - Сессии вкладки Code под политикой
cli: в блокеenvуправляемых настроек на стороне клиента на машине, которая выполняет сессию. При работе через SSH это удалённый хост.
parentSettingsBehavior: "merge" в источнике с наивысшим приоритетом на этой машине. Без этого сессии Cowork и сессии вкладки Code под политикой cli работают без списка разрешённых адресов для исходящего трафика и других политик, которые 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, передаваемой вместе с другими переменными телеметрии. Если вы задаёте OTEL_RESOURCE_ATTRIBUTES в блоке env политики, сессии терминала, подпадающие под эту политику, получают это значение вместо меток. Claude Desktop получает метки от шлюза вместе с user.email и другими атрибутами идентичности.
Claude Code также копирует каждую метку в каждую точку данных метрики, чтобы вы могли фильтровать по ней метрики в бэкенде, который не индексирует атрибуты ресурса. Чтобы отключить это копирование, см. Управление кардинальностью метрик.
Изменение групп во время открытой сессии
Сессии терминала помещаютuser.groups в ресурс OTLP и повторно в каждую точку данных метрики и каждое событие. Если группы разработчика меняются, пока сессия открыта, точки данных и события для использования после следующего фонового обновления содержат новые группы. Ресурс сохраняет старые группы, пока разработчик не перезапустит Claude Code, поэтому группируйте по атрибуту в точке данных или событии.
Если вы включаете resource_to_telemetry_conversion в экспортёре Prometheus remote write в OpenTelemetry Collector, экспортёр заменяет user.groups каждой точки данных значением из ресурса, поэтому каждая точка данных показывает старые группы. Чтобы сохранить значение точки данных, удалите user.groups из ресурса до этого экспортёра.
Этот процессор resource OpenTelemetry Collector удаляет атрибут в конвейерах, где он указан:
resource/drop-user-groups в processors конвейера метрик каждый ряд содержит метку user_groups из собственной точки данных.
Экспорт напрямую в ваш коллектор
Чтобы сессии, в которые выполнен вход через/login, отправляли телеметрию напрямую в ваш коллектор, а не через ретранслятор, задайте OTEL_EXPORTER_OTLP_ENDPOINT как базовый URL коллектора с https:// в блоке env управляемой политики. Claude Code добавляет /v1/metrics, /v1/logs или /v1/traces к заданному вами URL, например https://otel-collector.example.com:4318, и экспортирует туда каждый сигнал по OTLP/HTTP. Требуется Claude Code v2.1.265 или новее на машине каждого разработчика. Более ранние клиенты экспортируют через ретранслятор.
Для аутентификации в коллекторе задайте OTEL_EXPORTER_OTLP_HEADERS в том же блоке env. Сессии никогда не отправляют токен сессии шлюза разработчика в коллектор, указанный таким образом.
Когда вы добавляете или изменяете этот эндпоинт в политике, Claude Code просит каждого разработчика подтвердить его в диалоге подтверждения безопасности, прежде чем применить его в интерактивной сессии.
Claude Code проверяет эндпоинт перед тем, как экспортировать сигнал напрямую, и оставляет этот сигнал на ретрансляторе, если проверка не пройдена. Проверки включают:
- Эндпоинт поступает от самого шлюза. Если вы задаёте ту же переменную в профиле MDM или в локальном
managed-settings.json, экспорт остаётся на ретрансляторе. - URL использует
https://либо, для loopback-адреса,http:// - URL разрешается в путь, заканчивающийся на
/v1/<signal>, без строки запроса и фрагмента. Claude Code сам строит этот путь из общей переменной. Переменную для отдельного сигнала, такую какOTEL_EXPORTER_OTLP_METRICS_ENDPOINT, он использует как есть, поэтому указывайте в ней полный путь. - URL не является собственным хостом шлюза. Эндпоинт, адресованный шлюзу, сохраняет путь через ретранслятор и его токен сессии.
- Ни вы, ни разработчик не настроили
otelHeadersHelperни в одном источнике настроек. Если helper настроен, все сигналы остаются на ретрансляторе.
OTEL_*_EXPORTER.
Сам по себе эндпоинт не включает экспорт, поэтому также задайте переменные, которые это делают, если шлюз ещё не передаёт их:
- Если шлюз уже передаёт переменные телеметрии, они покрывают включение, селекторы и протокол, а ваш явно заданный эндпоинт переопределяет переданное значение
<public_url>. Устанавливайте селекторOTEL_*_EXPORTERвotlpсамостоятельно только для сигнала, который не включает ни одно назначениеforward_to. - Если нет, также задайте
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, а также любые другие внутренние диапазоны, из которых подключаются ваши разработчики. Если вы привязываете шлюз к loopback-адресу и не задаёте ниtrusted_proxies, ниpublic_url, как при локальной разработке, предупреждение не появляется. - Во время работы: когда впервые поступает запрос с адреса вне этих частных диапазонов, шлюз записывает в лог предупреждение и генерирует событие аудита
access.public_clientс IP клиента. Оба срабатывают один раз за процесс. Link-local адреса,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 токенов текста, передаваемым потоком около 10 секунд:
Нагрузочный тест в этом режиме охватывает шлюз, ваш Postgres и всё, что стоит перед шлюзом. Он не охватывает ограничения, скорость и сетевой путь провайдера, а также ожидание на ограничении числа одновременных запросов к вышестоящему серверу каждой реплики. Реплика по-прежнему записывает в лог предупреждение
client requests are open, когда открытых запросов больше этого ограничения — порога, при котором запросы в рабочей среде начинают ждать.
Запросы к модели не отправляются провайдеру, поэтому загрузка CPU реплики на запрос является оценочной и оказывается ниже, чем в продакшене, где трафик к провайдеру ещё и шифруется. Подтвердите количество реплик небольшим пилотом с реальным провайдером. До v2.1.283 оценка оказывается значительно ниже.
Пока режим включён, запрос может содержать заголовок x-load-test-user с целым числом длиной до семи цифр. Шлюз считает каждое число отдельным разработчиком с адресом электронной почты и группами того разработчика, чей токен пришёл с запросом.
Выделите развёртыванию для нагрузочного тестирования собственную пустую базу данных, поскольку шлюз отказывается запускаться с включённым режимом на базе данных, в которой какой-либо разработчик уже что-то потратил.
Полный пример
Этот полный справочный конфиг использует каждый основной раздел; блоки настройки HTTP сохраняют свои значения по умолчанию. Скопируйте его, удалите то, что вам не нужно, и заполните свои значения. Конфиг в Quickstart — это минимальная версия этого.gateway.yaml
Управляемые параметры на стороне клиента
Всё выше настраивает сервер gateway. Указание машин разработчиков на него настраивается отдельно, на каждом устройстве, через управляемые параметры Claude Code. Gateway не может отправлять эти ключи сам, потому что они говорят клиенту, где находится gateway. Для CLI установите эти ключи вmanaged-settings.json для каждой ОС. Два ключа входа маршрутизируют /login каждого разработчика на ваш gateway:
parentSettingsBehavior: "merge" сохраняет доставку Claude Desktop списка разрешённых исходящих соединений в его встроенные сеансы Claude Code; Доставка политики в сеансы Claude Desktop объясняет механизм и где должно находиться согласие.
Чтобы помешать разработчикам обойти gateway с помощью переменной облачного провайдера или собственного ANTHROPIC_BASE_URL, добавьте "allowedProviders": ["gateway"] в тот же файл. Claude Code затем отказывает в каждом сеансе на машине, который не настроен для Cloud gateway, и допускает gateway только когда это тот, который называет forceLoginGatewayUrl, или тот, чей URL файл устанавливает в блоке env как ANTHROPIC_BASE_URL. claude gateway отказывается запускаться на машине, которая устанавливает список, поэтому держите ключ отключённым на хосте gateway. См. запись allowedProviders в справочнике параметров. Требуется Claude Code v2.1.285 или позже.
Развёртывайте файл managed-settings.json на каждое устройство, обычно через вашу платформу MDM. Путь файла отличается по платформе. См. где каждый механизм хранит политику.
По умолчанию политика реестра в Windows или управляемые предпочтения plist в macOS заменяют файл managed-settings.json вместо слияния с ним, за исключением ключей исключения и проверок между источниками выше. Все три ключа в этом фрагменте следуют правилу источника с наивысшим приоритетом, поэтому парки, которые доставляют политику через Group Policy или профили конфигурации, должны поместить все три в этот механизм вместо этого.
Для Claude Desktop установите ключ bootstrapUrl в собственной управляемой конфигурации Claude Desktop на <listen.public_url>/user/bootstrap. Поток входа и политика для каждой группы затем совпадают с CLI после того, как политика на стороне сервера даёт согласие ключом desktop; без этого согласия /user/bootstrap возвращает 404. См. Наложение Claude Desktop для серверной части.
Claude Code учитывает forceLoginGatewayUrl, gatewayInternalNetworks и значение "gateway" ключа forceLoginMethod из управляемого источника на машине: managed-settings.json, plist macOS или реестра HKLM Windows либо помощника политики. Установка их в данных, передаваемых шлюзом, не настраивает вход через шлюз. Для собственного ~/.claude/settings.json разработчика см. Установка URL шлюза в пользовательских настройках.
Оставьте forceLoginMethod и forceLoginOrgUUID вне полезной нагрузки. Claude Code по-прежнему читает оба ключа из полезной нагрузки для проверки учётных данных при запуске, поэтому разработчик, который хранит выданные Anthropic учётные данные на машине, получает выход при запуске, описанный в разделе Политика администратора требует вход в Cloud gateway даже после того, как они вошли.
Связанное
- Обзор Claude apps gateway: quickstart и подключение разработчика
- Руководство по развёртыванию: настройка IdP, образ контейнера, Kubernetes и Cloud Run, и операции
- Лимиты расходов: ограничения для каждого разработчика и Admin API