Конфигурация Claude apps gateway
Справочник по каждому параметру gateway.yaml: listener и TLS, OIDC, session, хранилище Postgres, upstreams Amazon Bedrock, Claude Platform на AWS, Agent Platform Google Cloud и Microsoft Foundry, маршрутизация моделей, управляемые политики и телеметрия.
Развёртывание Claude apps gateway настраивается одним файлом YAML, обычно 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
Опциональные разделы:
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 разрешит значение при загрузке из переменной окружения или файла:
| Форма | Разрешается в | Используется для |
|---|---|---|
${VAR} |
Переменная окружения VAR. Загрузка не удаётся, если не определена. |
Переменные окружения контейнера, AWS Secrets Manager через внедрение env |
${file:/path} |
Содержимое файла по этому абсолютному пути, обрезано. Ссылка должна быть полным значением поля: в отличие от ${VAR}, она не расширяется внутри более длинной строки, поэтому для пароля базы данных установите store.password вместо встраивания его в postgres_url. |
Монтирования томов Kubernetes Secret, Vault Agent, SOPS |
Обязательные разделы
`listen`
Блок listen определяет, где шлюз принимает запросы: адрес и порт привязки, видимый извне origin и необязательное завершение TLS.
| Поле | Обязательно | Описание |
|---|---|---|
host |
Нет | Адрес привязки. По умолчанию 0.0.0.0. |
port |
Нет | Порт привязки. По умолчанию 8080. |
public_url |
Если host не loopback |
Видимый извне origin https://, из которого формируются redirect_uri для IdP и метаданные обнаружения. Обязателен всякий раз, когда host не является loopback-адресом, независимо от того, завершается ли TLS на прокси, таком как ALB, Ingress или Cloud Run, или на самом шлюзе через tls, потому что шлюз никогда не выводит собственный origin из заголовков X-Forwarded-*: клиент может их подделать. Без него шлюз не запустится. Параметр trusted_proxies ниже управляет только определением IP-адреса клиента. Также обязателен для включения телеметрии, потому что шлюз формирует из этого URL эндпоинт OTLP, который передаёт клиентам. |
tls.cert / tls.key |
Нет | Пути к PEM-файлам, если шлюз сам завершает TLS |
trusted_proxies |
Нет | CIDR или IP-адреса балансировщиков нагрузки перед шлюзом. Если задан, шлюз доверяет X-Forwarded-For только от этих узлов и записывает реальный IP-адрес клиента для ограничения частоты запросов по IP и аудита. Эквивалент set_real_ip_from в nginx. Записи X-Forwarded-For в виде ipv4:port или [ipv6]:port, как их пишут некоторые балансировщики нагрузки, читаются без порта. IPv6-адрес с добавленным портом без квадратных скобок может быть прочитан как другой адрес или не прочитан вовсе, поэтому отключите опцию порта на любом прокси, который пишет адреса в такой форме. |
`oidc`
Блок oidc подключает шлюз к вашему поставщику идентификации и определяет, кто может входить. В нём указываются издатель и OAuth-клиент, задаются claims, содержащие email и группы, и вход ограничивается по домену email или по группе.
OpenID Connect (OIDC) — это протокол SSO, который шлюз использует для работы с вашим поставщиком идентификации; что нужно зарегистрировать на стороне IdP, см. в разделе Настройка поставщика идентификации.
| Поле | Обязательно | Описание |
|---|---|---|
issuer |
Да | Базовый URL обнаружения OIDC. Документ обнаружения должен отдаваться по пути /.well-known/openid-configuration. В production используйте HTTPS; шлюз принимает издателя http://. Loopback-издатель, например http://localhost:8081, отклоняется защитой от SSRF, если в окружении шлюза не задано CLAUDE_GATEWAY_ALLOW_LOOPBACK=1. |
client_id |
Да | Из регистрации OAuth-клиента |
client_secret |
Если token_endpoint_auth_method не равен private_key_jwt |
Из регистрации OAuth-клиента. Не указывайте его, если используете аутентификацию клиента по сертификату. |
allowed_email_domains |
Нет | Отклонять id_token, claim email которых не относится ни к одному из этих доменов, без учёта регистра. Дополнительная защита от ошибок конфигурации мультитенантного IdP. Независимо от этой настройки id_token, claim email_verified которого явно равен false, всегда отклоняется. |
allowed_groups |
Нет | Разрешить вход только участникам этих групп IdP, сопоставляемых с groups_claim. Пользователь из разрешённого домена email, не входящий ни в одну из этих групп, отклоняется. Требует, чтобы IdP выдавал claim групп. Сопоставление — это точное сравнение строк с учётом регистра со значениями в этом claim, и шлюз не раскрывает вложенные группы: чтобы допустить участников подгруппы, укажите подгруппу здесь или настройте IdP на выдачу развёрнутого членства. |
groups_claim |
Нет | Какой claim id_token содержит членство в группах. По умолчанию groups. Microsoft Entra выдаёт роли приложения в roles. Принимает простой ключ или RFC 6901 JSON Pointer, например /resource_access/gateway/roles, для вложенных claims. |
google_groups |
Нет | Получать группы вошедшего пользователя через Google Workspace Admin SDK Directory API, поскольку id_token Google не содержит claim групп. Укажите в service_account_json_path файл ключа сервисного аккаунта с делегированием на уровне домена для scope https://www.googleapis.com/auth/admin.directory.group.readonly, а в admin_email — администратора Workspace, от имени которого действует сервисный аккаунт; Directory API требует реального субъекта-администратора. Email-адреса групп каждого пользователя становятся его claim групп, поэтому allowed_groups и managed.policies.match.groups сопоставляются с email-адресами групп. |
email_claim |
Нет | Какой claim id_token содержит email пользователя. По умолчанию email. Некоторые IdP, например ADFS и Entra B2C, вместо него выдают upn или preferred_username. Принимает простой ключ, JSON Pointer или список резервных ключей, из которых используется первый присутствующий. |
scopes |
Нет | Полное переопределение scope OIDC, которые запрашивает шлюз. По умолчанию [openid, profile, email, offline_access]. Задайте, если ваш IdP отклоняет нераспознанные scope или требует пользовательский scope для выдачи групп или email. Должен включать openid. Без offline_access refresh-токены отключаются, и разработчикам приходится заново проходить вход в браузере каждые session.ttl_hours. Рецепты scope для отдельных IdP, например для потока refresh-токенов Google, см. в разделе Настройка поставщика идентификации. |
scope_on_refresh |
Нет | Также отправлять scope с тем же списком, что и в запросе входа, когда шлюз обменивает refresh-токен. По умолчанию false: запрос обновления не содержит scope. Большинство IdP возвращают id_token при каждом обновлении, и им это не нужно. Задайте true, если ваш IdP возвращает id_token при обновлении, только когда снова запрошен openid, как Okta описывает для своего refresh grant. Без id_token каждое обновление зависит от того, примет ли эндпоинт userinfo IdP обновлённый access-токен. Если вы ограничиваете вход или сопоставляете политики по группам, а id_token вашего IdP при обновлении их не содержит, также задайте userinfo_fallback: true, чтобы шлюз получал их из эндпоинта userinfo. IdP, предоставивший меньше scope, чем запрошено, может отклонить обновление с invalid_scope, в том числе для существующих сессий, если при включённой настройке вы добавите записи в scopes. Удалите ключ, если после его установки обновления начнут завершаться ошибкой на token_endpoint. Требует Claude Code v2.1.260 или новее на сервере шлюза. |
extra_auth_params |
Нет | Дополнительные параметры запроса, дословно добавляемые к запросу авторизации IdP. Это механизм переопределения для поведения, специфичного для IdP, например access_type: offline для refresh-токенов Google, domain_hint для некоторых тенантов Entra или acr_values для потоков step-up. Не может переопределять параметры протокола, которыми управляет шлюз: state, nonce, redirect_uri, PKCE, scope, response_type, response_mode и client_id. |
userinfo_fallback |
Нет | Если id_token не содержит email или группы, получать их из /userinfo. Нужно для облегчённых access-токенов Keycloak, org server Okta и минимальных токенов ADFS. Приоритет остаётся за id_token; userinfo только заполняет пробелы. По умолчанию false. |
use_pkce |
Нет | Отправлять вызов PKCE (S256) в запросе авторизации. По умолчанию true. Задавайте false, только если ваш IdP отклоняет PKCE для этого конфиденциального клиента. |
clock_skew_seconds |
Нет | Допустимое расхождение часов при проверке временных claims id_token. По умолчанию 0, то есть строгая проверка. Увеличьте, если сразу после входа видите ошибки "token expired / not yet valid" из-за расхождения часов хоста и IdP. |
token_endpoint_auth_method |
Нет | Как шлюз аутентифицируется на эндпоинте токенов IdP: client_secret_basic, client_secret_post или private_key_jwt для аутентификации клиента по сертификату. По умолчанию шлюз выбирает один из двух методов client_secret на основе того, что объявляет IdP. |
client_assertion |
С private_key_jwt |
Блок с private_key_pem и certificate_pem: закрытый ключ и сертификат для аутентификации клиента по сертификату. Требует v2.1.284 или новее. |
id_token_signed_response_alg |
Нет | Ожидаемый алгоритм подписи id_token. По умолчанию RS256. Задайте для IdP, которые подписывают с помощью ES256, PS256 или EdDSA. |
additional_authorized_parties |
Нет | Дополнительные допустимые значения azp помимо client_id, для потоков брокера и обмена токенами Keycloak |
discovery_url |
Нет | Получать документ обнаружения по этому URL вместо выведения его из issuer, для IdP за прокси, который переписывает хост издателя. Путь должен содержать /.well-known/. |
use_proxy |
Нет | Отправлять собственные запросы шлюза к IdP через прямой прокси из HTTPS_PROXY или HTTP_PROXY с учётом NO_PROXY. Значение false оставляет эти запросы прямыми. Требует v2.1.227 или новее; см. Запросы к IdP через прямой прокси ниже. |
form_action_origins |
Нет | Дополнительные origin для директивы Content-Security-Policy: form-action страницы /device. Шлюз уже разрешает 'self' и origin обнаруженного authorization_endpoint, но Chrome применяет form-action ко всей цепочке перенаправлений. Если ваш IdP перенаправляет через второй хост, например Azure AD с федерацией в ADFS, Okta по схеме hub-spoke или корпоративный перехватчик SSO, перечислите все origin, через которые может перенаправляться запрос авторизации. |
ca_cert_pem |
Нет | Сам сертификат CA в кодировке PEM, а не путь к файлу. Заменяет системное хранилище доверенных сертификатов только для запросов к IdP. Чтобы загрузить смонтированный файл, напишите ${file:/etc/gateway/idp-ca.pem}. Используйте для Keycloak или Dex за корпоративной PKI. |
Аутентификация клиента по сертификату
Если ваш поставщик идентификации аутентифицирует OAuth-клиентов по сертификату вместо секрета клиента, как это делает Microsoft Entra с учётными данными-сертификатами, задайте token_endpoint_auth_method: private_key_jwt. Требует Claude Code v2.1.284 или новее на сервере шлюза.
В этой конфигурации шлюз не отправляет секрет. Он аутентифицируется на эндпоинте токенов IdP с помощью короткоживущего JWT, подписанного закрытым ключом сертификата, когда разработчик входит в систему и каждый раз, когда шлюз обновляет его сессию. JWT подписывается алгоритмом RS256 и идентифицирует сертификат заголовками отпечатков x5t и x5t#S256, а не kid. Ваш IdP должен уметь находить зарегистрированный сертификат по отпечатку.
Создайте ключ и сертификат
Создайте незашифрованный закрытый ключ RSA длиной не менее 2048 бит в формате PEM PKCS#8 или PKCS#1 и сертификат для него. Шлюз отказывается запускаться с ключом, который не соответствует этим условиям. Эта команда openssl создаёт такой ключ с самоподписанным сертификатом, действительным в течение одного года:
openssl req -x509 -newkey rsa:2048 -nodes -keyout idp-client.key -out idp-client.crt -days 365 -subj "/CN=claude-gateway"
Она записывает idp-client.key и idp-client.crt в текущий каталог. Скопируйте или смонтируйте оба файла туда, где шлюз сможет их прочитать. В примере на шаге 3 используется /etc/gateway/.
Загрузите сертификат в IdP
Загрузите сертификат, а не закрытый ключ, в регистрацию приложения шлюза в IdP.
Добавьте ключ и сертификат в gateway.yaml
Передайте шлюзу закрытый ключ и сертификат в блоке client_assertion. Не указывайте client_secret, потому что шлюз отказывается запускаться, если он задан вместе с private_key_jwt. Этот блок oidc аутентифицирует шлюз в тенанте Microsoft Entra с помощью сертификата:
oidc:
issuer: https://login.microsoftonline.com/<tenant-id>/v2.0
client_id: <application-id>
token_endpoint_auth_method: private_key_jwt
client_assertion:
private_key_pem: ${file:/etc/gateway/idp-client.key}
certificate_pem: ${file:/etc/gateway/idp-client.crt}
Оба значения — это содержимое PEM, а не пути к файлам, поэтому загружайте смонтированные файлы с помощью ${file:/path}, как в примере. Шлюз отказывается запускаться, если certificate_pem не является одним PEM-сертификатом без остальной цепочки, открытый ключ которого соответствует private_key_pem.
Перезапустите шлюз и проверьте лог загрузки
Перезапустите шлюз и найдите эту строку в логе загрузки:
[gateway] 2026-10-01T23:07:40.512Z info oidc: client authentication private_key_jwt; certificate CN=claude-gateway, SHA-1 thumbprint DE92821854EE8BAA1D98C758FAA04AABE80B9F57, expires Oct 1 23:07:31 2027 GMT
Сравните отпечаток SHA-1 с тем, который IdP показывает для загруженного вами сертификата. Если срок действия сертификата истёк или он ещё не действителен, шлюз всё равно запускается, но записывает в лог предупреждение о том, что входы и обновления будут завершаться ошибкой, пока вы его не замените. Чтобы убедиться, что IdP принимает сертификат, попросите одного разработчика войти через шлюз.
Ротация сертификата клиента
Шлюз читает ключ и сертификат один раз при загрузке, поэтому изменённый файл вступает в силу только после перезапуска. Выполняйте ротацию в таком порядке, чтобы ни один запрос токена не предъявлял сертификат, которого нет у IdP:
- Загрузите новый сертификат в IdP в дополнение к старому.
- Замените файлы ключа и сертификата, которые загружает
gateway.yaml, затем перезапустите шлюз. - Удалите старый сертификат из 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, чтобы ничто в файле конфигурации не могло ослабить проверку адресов шлюзом.
export HTTPS_PROXY=http://proxy.corp.example.com:3128
export NO_PROXY=
export no_proxy=
export CLAUDE_GATEWAY_PROXY_IS_EGRESS_BOUNDARY=1
Пока исходящий трафик только через прокси активен, шлюз при загрузке записывает в лог одну строку network:.
Каждая строка ниже — это один класс исходящих запросов шлюза с заданным HTTPS_PROXY: по умолчанию и при активном исходящем трафике только через прокси.
| Исходящий запрос | По умолчанию | Исходящий трафик только через прокси активен |
|---|---|---|
Upstream provider: anthropic, обмен токенов Workload Identity Federation, экспорт telemetry.forward_to |
Разрешается и проверяется локально, затем CONNECT к проверенному IP-адресу через прокси. К сборщику телеметрии, указанному в NO_PROXY, шлюз обращается напрямую |
Имя хоста передаётся прокси |
| Обнаружение IdP, JWKS, токены и userinfo | Напрямую, если не задано oidc.use_proxy: true; в этом случае CONNECT к проверенному IP-адресу |
Имя хоста передаётся прокси, если только oidc.use_proxy: false не оставляет внутренний IdP прямым |
| Upstream Amazon Bedrock, Claude Platform on AWS, Google Cloud's Agent Platform и Microsoft Foundry; поиск групп Google | Имя хоста передаётся прокси | Без изменений |
Исходящий трафик только через прокси остаётся выключенным, если окружение шлюза не удовлетворяет всем трём условиям:
- Задан
HTTPS_PROXYилиHTTP_PROXY. NO_PROXYиno_proxyпусты. Если ваша платформа внедряет любую из них в поды, задайте обеим пустое значение в контейнере шлюза. Если указать сборщик телеметрии вNO_PROXY, исходящий трафик только через прокси останется выключенным.CLAUDE_GATEWAY_ALLOW_LOOPBACKне включена. Сборщик или IdP на собственном loopback пода нельзя сочетать с исходящим трафиком только через прокси, потому что loopback-адрес, переданный прокси, указывал бы на сам хост прокси, поэтому дайте этим сервисам адрес, доступный для прокси. По той же причине, пока исходящий трафик только через прокси активен, шлюз полностью отклоняет имена видаlocalhost.
Если одно из этих условий не выполнено, шлюз при загрузке записывает в лог предупреждение с именем переменной, которая помешала включению, и сохраняет поведение по умолчанию.
Когда исходящий трафик только через прокси активен, разрешите в прокси все назначения, включая внутренний сборщик и любые хосты, заданные по IP-адресу. Вы по-прежнему можете оставить внутренний IdP прямым с помощью oidc.use_proxy: false.
Включайте это, только если список разрешённых адресов прокси как минимум так же строг, как собственная проверка шлюза. Прокси должен отклонять эндпоинты облачных метаданных, такие как 169.254.169.254 и metadata.google.internal, link-local-адреса и собственный loopback хоста прокси, причём отклонять по адресу, в который разрешается имя, а не только по имени, потому что шлюз больше не перехватывает имя хоста, которое разрешается в один из них. Прокси, который подключается куда угодно по запросу, снимает защиту от SSRF шлюза для этих запросов.
`session`
Блок session определяет Bearer-токены, которые шлюз выпускает после входа: секрет, которым они подписываются, и срок их жизни.
| Поле | Обязательно | Описание |
|---|---|---|
jwt_secret |
Да | Не менее 32 байт энтропии, например из openssl rand -base64 32. Подписывает Bearer-токены шлюза HS256. Принимает одну строку или массив для ротации: элемент с индексом 0 подписывает, все элементы проверяют. Для ротации добавьте новый секрет в начало, подождите ttl_hours, затем удалите старый. |
ttl_hours |
Нет | Время жизни Bearer-токена шлюза. По умолчанию 1. CLI незаметно обновляет токен до истечения, если IdP выдаёт refresh-токены. Более короткое время жизни ускоряет отзыв доступа; более длинное сокращает число обращений к IdP. Если ваш IdP не может выдавать refresh-токены, потому что offline_access недоступен, незаметного обновления нет, поэтому увеличьте значение до 8 или 12, чтобы разработчикам не приходилось проходить вход в браузере каждый час. |
`store`
Блок store указывает шлюзу на его базу данных PostgreSQL, в которой хранятся гранты устройств и счётчики ограничения частоты запросов.
| Поле | Обязательно | Описание |
|---|---|---|
postgres_url |
Да | URL postgres:// или postgresql://. Обязателен: точке встречи грантов устройств, куда пишет обратный вызов браузера и откуда читает опрашивающий CLI, нужно состояние, общее для реплик. Шлюз сам выполняет миграции схемы при загрузке и при обновлении, поэтому роли нужны права на создание и изменение таблиц в целевой схеме. См. Обновления и Postgres. |
username |
Нет | Переопределяет пользователя в postgres_url |
password |
Нет | Учётные данные базы данных. Задавайте их здесь, а не в postgres_url, чтобы учётные данные не попадали в URL. Принимает любые символы и имеет приоритет над учётными данными из URL. |
max_connections |
Нет | Размер пула соединений Postgres на реплику. По умолчанию 5 — консервативное значение, подходящее для общих баз данных. При включённых лимитах расходов горячий путь выполняет несколько операций на каждый запрос инференса, поэтому увеличьте значение для выделенной базы данных под нагрузкой и следите, чтобы число реплик × это значение было меньше max_connections базы данных. |
connect_timeout_seconds |
Нет | Сколько секунд шлюз ждёт при открытии соединения с Postgres. Целое число от 1 до 60, по умолчанию 5. Увеличьте, если попытки соединения завершаются по таймауту при запуске нового экземпляра шлюза. Требует Claude Code v2.1.274 или новее на сервере шлюза. Более ранние версии отказываются запускаться, если ключ задан. |
readiness_grace_seconds |
Нет | Сколько секунд /readyz продолжает сообщать о готовности после того, как Postgres перестаёт отвечать. Целое число от 0 до 3600, по умолчанию 0. Как выбрать значение, см. в разделе Поведение при сбое. Требует Claude Code v2.1.282 или новее на сервере шлюза. Более ранние версии отказываются запускаться, если ключ задан. |
Для локальной разработки укажите в postgres_url одноразовый контейнер Postgres, например docker run --rm -p 5432:5432 -e POSTGRES_HOST_AUTH_METHOD=trust postgres.
`upstreams`
upstreams — это упорядоченный список. Шлюз направляет запросы инференса первому upstream, который разрешает запрошенную модель.
При 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 шлюз больше не пробует.
- Каждый опробованный upstream завершился ошибкой, при которой шлюз переключается: последний
429. Если ни один не вернул429, шлюз выбирает, в порядке предпочтения, последний401или403, последний404и последний501. Если ни один не вернул ничего из этого — собственный502шлюза,all upstreams failed (N attempted), где N — число всех записей вupstreams, включая те, которые шлюз пропустил, потому что они не обслуживают запрошенную модель.
Возвращая ответ upstream, шлюз сохраняет его код статуса. Сохраняется ли сообщение upstream, зависит от поставщика. Тело ошибки от upstream Anthropic API доходит до разработчика без изменений.
Upstream Amazon Bedrock, Claude Platform on AWS, Google Cloud's Agent Platform и Microsoft Foundry могут указывать в тексте ошибки ID ваших аккаунтов, ARN ролей и ID проектов. Шлюз записывает полный текст в операционный лог. Что видит разработчик от этих upstream, зависит от типа отклонения:
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.
Например, шлюз заменяет сообщение Amazon Bedrock 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:
upstreams:
- provider: anthropic
auth:
api_key: ${ANTHROPIC_API_KEY}
# ИЛИ OAuth Bearer-токен (например, токен, полученный через Workload Identity Federation):
# oauth_token: ${file:/var/run/secrets/anthropic-oauth-token}
# base_url: https://api.anthropic.com # по умолчанию; переопределите для прямого прокси
Две формы учётных данных различаются отправляемым заголовком:
api_key: отправляетx-api-key. Выполняйте ротацию в Claude Console и обновляйте переменную окружения.oauth_token: отправляетAuthorization: Bearer. Используйте Bearer-форму, если ваша организация выдаёт короткоживущие токены вместо долгоживущих API-ключей. Bearer-токен читается один раз при запуске, поэтому для обновления перемонтируйте секрет и перезапустите шлюз.
Вместо статического ключа или Bearer-токена можно использовать Workload Identity Federation. Создайте правило федерации по руководству по Workload Identity Federation, затем смонтируйте OIDC JWT вашей рабочей нагрузки как файл, например проецируемый токен сервисного аккаунта Kubernetes или id-token CI-платформы. Шлюз обменивает JWT на короткоживущий Bearer-токен и автоматически его обновляет. Файл токена перечитывается при каждом обмене, поэтому ротированные проецируемые токены подхватываются без перезапуска.
upstreams:
- provider: anthropic
auth:
federation_rule_id: ${ANTHROPIC_FEDERATION_RULE_ID}
organization_id: ${ANTHROPIC_ORGANIZATION_ID}
identity_token_file: /var/run/secrets/anthropic/id-token
# workspace_id: wrkspc_... # обязателен, если правило охватывает >1 рабочего пространства
# service_account_id: svac_... # необязательная проверка ожидаемой цели
Заголовки идентификации пользователя для вашего прокси
Вы можете указать в base_url upstream provider: anthropic свой прокси вместо Anthropic API. Чтобы сообщать этому прокси, какой разработчик отправил каждый запрос, задайте forward_user_identity: true для этого upstream. Тогда прокси сможет учитывать расходы по разработчикам. Требует шлюза на Claude Code v2.1.233 или новее.
Например, для прокси по адресу upstream-gateway.internal.example.com:
upstreams:
- provider: anthropic
base_url: https://upstream-gateway.internal.example.com
auth:
api_key: ${PROXY_KEY}
forward_user_identity: true # по умолчанию false
Шлюз добавляет эти заголовки к каждому запросу, который направляет этому upstream.
| Заголовок | Значение |
|---|---|
x-litellm-end-user-id |
Email разработчика, если IdP его предоставил. |
x-claude-gateway-user-id |
Субъект IdP разработчика из claim sub токена. |
x-claude-gateway-user-email |
Email разработчика, если IdP его предоставил. |
Если токен IdP не содержит email, шлюз отправляет только x-claude-gateway-user-id и опускает два заголовка с email. Если ваш IdP передаёт email в другом claim, укажите этот claim в oidc.email_claim.
Когда ваш прокси отвечает 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, что является значением по умолчанию, шлюз отказывается запускаться.
Amazon Bedrock
О клиентском развёртывании Amazon Bedrock, которое шлюз заменяет или перед которым стоит, см. Claude Code на Amazon Bedrock. Upstream на стороне шлюза:
upstreams:
- provider: bedrock
region: us-east-1
auth: {} # предпочтительно: цепочка учётных данных AWS по умолчанию
# ИЛИ явные учётные данные:
# auth:
# aws_access_key_id: ${AWS_AKID}
# aws_secret_access_key: ${AWS_SK}
# aws_session_token: ${AWS_ST}
# ИЛИ Bearer-токен Bedrock API:
# auth:
# aws_bearer_token: ${AWS_BEARER_TOKEN}
# Переопределите эндпоинт bedrock-runtime для развёртываний с FIPS или VPC-эндпоинтом:
# base_url: https://bedrock-runtime-fips.us-east-1.amazonaws.com
Пустой блок 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: проходил проверку.
| Настройка | Как |
|---|---|
| Разрешения IAM | Предоставьте принципалу шлюза bedrock:InvokeModel и bedrock:InvokeModelWithResponseStream как на ARN профилей инференса, так и на ARN базовых foundation-моделей. Для встроенного каталога в регионах США: arn:aws:bedrock:<region>:<account>:inference-profile/us.anthropic.* и arn:aws:bedrock:*::foundation-model/anthropic.*. Также предоставьте bedrock:CountTokens на ARN foundation-моделей. Шлюз бесплатно использует это разрешение, чтобы подсчитать входные токены запроса, прерванного клиентом, и лимиты расходов оставались точными. Без него шлюз для такого подсчёта использует как резервный вариант запрос Bedrock на один токен. |
| Доступ к моделям | В коммерческих регионах Amazon Bedrock включает доступ к моделям по умолчанию. Остаётся одно ограничение на уровне аккаунта — одноразовая форма Anthropic с описанием сценария использования: если в вашем аккаунте AWS её ещё никто не отправлял, откройте консоль Amazon Bedrock, выберите модель Anthropic в каталоге моделей и заполните форму. О форме для AWS Organizations и разрешениях, которые нужны отправителю, см. Отправка сведений о сценарии использования. |
| EKS (IRSA) | Создайте IAM-роль с политикой выше и политикой доверия для OIDC-поставщика вашего кластера, ограниченной сервисным аккаунтом шлюза. Добавьте сервисному аккаунту аннотацию eks.amazonaws.com/role-arn: arn:aws:iam::<acct>:role/claude-gateway. auth: {} подхватит её. |
| ECS / EC2 | Привяжите IAM-роль к определению задачи или профилю экземпляра. auth: {} подхватит её. |
| В других средах | Передайте учётные данные через переменные окружения AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY и AWS_SESSION_TOKEN или задайте их явно в auth: с подстановкой ${VAR} |
| Регион | region: — регион эндпоинта API. Межрегиональные профили инференса маршрутизируют запросы в пределах географии (США, ЕС, APAC) независимо от выбранного региона. Для регионов за пределами США или ARN с выделенной пропускной способностью добавьте блок models: с правильными ID для каждого upstream. |
Применение guardrail Amazon Bedrock
Чтобы применить guardrail Amazon Bedrock ко всем запросам инференса, которые шлюз отправляет через upstream Bedrock, добавьте в этот upstream блок guardrail. Требует Claude Code v2.1.281 или новее на сервере шлюза.
upstreams:
- provider: bedrock
region: us-east-1
auth: {}
guardrail:
id: gr-abc123 # ID guardrail или полный ARN
version: "1" # номер опубликованной версии или DRAFT
# сохраните кавычки: 1 без кавычек вызывает ошибку при загрузке
Шлюз не поддерживает входные теги guardrail. Он не добавляет теги содержимого guard в промпты, поэтому фильтр guardrail, который Amazon Bedrock применяет только к помеченному входу, не срабатывает для трафика через шлюз. Какие фильтры зависят от входных тегов, см. в разделе input tags документации Amazon Bedrock.
Также предоставьте 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 вместо того, чтобы переслать его.
Bedrock в другом аккаунте AWS
Если задать assume_role для upstream Bedrock, шлюз использует собственную идентичность AWS только для вызова sts:AssumeRole на указанную вами роль, которая может находиться в другом аккаунте AWS, чем шлюз. Каждый запрос Bedrock от этого upstream подписывается одночасовыми учётными данными, которые возвращает STS, поэтому ни один долгоживущий ключ доступа не пересекает границы аккаунтов.
Требует шлюза на Claude Code v2.1.281 или новее. Более ранний шлюз отказывается запускаться, обнаружив этот ключ.
upstreams:
- name: bedrock-isolated
provider: bedrock
region: us-east-1
auth: {} # собственная роль шлюза: она только вызывает STS
assume_role:
role_arn: arn:aws:iam::222222222222:role/claude-gateway-bedrock
# external_id: ${BEDROCK_ROLE_EXTERNAL_ID} # если политика доверия роли его требует
Блок assume_role принимает три ключа:
| Ключ | Значение |
|---|---|
role_arn |
IAM-роль, которую принимает шлюз, в виде ARN arn:aws:iam:: или arn:aws-us-gov:iam::. Предоставьте ей разрешения Bedrock, необходимые этому upstream, включая bedrock:CountTokens, а также bedrock:ApplyGuardrail, если для upstream задан guardrail. |
external_id |
Необязательно. Отправляется как external ID в каждом вызове sts:AssumeRole. Задайте, если его требует политика доверия роли, и заключите в кавычки, если он состоит только из цифр. |
session_name |
Необязательно. email или sub дают каждому разработчику собственную сессию: см. Учёт затрат AWS по разработчикам. Если не задан, все запросы используют одну сессию с именем claude-apps-gateway. |
Политика доверия роли указывает собственный принципал шлюза, например его роль IRSA или роль задачи ECS. Этому принципалу нужно sts:AssumeRole на роль и не нужны собственные разрешения Bedrock. Удалите Condition, если не задаёте external_id.
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::111111111111:role/claude-gateway" },
"Action": "sts:AssumeRole",
"Condition": { "StringEquals": { "sts:ExternalId": "your-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применяется только кprovider: bedrockи требует исходных учётных данных SigV4: шлюз отказывается запускаться, если он задан вместе сaws_bearer_token.- Этот upstream может использовать каждый разработчик, допущенный шлюзом; какие разработчики могут использовать какие модели, определяет
managed. Чтобы модель, обслуживаемая через роль, не обслуживалась также из другого аккаунта, дайте ей пользовательский id, картаupstream_modelкоторого содержит только имя этого upstream. Для такого id шлюз пропускает все остальные upstream, поэтому ни запрос, ни подсчёт токенов для прерванного запроса не могут переключиться на другой аккаунт. Запрос к встроенному имени модели всё равно может дойти до этого upstream, и шлюз подпишет его той же ролью. Указывайте этот upstream последним, если только его аккаунт не должен обслуживать и эти модели.
В этом примере одной модели дан пользовательский id, который обслуживает только изолированный upstream:
models:
- id: claude-opus-restricted # пользовательский id, а не встроенное имя модели
upstream_model:
bedrock-isolated: us.anthropic.claude-opus-4-8 # единственный upstream, который её обслуживает
Учёт затрат AWS по разработчикам
По умолчанию шлюз подписывает каждый запрос Bedrock одними учётными данными, поэтому AWS видит запросы всех разработчиков под одним IAM-принципалом. Добавьте session_name: email в assume_role, и шлюз будет вызывать sts:AssumeRole раз в час для каждого разработчика с именем сессии, равным email этого разработчика, и подписывать его запросы полученными учётными данными, так что запросы каждого разработчика поступают в AWS в рамках его собственной сессии принятой роли. Роль может находиться в собственном аккаунте шлюза.
Требует шлюза на Claude Code v2.1.281 или новее. IAM-роль и то, где биллинг AWS показывает сессии, описаны в разделе Учёт затрат в AWS.
upstreams:
- provider: bedrock
region: us-east-1
auth: {} # собственная роль шлюза: она только вызывает STS
assume_role:
role_arn: arn:aws:iam::123456789012:role/claude-gateway-bedrock-user
session_name: email # или sub
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:
upstreams:
- provider: mantle
region: us-east-1
models: [claude-opus-4-7, claude-haiku-4-5] # обязательно
auth: {} # цепочка учётных данных AWS по умолчанию
- provider: bedrock
region: us-east-1
auth: {}
В таблице ниже перечислены поля, специфичные для upstream mantle.
| Поле | Обязательно | Описание |
|---|---|---|
region |
Да | Регион AWS. Шлюз выводит из него эндпоинт https://bedrock-mantle.<region>.api.aws/anthropic. |
models |
Да | Модели, доступ к которым в Mantle предоставлен вашему аккаунту AWS, под теми именами, которые отправляют клиенты, например claude-haiku-4-5. В этот upstream направляются только они, а все остальные модели переходят к следующему. |
auth |
Нет | Принимает те же ключи, что и блок auth upstream Amazon Bedrock, по тем же правилам. |
base_url |
Нет | Переопределить выведенный эндпоинт. Сохраните путь /anthropic в конце. |
Предоставьте идентичности 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: upstreammantleне принимаетassume_role. Запросы, обслуживаемые Mantle, отправляются с собственными учётными даннымиauthupstreammantleи не учитываются по разработчикам.
Что означают собственные ответы Mantle с ошибками, см. в разделе Ошибки эндпоинта 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 на стороне шлюза:
upstreams:
- provider: anthropicAws
region: us-east-1
workspace_id: wrkspc_...
auth:
api_key: ${ANTHROPIC_AWS_API_KEY} # отправляется как x-api-key
# ИЛИ SigV4 через цепочку учётных данных AWS по умолчанию:
# auth: {}
# ИЛИ явные учётные данные SigV4:
# auth:
# aws_access_key_id: ${AWS_ACCESS_KEY_ID}
# aws_secret_access_key: ${AWS_SECRET_ACCESS_KEY}
# Переопределите выведенный эндпоинт:
# base_url: https://aws-external-anthropic.us-east-1.api.aws
Платформа работает в отдельном от Amazon Bedrock аккаунте AWS и подписывает запросы SigV4 для собственного имени сервиса aws-external-anthropic, поэтому IAM-роль, ограниченная Bedrock, не даёт к ней доступа. API-ключ в auth.api_key имеет приоритет, если также заданы учётные данные SigV4. Пустой блок auth использует цепочку учётных данных AWS SDK по умолчанию — ту же, что и upstream Amazon Bedrock.
| Поле | Обязательно | Описание |
|---|---|---|
region |
Да | Регион AWS: строчные буквы, цифры и дефисы. Шлюз выводит из него эндпоинт https://aws-external-anthropic.<region>.api.aws. |
workspace_id |
Да | Отправляется как заголовок в каждом запросе; платформа его требует |
auth.api_key |
Нет | API-ключ для платформы, отправляется как x-api-key. Это не Bearer-токен: два режима аутентификации — API-ключ или SigV4. |
auth.aws_access_key_id / auth.aws_secret_access_key |
Нет | Явные учётные данные SigV4. Если задать одно без другого, шлюз не запустится. Вместе с ними принимается auth.aws_session_token. |
base_url |
Нет | Переопределить выведенный эндпоинт |
Поскольку платформа разрешает собственные ID моделей Anthropic, встроенный каталог направляет запросы к ней без блока models:. Если вы составляете собственный список models:, задайте для записи ключ anthropicAws: с собственным ID Anthropic.
Google Cloud Agent Platform
Об аналогичной клиентской настройке см. Claude Code на Google Cloud. Upstream на стороне шлюза:
upstreams:
- provider: vertex
region: us-east5
project_id: example-prod
auth: {} # предпочтительно: Application Default Credentials
# ИЛИ файл ключа сервисного аккаунта:
# auth: { service_account_json: /secrets/sa.json }
# Переопределите эндпоинт aiplatform для Private Service Connect:
# base_url: https://us-east5-aiplatform.p.googleapis.com
Пустой блок 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 направляет каждый запрос в доступный регион, и вам не нужно отслеживать доступность моделей по регионам. Указание конкретного региона закрепляет за ним все запросы.
| Настройка | Как |
|---|---|
| Разрешения IAM | Предоставьте сервисному аккаунту шлюза roles/aiplatform.user в проекте или пользовательскую роль с aiplatform.endpoints.predict. Включите API Google Cloud's Agent Platform (aiplatform.googleapis.com). |
| Доступ к моделям | В Model Garden включите модели Claude для вашего проекта. Они публикуются в определённых регионах; поддерживаемые регионы указаны в карточке модели. |
| GKE (Workload Identity) | Привяжите сервисный аккаунт GCP к сервисному аккаунту Kubernetes шлюза и добавьте KSA аннотацию iam.gke.io/gcp-service-account: claude-gateway@<proj>.iam.gserviceaccount.com. auth: {} подхватит её. |
| Cloud Run / GCE | Назначьте сервису сервисный аккаунт с roles/aiplatform.user. auth: {} подхватит его. |
| В других средах | auth: { service_account_json: /secrets/sa.json } — путь к JSON-файлу ключа, смонтированному как секрет. Поле принимает путь к файлу, а не содержимое ключа, поэтому подстановка ${file:…} здесь не используется. |
Microsoft Foundry
О клиентском развёртывании Microsoft Foundry см. Claude Code на Microsoft Foundry. Upstream на стороне шлюза:
upstreams:
- provider: foundry
resource: example-foundry # https://example-foundry.services.ai.azure.com
auth: { use_azure_ad: true } # предпочтительно: DefaultAzureCredential / Managed Identity
# ИЛИ API-ключ:
# auth:
# api_key: ${FOUNDRY_API_KEY}
use_azure_ad: true получает учётные данные через DefaultAzureCredential: Managed Identity на AKS, ACI или App Service, Azure CLI или учётные данные из окружения. API-ключи работают, но действуют на уровне всего проекта и не ротируются автоматически. Эндпоинт Microsoft Foundry выводится из resource:; задайте необязательный base_url, чтобы переопределить его для суверенных облаков, таких как Azure Government.
| Настройка | Как |
|---|---|
| RBAC | Предоставьте идентичности шлюза роль Azure AI User или Cognitive Services User на ресурс Microsoft Foundry |
| Развёртывания | Microsoft Foundry использует имена развёртываний, выбранные администратором, а не канонические ID моделей. Добавьте блок models:, сопоставляющий каждый канонический ID с именем вашего развёртывания. |
| AKS (workload identity) | Настройте федерацию User-Assigned Managed Identity с OIDC-издателем кластера и привяжите её к сервисному аккаунту шлюза. use_azure_ad: true подхватит её через WorkloadIdentityCredential. |
| ACI / App Service | Включите для ресурса управляемую идентичность, назначаемую системой или пользователем. use_azure_ad: true подхватит её. |
| В других средах | auth: { api_key: "${FOUNDRY_API_KEY}" }. Заключайте ${…} в кавычки внутри { }. |
Статические заголовки в запросах к upstream
Чтобы добавлять фиксированные заголовки к запросам, которые шлюз отправляет одному upstream, задайте для этого upstream headers:. Используйте это, если ваш прокси перед поставщиком маршрутизирует или учитывает трафик по заголовку.
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:
upstreams:
- provider: vertex
region: us-east5
project_id: example-prod
base_url: https://upstream-proxy.internal.example.com
auth: {}
headers:
x-source: claude-apps-gateway
x-proxy-token: ${PROXY_TOKEN}
Значения — печатный текст ASCII без пробелов в начале и конце. Заключайте в кавычки числа, true и false, чтобы YAML читал их как текст.
Чтобы не хранить секрет в файле конфигурации, используйте подстановку секретов и загружайте значение из переменной окружения через ${VAR} или из файла через ${file:/path}. Если ${VAR} разрешается в пустое значение, шлюз не запустится.
headers: работает для всех поставщиков, и каждый upstream отправляет только свои заголовки.
Не все запросы, которые шлюз отправляет upstream, содержат их:
| Запрос шлюза к этому upstream | Содержит headers: |
|---|---|
/v1/messages, потоковый или нет, и /v1/messages/count_tokens |
Да |
| Запрос, переключённый с другого upstream | Да, только headers: этого upstream |
Вызов CountTokens Amazon Bedrock для запроса, прерванного клиентом |
Нет |
| Обмен токенов Workload Identity Federation | Нет |
Для 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 разработчика, считается отказом для отдельного пользователя и не приводит к переключению.
Каждый запрос начинается с первого upstream. Запрос доходит до следующего upstream, только если все предыдущие завершились ошибкой или не обслуживают запрошенную модель.
Шлюз не запоминает неудачные upstream, поэтому, пока upstream недоступен, каждый доходящий до него запрос всё равно пробует его и ждёт ошибки, прежде чем двигаться дальше.
Для upstream Anthropic API время ожидания недоступного upstream ограничивает timeouts.upstream_ttfb_ms. Эта настройка не действует для других поставщиков: для них шлюз ждёт начала ответа upstream до одного часа.
404 означает недоступность модели в конкретном upstream, поэтому upstream, в котором модель не включена, не блокирует следующий upstream, который её обслуживает. Upstream, который не может разрешить запрошенную модель, пропускается без сетевого обращения.
В этом примере запросы сначала направляются в выделенную пропускную способность Amazon Bedrock, при переполнении — в режим оплаты по запросу и во второй аккаунт, а в последнюю очередь — в Anthropic API:
upstreams:
# Основной: выделенная пропускная способность в вашем домашнем регионе.
- name: bedrock-pt
provider: bedrock
region: us-east-1
auth: {}
# Переполнение: оплата по запросу, межрегиональный инференс.
- name: bedrock-od
provider: bedrock
region: us-west-2
auth: {}
# Другой аккаунт: отдельная квота Bedrock через статические ключи.
- name: bedrock-acct2
provider: bedrock
region: us-east-1
auth:
aws_access_key_id: ${ACCT2_AKID}
aws_secret_access_key: ${ACCT2_SK}
# Последний вариант: Anthropic API напрямую.
- name: anthropic-fallback
provider: anthropic
auth:
api_key: ${ANTHROPIC_API_KEY}
# ID моделей для каждого upstream задаются по `name:` upstream.
models:
- id: claude-opus-4-8
label: Claude Opus 4.8
upstream_model:
bedrock-pt: arn:aws:bedrock:us-east-1:111111111111:provisioned-model/abcdef
bedrock-od: us.anthropic.claude-opus-4-8
bedrock-acct2: us.anthropic.claude-opus-4-8
anthropic-fallback: claude-opus-4-8
| Рычаг | Как |
|---|---|
| Разные регионы | По одному upstream Amazon Bedrock на регион, каждый со своим region:. С auto_include_builtin_models: true межрегиональные профили инференса маршрутизируются автоматически; для развёртываний, закреплённых за регионом, используйте блок models:. |
| Разные аккаунты | По одному upstream Amazon Bedrock на аккаунт. Цепочка по умолчанию (auth: {}) использует идентичность пода; для второго аккаунта добавьте assume_role, чтобы обращаться к нему с короткоживущими учётными данными, или задайте в auth: явные учётные данные или Bearer-токен. |
| Выделенная пропускная способность | Сопоставьте модель с ARN выделенной пропускной способности в models: для имени этого upstream. Остальные upstream сохраняют ID для оплаты по запросу, поэтому мощность PT исчерпывается до переключения. |
| Эндпоинты VPC / FIPS | Задайте в base_url: upstream URL вашего VPC-эндпоинта или эндпоинта FIPS |
| Маршрутизация по моделям | Только пользовательский id модели, то есть не встроенной модели Claude, пропускает upstream, отсутствующие в его карте upstream_model:. Upstream mantle пробуется только для моделей, перечисленных в его поле models. На всех остальных upstream шлюз пробует встроенные модели по порядку и использует ID поставщика по умолчанию, если в карте нет записи, поэтому для встроенных моделей карта меняет то, какой ID получает upstream, а не то, пробуется ли он; upstream, отклонивший ID, подчиняется тем же правилам переключения, что и при любой другой ошибке upstream. |
Переключение между облачными поставщиками или на Anthropic API напрямую меняет соглашение, географию и другие условия, которым подчиняется запрос.
CLI применяет одинаковые ограничения функций к шлюзам независимо от того, какой upstream обслуживает конкретный запрос, поэтому переключение не приводит к отправке поля тела, которое upstream отклонил бы.
Дополнительные разделы
`admin`
Опционально. Включает /v1/organizations/spend_limits, который отражает публичный Admin API Anthropic, и принудительное ограничение расходов на разработчика на /v1/messages. Смотрите Spend limits, чтобы узнать, как устанавливаются и применяются ограничения; этот раздел охватывает ключи gateway.yaml, которые включают функцию и настраивают её.
admin:
# Именованные статические API-ключи для эндпоинтов администратора, отправляемые как x-api-key.
# Идентификатор появляется в журнале аудита как admin-key:<id>, поэтому каждый ключ
# можно отследить. Массив для ротации: добавьте новый ключ, обновите клиентов,
# удалите старый.
write_keys:
- { id: terraform, key: "${GATEWAY_ADMIN_WRITE_KEY_TF}" }
- { id: ci, key: "${GATEWAY_ADMIN_WRITE_KEY_CI}" }
read_keys:
- { id: reporting, key: "${GATEWAY_ADMIN_READ_KEY}" }
# Группы IdP с полным доступом администратора через обычный JWT шлюза (без API-ключа).
admin_groups: [platform-finops]
blocked_message: request an increase at https://go.example.com/claude-limits
| Поле | Обязательно | Описание |
|---|---|---|
write_keys |
Нет | Массив {id, key}. x-api-key, соответствующий одному из них, может перечислять, устанавливать и удалять ограничения расходов. Значения ключей должны быть не менее 32 символов; id должны быть уникальны в read_keys и write_keys. |
read_keys |
Нет | Массив {id, key}. Только для чтения: каждый эндпоинт GET, включая перечисление ограничений, получение одного по ID и чтение /effective и /audit. |
admin_groups |
Нет | Имена групп IdP. JWT шлюза, чей claim groups включает одну из них, имеет полный доступ администратора, чтение и запись, и аудит как oidc:<sub>. Используйте это для администраторов-людей; используйте API-ключи для машин. Пустая запись в этом списке останавливает шлюз при загрузке. Смотрите Значения сопоставления, которые останавливают шлюз при загрузке. |
blocked_message |
Нет | Добавляется дословно к 429 billing_error, который видит заблокированный разработчик. Напишите полную инструкцию, такую как URL или канал Slack. Если не установлено, шлюз отправляет только сообщение по умолчанию. Смотрите Как работает принудительное ограничение. |
audit_retention_days |
Нет | По умолчанию 365. Более старые строки admin_audit удаляются. |
spend_retention_months |
Нет | По умолчанию 13. Строки счётчика spend старше этого удаляются. По умолчанию сохраняется полный год плюс текущий неполный месяц для отчётности год к году. |
identity_retention_days |
Нет | По умолчанию 90. TTL последнего просмотра для строк principal_emails, которые содержат электронную почту каждого разработчика, отображаемое имя и группы (PII). Намеренно короче, чем сохранение расходов, поэтому отозванная идентичность устаревает, пока её анонимные счётчики расходов остаются. |
group_limit_mode |
Нет | min (по умолчанию) или max. Когда разработчик находится в нескольких группах с ограничениями, min применяет наиболее ограничивающее, а max — наименее ограничивающее. Используется как при принудительном ограничении, так и при /effective. |
`enforcement`
Блок enforcement контролирует поведение проверок ограничения расходов, когда хранилище недоступно.
| Поле | Обязательно | Описание |
|---|---|---|
fail_closed_on_error |
Нет | По умолчанию false. Принудительное ограничение расходов открывается при сбое Postgres, поэтому вывод остаётся доступным. Установите true, чтобы закрыться: разработчики, превысившие лимит, блокируются, но также блокируется всё остальное, если хранилище недоступно. Требует блока admin:: принудительное ограничение расходов работает только при настройке admin, и шлюз отказывается запускаться, если вы установите это true без него. |
`pricing`
Блок pricing сообщает счётчику расходов, что нужно взимать вместо цены USD по прайс-листу, поэтому ограничения и /effective отражают ваши договорные ставки. Суммы остаются в USD и остаются оценкой, а не счётом. Два предварительных условия:
- Claude Code v2.1.227 или позже на сервере шлюза. Более ранние версии отклоняют неизвестный ключ при загрузке.
- Блок
admin:или, в v2.1.268 или позже, блокmanaged:с хотя бы одной политикой. Шлюз отказывается запускаться с установленнымpricingи без одного из этих блоков, потому что ничто не будет его читать.
pricing:
multiplier: 0.85
overrides:
- upstream: bedrock-eu
model: claude-sonnet-4-6
input: 3.30
output: 16.50
cache_read: 0.33
cache_write: 4.125
| Поле | Обязательно | Описание |
|---|---|---|
multiplier |
Нет | По умолчанию 1. Счётчик умножает каждую измеренную сумму на это значение, независимо от того, указана ли цена по прайс-листу или переопределена, поэтому 0.85 выставляет счёт на 85% цены. Должно быть больше 0 и не более 10, и значение выше 1 — это надбавка. |
overrides |
Нет | Строки {upstream, model, input, output, cache_read, cache_write} в USD за миллион токенов. Все четыре ставки обязательны. Каждая должна быть больше 0 и не более 10000. |
Как счётчик сопоставляет строку переопределения:
- Строка заменяет цену по прайс-листу для запросов, которые
upstream,upstreams[].name, обслуживает дляmodel. Это включает более высокую ставку быстрого режима, поэтому запросы быстрого и стандартного режимов измеряются с одинаковыми четырьмя ставками. - Встроенный ID, такой как
claude-sonnet-4-6, сопоставляемый какmodels[].id, охватывает каждую датированную форму, региональную форму Amazon Bedrock или форму Google Cloud's Agent Platform, которую счётчик оценивает как эту модель. Любая другая строка, такая как псевдоним или ARN профиля вывода, сопоставляется с ID, который отправил клиент, или строкой, отправленной вверх по потоку, без учёта регистра. - Где строки перекрываются, счётчик выбирает наиболее специфичную строку, а не первую: строку, чей
model— это точная строка модели, отправленная вверх по потоку, затем строку, соответствующую точному ID, отправленному клиентом, затем строку, называющую встроенную модель. - Неизвестное имя upstream вызывает сбой при загрузке, как и две строки для одного upstream, которые называют одну и ту же модель, включая два написания одной встроенной модели. Шлюз предупреждает при загрузке о строке, которую не может использовать ни одна запрашиваемая модель.
- Запросы веб-поиска остаются на цене по прайс-листу $0.01; множитель всё ещё применяется к ним.
Для ставок по регионам дайте каждому региону свой именованный upstream и одну строку на upstream.
Надбавка к ценам
С v2.1.271 или позже на сервере шлюза вы можете установить multiplier выше 1, до 10, чтобы взимать больше, чем взимает поставщик, например внутреннюю ставку возмещения. Этот пример взимает каждый запрос на 120% цены:
pricing:
multiplier: 1.2
С блоком admin: надбавка также применяется к ограничениям расходов. Счётчик считает 120% цены, поэтому разработчики достигают своих ограничений быстрее. Шлюз записывает в лог предупреждение при загрузке, которое об этом сообщает.
Множитель не изменяет то, что взимает поставщик upstream за запросы.
Если шлюз также отправляет ставки подписанным клиентам, разработчикам нужен Claude Code v2.1.271 или позже, чтобы увидеть надбавку. Более ранние клиенты игнорируют multiplier выше 1 и показывают затраты без него.
Сервер шлюза ранее v2.1.271 отказывается запускаться, если вы установите multiplier выше 1.
Отправка ставок подписанным клиентам
С v2.1.268 или позже на сервере шлюза шлюз также помещает ставки из pricing в политики managed, которые он обслуживает, как управляемую настройку modelPricing. Разработчики, соответствующие политике, затем видят ставки pricing для первого upstream, который обслуживает каждый ID модели в /usage, строке состояния и OpenTelemetry. Разработчик, который не соответствует ни одной политике, не получает управляемые настройки, поэтому его цифры остаются по цене по прайс-листу. Клиенты применяют настройку в Claude Code v2.1.242 или позже.
- Что добавляет шлюз: если блок
cliполитики уже не устанавливаетmodelPricing, шлюз добавляетmultiplierи, для каждого ID модели, который может запросить клиент, строку переопределения первого upstream, который обслуживает этот ID. Ставка, которую взимает только failover upstream, остаётся на шлюзе. - Исключить одну политику: установите
modelPricingна{}в блокеcliэтой политики, и её разработчики остаются по цене по прайс-листу. - Сохранить собственные ставки политики: политика, чей блок
cliустанавливаетmodelPricingс собственнымmultiplierилиoverrides, сохраняет этотmodelPricingцеликом, и шлюз не добавляет к нему свои ставки.
`models`
Блок models — это опциональный список моделей, курируемый администратором, обслуживаемый в /v1/models и используемый для перевода ID моделей на upstream. Это требуется для регионов Amazon Bedrock, не входящих в США, ARN с выделенной пропускной способностью Amazon Bedrock и имён развёртывания Microsoft Foundry.
auto_include_builtin_models: true # false: expose only the list below
models:
- id: claude-opus-4-8
label: Claude Opus 4.8
# description: optional text shown in clients that surface it
upstream_model:
anthropic: claude-opus-4-8
bedrock: us.anthropic.claude-opus-4-8 # or an inference-profile ARN
foundry: your-opus-deployment-name
Каждый ключ под upstream_model должен соответствовать name настроенного upstream, который по умолчанию является именем поставщика. Ключ, который не соответствует ни одному upstream, вызывает сбой при загрузке, поэтому опустите строки для поставщиков, которых вы не используете.
`managed`
Блок managed определяет политики доступа на основе ролей, ключевые по группам IdP или домену электронной почты. Политики оцениваются по порядку; выбирается первое совпадение, затем объединяется с базовым match: {} catch-all. Они обслуживаются для каждого пользователя в GET /managed/settings с кешированием ETag/304.
managed:
policies:
# Specific groups first.
- match: { groups: [eng-contractors] }
cli:
availableModels: [claude-sonnet-4-6]
permissions: { deny: ["WebFetch", "WebSearch"] }
# Default catch-all last: matches everyone who authenticated.
- match: {}
cli:
availableModels: [claude-opus-4-8, claude-sonnet-4-6, claude-haiku-4-5]
# Make the Default option in /model resolve inside each policy's
# list. The eng-contractors policy inherits enforceAvailableModels.
enforceAvailableModels: true
Catch-all match: {}, обычно указываемый последним, рассматривается как базовый слой. Каждая другая политика наследует любой ключ, который она не устанавливает, из catch-all, поэтому записи для каждой роли должны только перечислять то, что отличается от организационного значения по умолчанию. Правила объединения зависят от типа ключа:
- Списки разрешённых:
availableModelsиpermissions.allow. Список конкретной политики полностью заменяет базовый. - Списки запрещённых и массивы хуков:
permissions.deny,permissions.ask,disabledMcpjsonServers,deniedMcpServers,blockedMarketplacesи каждый массив типа событияhooks. Они берут объединение базового и политики, поэтому организационный запрет или хук аудита не может быть случайно удалён переопределением для каждой роли. - Ключи типа Record:
env,modelOverridesиskillOverrides. Они выполняют поверхностное объединение, поэтому блокenvдля каждой роли переопределяет ключи, которые он устанавливает, и наследует остальное из базового.
availableModels также применяется на стороне сервера в /v1/messages, поэтому запрещённая модель возвращает 400 независимо от того, что отправляет клиент. Пустой список запрещает все модели. Проверка также охватывает модель, на которой сессия запускается до того, как разработчик выберет модель, поэтому запускайте сессии на модели, которую разрешает политика.
Шлюз проверяет само значение model перед тем, как передать запрос upstream, поэтому неправильное значение никогда не достигает upstream. Он отклоняет запрос с 400 в двух случаях:
- Когда значение отсутствует или пусто, шлюз отклоняет запрос с сообщением
model is required. Эта проверка требует шлюза, работающего на Claude Code v2.1.228 или позже. - Когда значение присутствует, но не является строкой, шлюз отклоняет запрос с сообщением
model must be a string. Требует шлюза, работающего на Claude Code v2.1.221 или позже.
| Сопоставление | Поведение |
|---|---|
match: {} |
Соответствует каждому аутентифицированному пользователю. Начните с одного из них и добавьте политики для каждой группы выше позже. |
match: { groups: [a, b] } |
Соответствует, если claim groups JWT содержит любую из перечисленных групп. С учётом регистра: группы должны соответствовать точному регистру IdP. |
match: { email_domain: example.com } |
Соответствует части после последнего @ в claim email JWT, без учёта регистра. Принимает один домен на политику. |
match: { groups: [a], email_domain: example.com } |
Оба условия должны совпадать |
Аутентифицированный пользователь, который не соответствует ни одной политике, получает значения по умолчанию шлюза, что означает каждую модель в каталоге и никаких управляемых настроек. Добавьте catch-all match: {} последним, если вы хотите гарантированную политику по умолчанию.
Шлюз не ведёт собственный каталог пользователей. Он авторизует каждый запрос из токена IdP пользователя, читая членство в группе из claim groups токена и оценивая политики против него. Нет реестра для перечисления и нет учётных записей для предварительного создания, и поэтому нет эндпоинта SCIM, потому что нечего синхронизировать в SCIM.
Запустите управление жизненным циклом пользователя и группы в источнике истины, который является собственной подготовкой SCIM вашего IdP или выделенной платформой управления идентификацией. Членство и отзыв, управляемые там, автоматически поступают в шлюз через токен. Если вы хотите подготовку SCIM самих учётных записей Claude, это возможность Claude for Enterprise.
Применяются два часов распространения:
- Содержание политики: редактирование политики и переразвёртывание достигает подключённых клиентов при их следующем опросе управляемых настроек, в течение часа, кроме изменений, которые применяются только при следующем запуске
- Членство в группе: изменение членства пользователя в группе изменяет, какая политика ему соответствует. Это вступает в силу при следующем перевыпуске сессии, то есть при следующем молчаливом обновлении, ограниченном
session.ttl_hours.
Запуск сессий на модели, которую разрешает политика
Если availableModels не включает модель Claude Code по умолчанию, сессии получают ответы 400, пока разработчик не выберет модель из списка, например с помощью /model. В сессиях шлюза моделью по умолчанию является модель Opus, в которую разрешается псевдоним opus, и сам по себе availableModels этого не меняет.
Чтобы исправить это, установите enforceAvailableModels: true в том же блоке cli, затем проверьте, какие записи содержит список:
- Псевдоним, такой как
sonnet, или встроенный ID, такой какclaude-sonnet-4-6: сессии начинаются на одной из этих моделей, и вариант Default в/modelразрешается в неё - В списке нет ни псевдонима, ни встроенного ID: сессии могут по-прежнему начинаться на встроенной модели по умолчанию, поэтому также установите
modelна один из перечисленных ID в блокеcliэтой политики
Эта политика перечисляет один пользовательский ID, определённый в models, и запускает сессии на этом ID:
managed:
policies:
- match: { groups: [restricted-projects] }
cli:
availableModels: [claude-opus-restricted]
enforceAvailableModels: true
model: claude-opus-restricted
Значения сопоставления, которые останавливают шлюз при загрузке
При загрузке шлюз проверяет блок match каждой политики и список admin_groups. Любое из этих значений останавливает шлюз с ошибкой, которая называет поле:
- Пустой список
groups - Пустая запись в
groupsили вadmin_groups - Пустой
email_domain email_domain, содержащий@, пробел или запятую. Шлюз обрезает значение и удаляет один ведущий@перед этой проверкой. Напишите один простой домен, такой какexample.com.
До v2.1.232 шлюз запускался с этими значениями. Каждое значение имело этот эффект:
- Пустой
email_domain: шлюз пропустил проверку домена, поэтому политика с пустымemail_domainи без спискаgroupsсоответствовала каждому аутентифицированному пользователю - Пустой список
groups: политика не соответствовала никому email_domain, содержащий@, пробел или запятую: политика не соответствовала никому- Пустая запись в
groupsили вadmin_groups: запись соответствовала пользователю только когда claimgroupsIdP этого пользователя также содержал пустую запись. Вadmin_groupsэто совпадение предоставляло доступ администратора. Если ваш списокadmin_groupsникогда не содержал пустую запись, никто не получал доступ администратора таким образом.
Что входит в `cli`
Каждое значение cli — это полный документ Claude Code managed-settings.json, та же схема, которую вы развернули бы через MDM или /etc/claude-code/managed-settings.json, выраженная здесь как YAML. CLI применяет доставленный документ на управляемом уровне, выше пользовательских и проектных настроек, вместо управляемых на сервере настроек. Поэтому он игнорирует настройки ограниченные источниками политики на уровне ОС, такие как policyHelper и wslInheritsWindowsSettings.
Шлюз проверяет каждый документ против схемы настроек CLI при загрузке, поэтому неизвестный ключ верхнего уровня вызывает сбой при загрузке с ошибкой, называющей каждый нарушающий ключ. Намеренно открытые части схемы всё ещё принимают произвольные значения, потому что более новые клиенты могут распознавать записи, которые схема шлюза не распознаёт. Эти открытые ключи включают env, pluginConfigs и ключи, вложенные под permissions.
Поскольку проверка использует схему, поставляемую с установленной версией шлюза, помещение ключа настроек верхнего уровня, введённого более новым выпуском Claude Code, в управляемую конфигурацию требует сначала обновления шлюза. Протестируйте новую политику на одном клиенте перед развёртыванием.
Полная справка по ключам находится в Claude Code settings. Ключи, которые операторы чаще всего используют в первую очередь:
managed:
policies:
- match: {}
cli:
# Model access (also enforced server-side at /v1/messages)
availableModels: [claude-opus-4-8, claude-sonnet-4-6, claude-haiku-4-5]
enforceAvailableModels: true # Default resolves inside the list
# Permission policy
permissions:
deny:
- "WebFetch"
- "Read(./.env)"
- "Read(./secrets/**)"
disableBypassPermissionsMode: disable # blocks --dangerously-skip-permissions
allowManagedPermissionRulesOnly: true # ignore user/project permission rules
# Environment pushed into the CLI process. DISABLE_UPDATES blocks
# background and manual updates; DISABLE_AUTOUPDATER stops only
# background updates.
env:
DISABLE_UPDATES: "1" # pin versions via your own distribution
# Org-wide hooks. Hook commands run on developer machines, not the
# gateway, so the path must exist on every client OS in the policy.
hooks:
PostToolUse:
- matcher: "Edit|Write"
hooks:
- { type: command, command: /usr/local/bin/audit-edit.sh }
| Ключ | Применяется | Эффект |
|---|---|---|
availableModels |
Шлюз + CLI | Список разрешённых моделей. Также проверяется в /v1/messages, поэтому исправленный клиент не может его обойти. |
permissions.allow / .deny |
CLI | Правила инструментов и команд. Смотрите Permissions. |
permissions.disableBypassPermissionsMode |
CLI | Установите на disable, чтобы заблокировать bypassPermissions, режим, который пропускает запросы разрешений, и флаг --dangerously-skip-permissions |
allowManagedPermissionRulesOnly |
CLI | Когда true, управляемые настройки становятся единственным источником настроек правил разрешений. Запись allowManagedPermissionRulesOnly перечисляет каждый источник, который Claude Code затем игнорирует. |
env |
CLI | Переменные окружения объединены в процесс CLI. Используйте для телеметрии, автоматического обновления и переопределения имён моделей. |
hooks |
CLI | Организационные хуки |
managedMcpServers |
CLI | Удалённые MCP-серверы предоставляемые каждому соответствующему разработчику наряду с серверами, которые они добавляют сами, только http и sse. Смотрите MCP-серверы в политике. Требует Claude Code v2.1.259 или позже на сервере шлюза и на клиентах. Более ранние клиенты игнорируют ключ. |
Поскольку эти настройки поступают по сети, CLI показывает каждому разработчику диалог одобрения безопасности перед применением настроек, указанных ниже:
hooks- Переменные
env, требующие одобрения разработчика, такие как переменные прокси и базового URL - Настройки выполнения оболочки, такие как
apiKeyHelperиstatusLine - Настройки двоичного файла песочницы
sandbox.bwrapPath,sandbox.socatPathиsandbox.ripgrep - Настройки песочницы, которые перехватывают трафик, внедряют учётные данные или ослабляют изоляцию, такие как
sandbox.network.tlsTerminateи настройки портов прокси. Диалоги одобрения безопасности перечисляют их все.
Память одобрения охватывает, как долго длится одобрение и когда диалог появляется снова.
Claude Code применяет некоторые доставленные переменные env без показа разработчику диалога одобрения безопасности, такие как настройки выбора модели и числовые ограничения. Другие доставленные переменные могут требовать одобрения разработчика перед вступлением в силу; непустое значение прокси, базового URL или OTEL_EXPORTER_OTLP_ENDPOINT всегда требует. Когда доставленная переменная требует одобрения, диалог называет её.
Переменные окружения и диалог одобрения содержит детали, включая четыре переключателя конфиденциальности, чьё доставленное значение решает, требуют ли они одобрения. До v2.1.218 Claude Code применял меньше переменных без запроса разработчика, поэтому больше доставленных переменных вызывали диалог.
Конфигурация телеметрии шлюза отправляет OTEL_EXPORTER_OTLP_ENDPOINT, поэтому установка telemetry.forward_to вызывает диалог на каждом интерактивном клиенте. Диалог защищает машину разработчика от скомпрометированного или враждебного шлюза, а не организацию от разработчика.
Неинтерактивный запуск, такой как claude -p или сессия Agent SDK, не может показать диалог. Он применяет отправленные настройки только для этого запуска и не записывает их как одобренные, поэтому следующая интерактивная сессия разработчика всё ещё показывает диалог. До v2.1.207 неинтерактивный запуск сохранял настройки как одобренные и ни одна более поздняя интерактивная сессия не показывала диалог для них.
Если разработчик отклоняет, Claude Code завершает эту сессию, а не применяет политику. Когда вы отправляете новый хук или любую переменную env, которая вызывает диалог, в широкую политику, каждый соответствующий разработчик видит диалог в своих интерактивных сессиях. Работающая интерактивная сессия показывает его при следующем ежечасном опросе, в противном случае он появляется при следующем интерактивном запуске разработчика.
Ключ cli был назван settings в более ранних выпусках. Это написание всё ещё принимается как псевдоним, но новые развёртывания должны использовать cli.
Контекстное окно в терминальных сессиях
Терминальные сессии, в которые выполнен вход через /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 политики:
managed:
policies:
- match: {}
cli:
env:
CLAUDE_CODE_AUTO_COMPACT_WINDOW: "200000"
Claude Code применяет эту переменную без показа разработчику диалога одобрения. Переменная применяется ко всем моделям, включая ID моделей, заканчивающиеся на [1m].
Чтобы вместо этого отключить контекст 1M, установите CLAUDE_CODE_DISABLE_1M_CONTEXT: "1" в том же блоке env. Тогда Claude Code считает, что у каждой модели окно 200K. В интерактивных сессиях каждый разработчик одобряет эту переменную в диалоге одобрения, прежде чем она вступит в силу.
MCP-серверы в политике
Чтобы предоставить MCP-серверы клиентам Claude Code, которым соответствует политика, установите managedMcpServers в блоке cli этой политики. Вам нужен Claude Code v2.1.259 или позже на сервере шлюза и на клиентах.
Шлюз проверяет каждую запись при загрузке с теми же правилами, которые Claude Code применяет на клиенте, и если запись не проходит проверку, шлюз отказывается запускаться и называет запись.
Если вы напишете ссылку ${VAR} в gateway.yaml, шлюз разрешит её из своего окружения при загрузке через расширение секретов перед запуском проверок записей, поэтому каждый соответствующий клиент получает буквальное значение и может его прочитать. Руководство по заголовкам для предоставленных серверов применяется к расширенному значению.
Шлюз отклоняет написание .mcp.json mcpServers в блоке 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.
Шлюз выводит большую часть ответа из блока cli соответствующей политики и из конфигурации шлюза верхнего уровня:
-
Список моделей из
availableModels. Расширенный контекст в Claude Desktop описывает вариант с контекстом 1M для каждой модели -
Отключённые инструменты из записей
permissions.denyс простым названием инструмента. Если вы установитеdisabledBuiltinToolsв блокеdesktopполитики, шлюз обслуживает объединение вашего значения и выведённого списка, поэтому вы можете отключить больше инструментов таким образом, но не можете повторно включить инструмент, который вы отключили черезpermissions.deny -
Список разрешённых исходящих соединений из
sandbox.network.allowedDomains. Если вы установитеcoworkEgressAllowedHostsв блокеdesktopполитики, шлюз использует это значение вместо выведённого списка -
Эндпоинт 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 или собственную настройку Claude Desktop managedMcpServers в блоке desktop политики, вам нужен Claude Code v2.1.232 или позже на сервере шлюза. managedMcpServers Claude Desktop принимает значение массива, а не объекта.
Шлюз опускает ключи без эквивалента Claude Desktop, такие как hooks и правила разрешений для каждой области, такие как Bash(npm *), из ответа bootstrap.
Добавьте опциональный блок desktop рядом с cli, чтобы установить настройки Claude Desktop напрямую. Напишите настройки из справочника управляемой конфигурации Claude Desktop как плоские имена ключей. Не указывайте ключи, которые Claude Desktop читает только из MDM или локальных файлов, такие как bootstrapUrl; шлюз отклоняет их при загрузке. До v2.1.232 шлюз принимал фиксированный список из 11 ключей функциональных ворот, таких как chatTabEnabled и disableAutoUpdates, и отклонял каждый другой ключ при загрузке. До v2.1.227 шлюз также отклонял chatTabEnabled и chatAdvancedFileAnalysisEnabled при загрузке.
managed:
policies:
- match: { groups: [eng-contractors] }
cli:
availableModels: [claude-sonnet-4-6]
enforceAvailableModels: true
desktop:
isLocalDevMcpEnabled: false
disableAutoUpdates: true
banner: { text: "Contractor build: internal use only" }
Каждый ключ опционален; Claude Desktop применяет свой собственный стандарт для любого ключа, который вы опустите. Шлюз проверяет каждый блок desktop при загрузке против схемы конфигурации, которую использует сам Claude Desktop, поэтому ошибка появляется при запуске шлюза как ошибка, называющая ключ, а не достигает каждого подключённого рабочего стола. Шлюз не запускается, когда блок содержит:
- Неизвестный ключ
- Распознанный ключ, чьё значение Claude Desktop отклонил бы или молча удалил, такое как пустое значение или неправильно написанный подключ внутри вложенной записи. До v2.1.260 шлюз молча удалял неправильно написанное поле внутри вложенного объекта записи
managedMcpServersилиorgPluginSettingsвместо отказа при загрузке. - Ключ, который шлюз вычисляет сам: соединение вывода, список моделей и реле OTLP. Настройте их через
upstreams,modelsи разделtelemetryforward_to. - Устаревший псевдоним текущего ключа. В ошибке загрузки шлюз называет канонический ключ для написания.
Если вы используете устаревшее значение или форму записи, такую как запись managedMcpServers без transport, шлюз запускается и записывает в лог предупреждение, которое называет замену.
Шлюз проверяет блок 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 записи Microsoft 365 managedMcpServers. Выпуски Claude Desktop, которые предшествуют значению required, читают его как disabled, поэтому установите required только после того, как каждый член Claude Desktop его поддерживает. Справочник управляемой конфигурации Claude Desktop перечисляет выпуск, который первым читает каждый ключ.
Если вы установите orgPluginSettings в блоке desktop политики, шлюз обслуживает его в форме массива, которую читают Claude Desktop 1.15200.0 и позже. Более старые рабочие столы игнорируют массив и не применяют политику инструмента плагина, поэтому обновите членов до 1.15200.0 или позже перед тем, как полагаться на это.
Шлюз заполняет ключи, которые блок desktop политики не устанавливает, из блока desktop catch-all match: {}, так же как он заполняет блок cli политики из базового. Если вы установите disabledBuiltinTools или builtinToolPolicy как в базовом, так и в политике роли, шлюз сохраняет ограничение базового:
disabledBuiltinTools: шлюз использует объединение списка базового и списка политикиbuiltinToolPolicy: если вы установите инструмент на значение, отличное отallow, в базовом, шлюз сохраняет это значение, даже если вы установитеallowдля того же инструмента в политике роли
Для каждого другого ключа, если вы установите его в политике роли, шлюз использует значение политики роли. Шлюз заменяет массив или вложенный объект, такой как banner, целиком, поэтому если вы установите banner.text в политике роли, шлюз удаляет banner.backgroundColor базового.
Если вы не развёртываете Claude Desktop, полностью исключите desktop из ваших политик; шлюз затем возвращает 404 из /user/bootstrap для каждого пользователя.
Расширенный контекст в 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, к которому шлюз обращается только при failover
- Ни её
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.
Этот пример предлагает вариант вручную для пользовательского псевдонима, направленного на профиль вывода приложения, и начинает новых пользователей с него:
models:
- id: corp-sonnet
upstream_model:
bedrock: arn:aws:bedrock:us-east-2:123456789012:application-inference-profile/sonnet-5-prod
- id: corp-sonnet[1m]
upstream_model:
bedrock: arn:aws:bedrock:us-east-2:123456789012:application-inference-profile/sonnet-5-prod
managed:
policies:
- match: {}
desktop:
modelPrefer1mContext: true
Удаление варианта 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. Чтобы пропустить реле и заставить сессии экспортировать прямо на ваш сборщик, назовите сборщик в политике. Смотрите Monitoring usage для метрик и событий, которые CLI излучает.
В сессиях, в которые выполнен вход через /login, CLI штампует каждый экспорт идентификацией аутентифицированного пользователя, прочитанной из выданного шлюзом JWT: атрибуты user.id, user.email и user.groups. Атрибуция затрат и использования на разработчика поэтому работает без конфигурации на стороне разработчика.
Claude Desktop и сессии Cowork, в которые выполнен вход через шлюз, штампуют свою телеметрию с user.email и user.groups наряду с enduser.id, поэтому вы можете охватить использование терминала, Desktop и Cowork одним запросом на user.email или user.groups. user.groups — это список групп IdP, разделённый запятыми.
Телеметрия Desktop и Cowork также несёт enduser.sub, claim sub, который выдаёт ваш поставщик идентификации для пользователя, который остаётся одинаковым, когда электронная почта пользователя изменяется. Терминальные сессии штампуют то же значение под 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 этого пользователя сохраняет свои другие атрибуты.
Вам нужен Claude Code v2.1.265 или позже на сервере шлюза для user.email и user.groups на телеметрии Desktop и Cowork, и Claude Desktop 1.24012 или позже на машине каждого разработчика для user.groups.
Вам нужен Claude Code v2.1.274 или позже на сервере шлюза для enduser.sub.
telemetry:
forward_to:
- url: https://otel-collector.internal.example.com
headers:
Authorization: ${OTLP_TOKEN}
# Per-signal opt-in. Default: metrics only.
metrics: true
logs: false
traces: false
- url: https://api.datadoghq.com/api/v2/otlp
headers:
DD-API-KEY: ${DD_API_KEY}
Каждое назначение согласует metrics, logs и traces независимо, и по умолчанию только метрики. Сигналы отличаются по чувствительности:
- Metrics: совокупные счётчики, такие как количество токенов, количество запросов и задержка
- Logs и traces: могут нести полные команды Bash, входные данные инструмента и пути файлов, охватывая всё, что делает Claude Code на машине разработчика
Включайте логи и трассировки только на назначениях с элементами управления доступом и политикой хранения, которые данные оправдывают.
Каждый URL forward_to должен использовать https://, с одним исключением для сборщика на собственном интерфейсе обратной связи шлюза:
http://localhost:<port>проходит проверку конфигурации, но защита SSRF блокирует каждый экспорт сECONNREFUSED_SSRF, если вы не установитеCLAUDE_GATEWAY_ALLOW_LOOPBACK=1в окружении шлюзаhttp://127.0.0.1:<port>илиhttp://[::1]:<port>не запускается, если эта переменная не установлена
Для сборщика в кластере выставьте его по HTTPS на его собственный внутренний адрес, или запустите его как sidecar с установленной переменной.
Когда установлен 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, с включёнными логами или трассировками, если они их экспортируют, поэтому он продолжает получать их данные после входа. Чтобы пропустить реле вместо этого, назовите сборщик в политике.
Traces также требуют CLAUDE_CODE_ENHANCED_TELEMETRY_BETA=1 на каждом клиенте. Установите его в блоке env управляемой политики, так как шлюз его не отправляет. Разработчики одобряют его в том же диалоге одобрения безопасности, который уже вызывает отправленный эндпоинт.
Установите его на 1 только в политиках, чьи группы вы хотите отследить. Политика, которая его не устанавливает, наследует значение из вашей политики catch-all match: {}, если эта политика устанавливает одно, согласно правилам объединения. Чтобы помешать клиентам группы отправлять трассировки, даже когда разработчик устанавливает переменную локально, установите её на 0 в политике этой группы.
Оба кодирования OTLP protobuf и JSON передаются, и любой совместимый с OpenTelemetry бэкенд работает как назначение.
Добавьте свои собственные метки
Чтобы поместить фиксированные метки, такие как service.namespace или deployment.environment.name, на телеметрию сессий, в которые выполнен вход через шлюз, установите telemetry.resource_attributes. Каждая метка — это атрибут ресурса OpenTelemetry, и каждое назначение получает одинаковые метки.
Сессии получают метки только когда вы также устанавливаете telemetry.forward_to и listen.public_url. Этот пример добавляет две метки:
telemetry:
forward_to:
- url: https://otel-collector.internal.example.com
resource_attributes:
service.namespace: claude
deployment.environment.name: prod
Шлюз отказывается запускаться, когда метка нарушает одно из этих правил, и ошибка запуска называет метку:
- Имена используют только буквы, цифры,
.,_и- - Имена не зарезервированы. Сравниваемые в любом регистре букв, зарезервированные имена — это всё, что начинается с
user.,enduser.илиidentity., плюсservice.name,service.version,claude.deployment_mode,host.arch,os.type,os.versionиwsl.version - Значения — это непустой печатный ASCII без пробела и ни один из
, ; = \ " % - Значения не более 255 символов, как шлюз их считает после процентного кодирования, поэтому
/,:и@каждый считаются как три - Значения — это текст, поэтому заключайте в кавычки число,
trueилиfalse
Вам нужен Claude Code v2.1.281 или позже на сервере шлюза, чтобы установить telemetry.resource_attributes. Более ранний шлюз отказывается запускаться, когда находит ключ. Обновите каждую реплику перед добавлением ключа и удалите ключ перед откатом на более раннюю версию.
Терминальные сессии, в которые выполнен вход через /login, получают метки как OTEL_RESOURCE_ATTRIBUTES, отправленные с другими переменными телеметрии. Если вы установите OTEL_RESOURCE_ATTRIBUTES в блоке env политики, терминальные сессии, которым соответствует эта политика, получают это значение вместо меток. Claude Desktop получает метки от шлюза наряду с user.email и другими атрибутами идентификации.
Claude Code также копирует каждую метку на каждую точку данных метрики, поэтому вы можете фильтровать метрики по ней в бэкенде, который не индексирует атрибуты ресурса. Чтобы отключить эту копию, смотрите Metrics cardinality control.
Экспорт прямо на ваш сборщик
Чтобы сессии, в которые выполнен вход через /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://, илиhttp://на адрес обратной связи - URL разрешается на путь, заканчивающийся на
/v1/<signal>, без запроса или фрагмента. Claude Code формирует этот путь сам из общей переменной. Он использует переменную для каждого сигнала, такую какOTEL_EXPORTER_OTLP_METRICS_ENDPOINT, как написано, поэтому включите полный путь туда. - URL не является собственным хостом шлюза. Эндпоинт, адресованный шлюзу, сохраняет путь реле и его токен сессии.
- Ни вы, ни разработчик не настроили
otelHeadersHelperни в каком источнике настроек. С настроенным помощником каждый сигнал остаётся на реле.
Эндпоинт, который вы называете, изменяет только то, куда идут экспорты. Вы всё ещё выбираете, какие сигналы экспортируются вообще, с селекторами OTEL_*_EXPORTER.
Эндпоинт сам по себе не включает экспорт, поэтому также установите переменные, которые это делают, если шлюз их уже не отправляет:
- Если шлюз уже отправляет переменные телеметрии, они охватывают включение, селекторы и протокол, и ваш явный эндпоинт переопределяет отправленное значение
<public_url>. Установите селекторOTEL_*_EXPORTERнаotlpсами только для сигнала, который ни одно назначениеforward_toне включает. - Если нет, также установите
CLAUDE_CODE_ENABLE_TELEMETRY=1, селекторыOTEL_*_EXPORTERиOTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf.
Когда разработчик выходит, или входит на другой шлюз, экспорты на сборщик останавливаются и Claude Code удаляет каждый оставшийся пакет, а не отправляет его.
Когда назначение не удаётся
Шлюз не буферизирует, не повторяет и не хранит телеметрию, поэтому он удаляет экспорт, который не достигает назначения, а не доставляет его поздно. Каждое назначение успешно или не удаётся само по себе, и экспортирующий клиент получает ответ об успехе в любом случае, поэтому неудачная доставка появляется только в логе шлюза.
После пяти последовательных неудачных доставок на назначение шлюз приостанавливает пересылку на него на 30-секундные интервалы, записывая в лог каждую паузу, пока доставка не удаётся. Любой ответ об ошибке, таймаут или ошибка соединения считаются неудачной доставкой, кроме 400, 413, 415, 422 и 431, которые означают, что сборщик отклонил полезную нагрузку этого экспорта как неправильно сформированную или слишком большую.
Отклонённая полезная нагрузка ни продвигает, ни сбрасывает счётчик отказов: шлюз продолжает пересылку на назначение и записывает в лог предупреждение, называющее его и статус, при первом отказе назначения и каждом сотом после.
Настройка HTTP
Четыре опциональных блока верхнего уровня, access_control, limits, timeouts и rate_limits, настраивают HTTP поверхность. Значения по умолчанию подходят для большинства развёртываний.
| Блок | Ключ | По умолчанию | Описание |
|---|---|---|---|
access_control |
allow_cidrs / deny_cidrs |
пусто | Входящий IP разрешить/запретить по адресу клиента, после разрешения trusted_proxies. deny_cidrs проверяется первым; клиент, которому он соответствует, отклоняется, даже если allow_cidrs также соответствует. Если allow_cidrs не пусто, шлюз по умолчанию отклоняет. /healthz и /readyz исключены из allow_cidrs. Когда доверенный прокси отправляет запись X-Forwarded-For, которая не является IP адресом, реальный клиент неизвестен и шлюз один раз записывает в лог предупреждение, называя, что проверить. Где применяется либо список, он отклоняет запрос с 403 и причиной аудита xff_unparseable. Где ни один не применяется, он обслуживает запрос и использует собственный адрес прокси как IP клиента для ограничений частоты запросов на IP и аудита. |
limits |
max_request_bytes |
32 MiB | Максимальный размер входящего тела запроса; запросы большего размера получают 413 перед буферизацией тела. Поднимите для больших запросов файлов или изображений. |
limits |
max_request_header_bytes |
не установлено | Снижает установленный в шлюзе лимит в 256 KiB на общий размер заголовков запроса. Запрос сверх лимита возвращает 431, а значение выше 256 KiB ни на что не влияет. Если разработчики получают 431 после входа, смотрите Слишком большие заголовки запроса после входа. |
limits |
max_url_length |
не установлено | Когда установлено, слишком длинный URL возвращает 414 |
timeouts |
upstream_ttfb_ms |
120000 | Максимальное ожидание заголовков ответа upstream (время до первого байта). Тело ответа затем передаётся потоком без ограничения по общему времени. Применяется к прямому пути upstream Anthropic; на каждом другом поставщике шлюз ждёт до одного часа, пока ответ не начнётся. |
rate_limits |
device_authorization.max / .window_seconds |
30 / 600 | Ограничение частоты запросов на IP для неаутентифицированного эндпоинта авторизации устройства. Поднимите для большой организации за общим исходящим IP или NAT. Large rollouts показывает, как подобрать его размер. Эти ограничения применяются только к потоку входа с кодом устройства, а не к выводу /v1/messages. Смотрите User-code brute-force resistance. |
rate_limits |
device_verify.max / .window_seconds |
10 / 600 | Ограничение частоты запросов на IP для отправок user_code в /device. Это то, что не даёт кому-либо угадать код другого разработчика. Large rollouts показывает, как далеко его поднять. |
Если вы оставите оба списка access_control пустыми, что является значением по умолчанию, шлюз обслуживает любой адрес клиента, поэтому только ваша сеть ограничивает, кто может его достичь. Это важно, потому что шлюз может отправлять управляемые настройки, которые запускают команды на машинах разработчиков.
Пока allow_cidrs пусто, шлюз предупреждает в двух местах, не изменяя, как он отвечает на любой запрос:
- При загрузке: предупреждение в операционном логе рекомендует разрешить только частные диапазоны
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,100.64.0.0/10,127.0.0.0/8,::1/128иfc00::/7, плюс любые другие внутренние диапазоны, из которых ваши разработчики подключаются. Если вы привязываете шлюз к адресу обратной связи и не устанавливаете ниtrusted_proxies, ниpublic_url, как при локальной разработке, предупреждение не появляется. - При выполнении: первый раз, когда запрос поступает с адреса вне этих частных диапазонов, шлюз записывает в лог предупреждение и излучает событие аудита
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 секунд:
load_test_mode:
enabled: true
reply_tokens: 750 # roughly how many tokens of text each canned reply carries
reply_seconds: 9.5 # how long a streamed reply takes
| Поле | Обязательно | Описание |
|---|---|---|
enabled |
Да | true включает режим. false сохраняет ваши числа в файле с выключенным режимом. Шлюз отказывается запускаться, если блок присутствует без него. |
reply_tokens |
Нет | По умолчанию 750. Примерно сколько токенов текста несёт каждый заготовленный ответ, целое число от 1 до 100000. |
reply_seconds |
Нет | По умолчанию 9.5. Как долго передаётся потоковый ответ, от 0 до 600. 0 отправляет весь ответ сразу. Ответ на запрос без потока всегда приходит сразу. |
Нагрузочное тестирование в этом режиме охватывает шлюз, ваш Postgres и всё перед шлюзом. Оно не охватывает ограничения, скорость или сетевой путь поставщика.
Никакой запрос модели не отправляется поставщику, поэтому CPU реплики на запрос — это оценка, и она ниже, чем в продакшене, где трафик к поставщику также шифруется. Подтвердите количество реплик небольшим пилотом с реальным поставщиком. До v2.1.283 оценка намного ниже.
Пока режим включён, запрос может нести заголовок x-load-test-user, содержащий целое число до семи цифр. Шлюз считает каждое число отдельным разработчиком, с электронной почтой и группами разработчика, чей токен пришёл с запросом.
Дайте развёртыванию нагрузочного тестирования свою собственную пустую базу данных, потому что шлюз отказывается запускаться с включённым режимом с базой данных, в которой какой-либо разработчик уже что-либо потратил.
Никогда не включайте это для шлюза, который используют разработчики. Каждый запрос получает заготовленный ответ и ни одна модель не вызывается. Шлюз записывает в лог предупреждение load_test_mode is on при загрузке и помечает каждое событие аудита inference с load_test: true, пока режим включён.
Полный пример
Этот полный справочный конфиг использует каждый основной раздел; блоки настройки HTTP сохраняют свои значения по умолчанию. Скопируйте его, удалите то, что вам не нужно, и заполните свои значения. Конфиг в Quickstart — это минимальная версия этого.
# Запуск с помощью:
# claude gateway --config gateway.yaml
#
# Подробность операционного журнала контролируется переменной окружения
# CLAUDE_GATEWAY_LOG_LEVEL (debug | info | warn | error; по умолчанию info). debug
# также логирует имена утверждений в каждом id_token для диагностики groups_claim.
# Это не влияет на события аудита, которые всегда генерируются.
listen:
host: 0.0.0.0
port: 8080
public_url: https://claude-gateway.internal.example.com
# Опустите блок tls при запуске за TLS-завершающим ingress.
# tls:
# cert: /certs/gateway.crt
# key: /certs/gateway.key
# trusted_proxies:
# - 10.0.0.0/8
oidc:
issuer: https://example.okta.com
client_id: 0oa1example2
client_secret: ${OIDC_CLIENT_SECRET}
allowed_email_domains:
- example.com
# Требуется, когда издатель является сервером организации Okta, чьи id_tokens
# могут опускать email и groups; шлюз заполняет их из /userinfo.
userinfo_fallback: true
# allowed_groups: [claude-code-users]
# Okta выдает groups только когда запрашивается scope `groups` и
# фильтр утверждения groups приложения их разрешает. Политика contractors ниже
# соответствует groups, поэтому scope запрашивается здесь.
scopes: [openid, profile, email, offline_access, groups]
# extra_auth_params: { access_type: offline, prompt: consent } # Google
# groups_claim: groups # Роли приложения Entra: используйте `roles`
# email_claim: email
session:
jwt_secret: ${GATEWAY_JWT_SECRET} # openssl rand -base64 32
# ttl_hours: 1
store:
postgres_url: ${GATEWAY_POSTGRES_URL}
# max_connections: 5
# connect_timeout_seconds: 5
# readiness_grace_seconds: 300 # продолжайте проходить проверку готовности через отказ базы данных
# Включает /v1/organizations/spend_limits (зеркалирует Admin API Anthropic)
# и принудительное соблюдение лимитов расходов на разработчика на /v1/messages. Опустите для отключения.
# Сами лимиты устанавливаются через admin API, а не здесь.
# admin:
# write_keys:
# - { id: terraform, key: "${GATEWAY_ADMIN_WRITE_KEY_TF}" }
# read_keys:
# - { id: reporting, key: "${GATEWAY_ADMIN_READ_KEY}" }
# admin_groups: [platform-finops]
# blocked_message: request an increase at https://go.example.com/claude-limits
# # audit_retention_days: 365
# # spend_retention_months: 13
# # identity_retention_days: 90
# # group_limit_mode: min
# enforcement:
# fail_closed_on_error: false
# Нагрузочное тестирование этого развёртывания без вызова поставщика модели. Никогда на
# шлюзе, который используют разработчики: каждый запрос получает заготовленный ответ.
# load_test_mode:
# enabled: true
# # reply_tokens: 750
# # reply_seconds: 9.5
# Измеряйте по договорным ставкам вместо цены USD по прайс-листу. Требует admin: или
# managed: политику. С managed:, те же ставки также идут подписанным клиентам.
# Ставки ниже — это заполнители, а не реальные договорные цены.
# pricing:
# multiplier: 0.85
# overrides:
# - { upstream: anthropic, model: claude-sonnet-4-6, input: 3.30, output: 16.50, cache_read: 0.33, cache_write: 4.125 }
upstreams:
- provider: anthropic
auth:
api_key: ${ANTHROPIC_API_KEY}
# - provider: bedrock
# region: us-east-1
# auth: {}
# - provider: mantle
# region: us-east-1
# models: [claude-opus-4-8, claude-opus-4-7, claude-haiku-4-5]
# auth: {}
# - provider: anthropicAws
# region: us-east-1
# workspace_id: wrkspc_...
# auth:
# api_key: ${ANTHROPIC_AWS_API_KEY}
# - provider: vertex
# region: us-east5
# project_id: example-prod
# auth: {}
# - provider: foundry
# resource: example-foundry
# auth: { use_azure_ad: true }
auto_include_builtin_models: true
models:
- id: claude-opus-4-8
label: Claude Opus 4.8
upstream_model:
anthropic: claude-opus-4-8
# bedrock: us.anthropic.claude-opus-4-8
# mantle: anthropic.claude-opus-4-8
# anthropicAws: claude-opus-4-8
# vertex: claude-opus-4-8
# foundry: <your-opus-deployment-name>
- id: claude-sonnet-4-6
label: Claude Sonnet 4.6
upstream_model:
anthropic: claude-sonnet-4-6
- id: claude-haiku-4-5
label: Claude Haiku 4.5
upstream_model:
anthropic: claude-haiku-4-5
managed:
policies:
- match: { groups: [contractors] }
cli:
availableModels: [claude-haiku-4-5]
# allow автоматически одобряет эти инструменты; это не блокирует остальное.
# Добавьте правила deny для ограничения инструментов.
permissions: { allow: [Read, Grep] }
- match: {}
cli:
availableModels: [claude-opus-4-8, claude-sonnet-4-6, claude-haiku-4-5]
# Ограничьте опцию Default в выборе модели значением availableModels каждой политики
# вместо встроенного значения по умолчанию, чтобы ни одна роль не получила 400 на Default.
# Политика contractors наследует этот ключ.
enforceAvailableModels: true
permissions:
allow: [Read, Grep, Bash, Edit]
deny: ["WebFetch"]
env: { HTTP_PROXY: http://proxy.example.com:8080 }
telemetry:
forward_to:
- url: https://otel.internal.example.com:4318
headers:
Authorization: Bearer ${OTEL_TOKEN}
Управляемые параметры на стороне клиента
Всё выше настраивает сервер gateway. Указание машин разработчиков на него настраивается отдельно, на каждом устройстве, через управляемые параметры Claude Code. Gateway не может отправлять эти ключи сам, потому что они говорят клиенту, где находится gateway.
Для CLI установите эти ключи в managed-settings.json для каждой ОС. Два ключа входа маршрутизируют /login каждого разработчика на ваш gateway:
{
"forceLoginMethod": "gateway",
"forceLoginGatewayUrl": "https://claude-gateway.internal.example.com",
"parentSettingsBehavior": "merge"
}
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 разработчика или в полезной нагрузке gateway не настраивает вход в gateway.
Оставьте forceLoginMethod и forceLoginOrgUUID вне полезной нагрузки. Claude Code по-прежнему читает оба ключа из полезной нагрузки для проверки учётных данных при запуске, поэтому разработчик, который хранит выданные Anthropic учётные данные на машине, получает выход при запуске, описанный в разделе Политика администратора требует вход в Cloud gateway даже после того, как они вошли.
Связанное
- Обзор Claude apps gateway: quickstart и подключение разработчика
- Руководство по развёртыванию: настройка IdP, образ контейнера, Kubernetes и Cloud Run, и операции
- Лимиты расходов: ограничения для каждого разработчика и Admin API