SpyBara
Go Premium

claude-apps-gateway-deploy.md 2026-09-11 23:01 UTC to 2026-09-12 03:02 UTC

This page contains 14 additions and 5 deletions.

2026
Thu 10 23:00 Sat 12 03:02 Fri 18 23:58 Sat 19 23:57 Fri 25 23:58

Развертывание и эксплуатация шлюза Claude apps

Зарегистрируйте шлюз в вашем поставщике идентификации, создайте контейнер, разверните на Kubernetes или Cloud Run и управляйте им: проверки здоровья, ротация секретов, обновления и безопасность.

На этой странице рассматривается операционная сторона запуска шлюза Claude apps: регистрация клиента OAuth в вашем поставщике идентификации (IdP), развертывание шлюза как контейнера и его ежедневное управление. Для каждого параметра в файле gateway.yaml, который шлюз читает при загрузке, см. Справочник по конфигурации.

Развертывание в производстве следует четырем этапам по порядку, и разделы ниже соответствуют им. Первые два — это места, где вы делаете выбор; вторые два — справочный материал, который следует консультировать после запуска.

  1. Настройка вашего поставщика идентификации: зарегистрируйте клиента OAuth и проверьте примечания для каждого IdP для Okta, Entra и Google
  2. Развертывание шлюза: создайте образ контейнера с закрепленной версией и запустите его на Kubernetes, Cloud Run или вашей собственной платформе. Этот раздел также охватывает решения по стоимости, обходу, нескольким шлюзам и бессерверным вычислениям
  3. Настройка операций: журналы, зонды здоровья, поведение при сбое, ротация секретов и обновления. Справочник для подключения мониторинга и runbooks
  4. Проверка позиции безопасности: какие данные куда передаются, модель угроз и ответы на вопросы соответствия. Справочник для проверки безопасности

Если вход или загрузка не удаются, перейдите прямо к Устранению неполадок, который организован по ошибкам, которые вы видите.

Настройка поставщика удостоверений

Зарегистрируйте конфиденциальное веб-приложение OAuth/OpenID Connect (OIDC) с одним URI перенаправления, https://<gateway>/oauth/callback, и назначьте его пользователям или группам, которые должны иметь доступ к шлюзу.

Работает любой OIDC-совместимый IdP: Okta, Microsoft Entra ID, Google Workspace, Keycloak, Dex, PingFederate и другие. IdP должен соответствовать трем требованиям:

  • Обслуживает /.well-known/openid-configuration по HTTPS в production; шлюз принимает http:// издателя, и издатель loopback дополнительно требует CLAUDE_GATEWAY_ALLOW_LOOPBACK=1
  • Поддерживает поток authorization-code. PKCE (Proof Key for Code Exchange) включен по умолчанию; отключите его с помощью oidc.use_pkce: false для IdP, которые его не поддерживают
  • Возвращает email и опционально groups в id_token или обслуживает их из конечной точки userinfo с oidc.userinfo_fallback: true

Для приватной PKI установите oidc.ca_cert_pem.

Несколько поставщиков обрабатывают утверждения email и group по-разному:

  • Okta: сервер авторизации организации в https://example.okta.com возвращает тонкий id_token, который опускает email и groups, поэтому установите oidc.userinfo_fallback: true всякий раз, когда вы используете его как issuer. Пользовательский сервер авторизации, такой как https://example.okta.com/oauth2/default, который включает email и опционально groups в id_token, выдает их напрямую и не требует fallback. Okta выдает groups только когда область groups запрашивается в oidc.scopes и фильтр утверждения groups приложения это позволяет; userinfo_fallback не может заполнить утверждение, которое IdP не был попрошен выдать.
  • Microsoft Entra ID: issuer = https://login.microsoftonline.com/<tenant-id>/v2.0. Entra выдает Object ID групп, а не имена, поэтому используйте GUID в managed.policies.match.groups или используйте App Roles для читаемых имен. Если ваш tenant выдает роли под roles вместо groups, установите oidc.groups_claim: roles.
  • Google Workspace: issuer = https://accounts.google.com. id_token Google не содержит groups. Чтобы использовать основанные на группах allowed_groups или managed.policies с Google в качестве IdP, настройте oidc.google_groups, которая ищет группы каждого пользователя через Admin SDK Directory API, используя сервисный аккаунт с делегированием на уровне домена. Без этого используйте oidc.allowed_email_domains для проверки членства и managed.policies.match.email_domain для назначения политики. Google также игнорирует стандартную область offline_access. Для refresh tokens установите oidc.scopes: [openid, profile, email] и oidc.extra_auth_params: { access_type: offline, prompt: consent }.

Развертывание

Шлюз — это один stateless бинарный файл Linux, который координирует работу через Postgres, поэтому развертывайте его так же, как вы развертываете любой другой stateless сервис в вашей среде. Держите его внутри вашей сети, где ваши разработчики и IdP могут достичь его по HTTPS, и относитесь к нему как к любому сервису, содержащему production учетные данные.

Несколько решений формируют развертывание помимо того, где оно работает:

  • Стоимость: нет отдельной лицензии или платы за место. Шлюз является частью бинарного файла claude, поэтому вы платите за inference через ваше существующее обязательство, плюс вычисления, на которых он работает.
  • Обход: шлюз не требует, чтобы единственный маршрут к модели проходил через него. Разработчик со своими собственными учетными данными все еще может вызвать поставщика напрямую, поэтому закрытие этого пути — это решение политики сети, например блокировка выхода на api.anthropic.com кроме как от шлюза. Блокировка этого выхода также нарушает проверку безопасности домена WebFetch, которая вызывает api.anthropic.com с каждой машины разработчика. Установите skipWebFetchPreflight: true в управляемой политике, чтобы отключить это.
  • Несколько шлюзов: каждый — это отдельное развертывание со своей конфигурацией, и CLI хранит доверие и учетные данные для каждого имени хоста шлюза, поэтому команды могут использовать разные шлюзы без конфликтов. Чтобы обслуживать несколько издателей OIDC, запустите отдельные экземпляры.
  • Бессерверная архитектура: Cloud Run работает, если вы установите min-instances: 1, чтобы избежать холодного обнаружения OIDC. Lambda и Cloud Functions не работают, потому что шлюз — это долгоживущий HTTP сервер.

Каждая production топология здесь помещает прокси L7, такой как Ingress, фронтенд Cloud Run или ALB, перед простыми HTTP репликами. Установите listen.trusted_proxies на диапазоны источников прокси, чтобы шлюз читал IP клиентов из X-Forwarded-For. Шлюз соблюдает заголовок только когда TCP peer доверен. Пример Google Cloud и пример AWS содержат конкретные значения для каждой топологии. Без доверенных прокси каждый запрос выглядит как исходящий с IP прокси, что сворачивает ограничения скорости для каждого IP в один общий bucket и записывает IP прокси в события аудита.

Не перенаправляйте запросы на конечные точки авторизации устройства и токена шлюза, например с переписыванием HTTP-в-HTTPS или канонизацией хоста на ingress. Claude Code не следует перенаправлениям на эти запросы, поэтому правило ingress, которое их перенаправляет, нарушает вход и обновление токена.

Дайте прокси любой timeout неактивности, превышающий интервал keepalive шлюза, который зависит от upstream:

  • На каждом upstream кроме provider: anthropic, шлюз записывает SSE ping один раз, когда поток был молчалив около 15 секунд.
  • На provider: anthropic, шлюз пропускает ответ без изменений, включая собственные ping'и API Anthropic.

Значение по умолчанию, такое как 60 секунд ALB, достаточно, чтобы держать тихий поток открытым. Пример AWS поднимает его до часа в любом случае, и его строка troubleshooting охватывает шлюзы старше v2.1.229, которые не отправляли ничего во время тихих периодов на upstream'ах, которые теперь получают ping'и.

Образ контейнера

Создайте свой собственный образ вокруг нативного бинарного файла claude из стандартного выпуска Claude Code:

  1. Загрузите сборку Linux для архитектуры вашего образа из закрепленного выпуска; см. Установка конкретной версии для URL загрузки.
  2. Проверьте его против подписанного GPG manifest.json выпуска, как описано в Целостность бинарного файла и подпись кода.
  3. Скопируйте его в контекст сборки.

Зеркалируйте выпуск в ваш внутренний реестр, если ваши сборки не могут достичь хоста выпуска, и закрепите версию, которую запускает ваш флот.

Помимо бинарного файла, образу нужны:

  • Образ на основе glibc: единственные динамические зависимости сборки glibc — это библиотеки glibc. Образы на основе Musl нуждаются в сборке linux-x64-musl или linux-arm64-musl плюс дополнительные пакеты; см. Настройка Alpine Linux.
  • Записываемый каталог состояния: шлюз работает как любой пользователь, но минимальные образы не имеют записываемого home. Установите CLAUDE_CONFIG_DIR на записываемый путь, такой как /tmp/.claude.
  • Команда контейнера: claude gateway --config /etc/claude/gateway.yaml, с файлом конфигурации, смонтированным только для чтения, и секретами, предоставленными как переменные окружения; шлюз слушает на listen.port, по умолчанию 8080.

Kubernetes

Запустите шлюз как Deployment, как любой stateless сервис:

  • Смонтируйте конфигурацию из ConfigMap и секреты из Secret; ссылайтесь на секреты в YAML через ${file:/path/to/secret} или как переменные окружения
  • Завершите TLS на Ingress и установите listen.public_url на имя хоста Ingress
  • Укажите зонд готовности на GET /readyz и зонд живучести на GET /healthz

Для полного примера на AWS, охватывающего ECS Fargate или EKS, Amazon RDS и AWS Secrets Manager, см. Развертывание на AWS.

Предпочитайте workload identity платформы вместо статических ключей; справочник upstreams содержит детали настройки для каждой платформы. Для кросс-облачного сопряжения, такого как upstream Bedrock на GKE, установите явные учетные данные в блоке auth upstream вместо этого.

Cloud Run

Настройте сервис следующим образом:

  • Оставьте listen.port на его значении по умолчанию 8080, которое соответствует PORT Cloud Run по умолчанию, или установите port: ${PORT}
  • Установите public_url на внешне доступное происхождение. Для production это обычно имя хоста внутреннего балансировщика нагрузки, потому что /login отклоняет публичные адреса и URL *.run.app разрешается на один, поэтому URL Cloud Run один работает только для curl или дымового теста браузера. Исключение — сеть, где *.run.app разрешается приватно через Private Service Connect и приватную зону Cloud DNS; в этой топологии URL Cloud Run — это действительный public_url. Пример Google Cloud охватывает оба.
  • Смонтируйте конфигурацию как том секрета
  • Установите min-instances: 1, чтобы избежать холодного обнаружения OIDC при первом запросе

Для полного примера на Google Cloud, охватывающего Cloud Run или GKE, Cloud SQL и Secret Manager, см. Развертывание на Google Cloud.

Отправьте URL шлюза на машины разработчиков

Как только шлюз начнет обслуживать, отправьте forceLoginMethod, forceLoginGatewayUrl и parentSettingsBehavior: "merge" на каждую машину разработчика через управляемые параметры, через MDM или путем прямого написания файла managed-settings.json для каждой ОС. Без этого /login показывает стандартный выбор аккаунта без опции шлюза.

Как только вы развернете ключи, Claude Code перестанет использовать оставшийся API ключ или вход claude.ai на машине, поэтому спланируйте отправку вместе с вашими инструкциями по входу. Политика администратора требует вход через Cloud шлюз описывает сообщения, которые видят разработчики.

См. где каждый механизм хранит политику для путей файлов и Управляемые параметры на стороне клиента для эквивалента Claude Desktop bootstrapUrl.

Операции

Как только шлюз начнет обслуживать трафик, ежедневная операция — это чтение его логов, проверка его здоровья и ротация его секретов по вашему расписанию. Подразделы охватывают каждое, плюс то, что содержит Postgres и как ведут себя обновления и откаты.

Логи

Шлюз записывает два потока в stderr, оба JSON-дружественные:

  • События аудита: однострочный JSON для каждого события, связанного с безопасностью. Направьте stderr в ваш агрегатор логов. Выдаваемые события включают config.load, session.mint, session.refresh, device.authorize, device.verify, device.callback, auth.denied, access.denied, inference, managed.serve, desktop_bootstrap.serve, desktop_bootstrap.denied, spend.blocked, admin.denied, admin.limit.upsert и admin.limit.delete. Поля варьируются по событиям:
    • Успешные события mint и refresh содержат sub, email, client_ip и результат
    • auth.denied и access.denied содержат причину и IP клиента, плюс путь запроса для auth.denied, так как идентификация пользователя не существует при этих отказах. Две причины access.denied изменяют то, что несет событие:
      • xff_unparseable: событие также содержит запись X-Forwarded-For, которую не удалось прочитать
      • client_ip_unknown: событие не содержит IP клиента, потому что соединение не имело адреса peer, пока был установлен список access_control
    • inference записывает, какой upstream обслужил запрос и статус ответа
    • desktop_bootstrap.denied записывает отклоненную выборку Claude Desktop bootstrap с причиной (not_configured, policy_not_opted_in или no_policy_matched) и идентификацией пользователя
    • admin.denied записывает отклоненную попытку аутентификации admin-API с IP клиента, методом, путем и причиной, без представленного материала ключа: invalid_key когда был представлен x-api-key, но он не совпал ни с одним настроенным ключом, bearer_rejected когда был представлен только заголовок Authorization и он не проверился как сеанс шлюза в admin.admin_groups, или no_credentials когда ни один заголовок не был представлен
  • Операционные логи: читаемые для человека строки с префиксом [gateway] для загрузки, предупреждений и ошибок upstream. Переменная окружения CLAUDE_GATEWAY_LOG_LEVEL управляет многословностью и принимает debug, info, warn или error, с info по умолчанию. При debug, каждый вход и обновление также логируют имена, а не значения, утверждений в id_token, плюс имена утверждений userinfo когда userinfo_fallback предоставил какие-либо, поэтому вы можете диагностировать параметры email_claim и groups_claim без логирования PII. Это не влияет на события аудита, которые всегда выдаются.

Здоровье

Шлюз обслуживает GET /healthz как зонд живучести и GET /readyz как зонд готовности; /readyz проверяет доступность хранилища. Оба исключены из access_control.allow_cidrs, поэтому зонды продолжают работать на заблокированном слушателе.

Документ обнаружения OAuth в /.well-known/oauth-authorization-server также возвращает 200 только после загрузки конфигурации, обнаружения OIDC, построения клиента upstream и миграции Postgres, поэтому он также служит проверкой загрузки end-to-end.

Поведение при сбое

Если Postgres выходит из строя, сам шлюз продолжает обслуживать вошедших разработчиков, а новые входы не удаются. Продолжают ли разработчики работать, зависит от того, как ваш оркестратор обрабатывает готовность:

  • Существующие сеансы: bearer tokens проверяются локально с помощью JWT secret, обновления сеанса не касаются хранилища, и процесс шлюза все еще может обслуживать inference
  • Новые входы: не удаются до восстановления Postgres, потому что поток устройства и его счетчики ограничения скорости живут в Postgres
  • Применение ограничения расходов: по умолчанию не удается открыто во время сбоя, поэтому inference все еще течет; переключите его на отказ закрыто, если вы предпочитаете блокировать, чем работать без учета
  • Готовность: /readyz сообщает о неготовности во время сбоя, поэтому оркестраторы, которые управляют трафиком на готовность, удаляют каждую реплику из ротации сразу. В этой топологии весь трафик, включая inference, который шлюз все еще может обслуживать, не удается на балансировщике нагрузки до восстановления Postgres. Зонд живучести на /healthz продолжает проходить, поэтому реплики не перезапускаются. Укажите зонд готовности на /healthz вместо этого, если вы предпочитаете, чтобы вошедшие разработчики продолжали работать через сбой хранилища; стоимость в том, что новые входы не удаются против реплики, которая все еще сообщает о готовности.

Если ваш IdP выходит из строя, существующие сеансы работают до ttl_hours, а новые входы и обновления не удаются. Установите более длительный ttl_hours, если ваш IdP имеет частые окна обслуживания.

Ротация JWT secret

Ротируйте подписывающий secret в три этапа, чтобы существующие сеансы оставались действительными:

  1. Создайте новый secret. Добавьте его в начало массива session.jwt_secret.
  2. Разверните развертывание. Новые tokens подписываются новым secret; старые tokens все еще проверяются.
  3. После ttl_hours плюс запас, удалите старый secret и разверните снова.

Ротация также является единственным способом вынудить сеансы выйти до истечения: bearer tokens проверяются локально против JWT secret, поэтому нет отзыва для каждого сеанса. Замена secret полностью, без сохранения старого в массиве, делает недействительным каждый выдающийся сеанс сразу. Для индивидуального offboarding deprovision пользователя в вашем IdP; их сеанс заканчивается в течение ttl_hours.

Postgres

Шлюз содержит пять таблиц данных плюс таблицу _migrations, все созданные его миграциями при загрузке:

Таблица Содержимое Хранение
kv Гранты устройства (10-минутный TTL) и счетчики ограничения скорости TTL для каждой строки
spend Счетчики расходов за период для каждого principal, в центах admin.spend_retention_months, по умолчанию 13
spend_limits Настроенные лимиты расходов До удаления через API
admin_audit Трассировка мутаций Admin API admin.audit_retention_days, по умолчанию 365
principal_emails Последний просмотренный email каждого principal, отображаемое имя и группы IdP. Содержит PII. admin.identity_retention_days с момента последней активности, по умолчанию 90

Цикл на 30 секунд истекает строки kv прошедшие их TTL, и почасовая очистка применяет окна хранения на таблицы расходов, поэтому ничего не растет без ограничений. Без ограничений расходов настроенных, только kv записывается. Шлюз применяет свои собственные миграции схемы при загрузке и при каждом обновлении, поэтому его роль базы данных нуждается в правах для создания и изменения таблиц. Укажите его на базу данных или схему, выделенную для шлюза, чтобы сохранить это разрешение узким.

С ограничениями расходов в использовании, потерянная база данных означает потерю отслеживания расходов и лимитов, а не просто повторные входы разработчиков, поэтому запускайте регулярные резервные копии. Чтобы стереть одного ушедшего разработчика немедленно, а не ждать хранения, запустите DELETE FROM principal_emails WHERE principal = '<sub>' напрямую; это удаляет единственную таблицу, содержащую их email, имя и группы. Строки spend и admin_audit ссылаются только на псевдонимный OIDC sub.

Обновления

Реплики не имеют состояния, поэтому rolling restart безопасен в любое время. Шлюз запускает миграции схемы при загрузке, что означает, что развертывание нового бинарного файла автоматически мигрирует базу данных. Параллельные реплики сериализуются на advisory lock Postgres, поэтому только одна применяет каждую миграцию.

Миграции добавляются только, поэтому откат к предыдущему бинарному файлу, который знает меньше миграций, безопасен; он игнорирует дополнительные строки. Откат также переподтверждает YAML против схемы более старого бинарного файла, поэтому конфигурация, которая приняла ключ, введенный более новым выпуском, не удается при загрузке на более старом. Удалите новый ключ перед откатом.

Потому что вы закрепляете версию шлюза в своем собственном образе, исправления в новых выпусках Claude Code, включая исправления безопасности, достигают вашего развертывания только когда вы обновляете закрепление и переразворачиваете. Включите шлюз в тот же цикл патчей, который вы используете для других сервисов, содержащих production учетные данные.

Безопасность

Этот раздел отвечает на вопросы, которые задает проверка безопасности: какие данные проходят через шлюз и куда они идут, какие атаки защищает дизайн и какие ответы принадлежат в опроснике соответствия.

Поток данных

Данные Путь Отправлено Anthropic шлюзом
Inference (prompts, completions) CLI → шлюз → ваш upstream Только если API Anthropic — это настроенный upstream
Телеметрия (метрики OTLP, плюс опциональные логи и трассировки) CLI → шлюз → ваш сборщик Никогда
Идентификация (email, groups, sub) IdP → шлюз → JWT → CLI; CLI штампует это на экспортах OTLP. Если вы включите forward_user_identity, шлюз также отправляет email разработчика и subject IdP в качестве заголовков вашему прокси Никогда
Управляемые параметры Ваш YAML шлюза → CLI Никогда
Журнал аудита Stderr шлюза → ваш агрегатор Никогда

Краткое резюме модели угроз

Шлюз находится внутри периметра вашей сети, но отдельные ноутбуки разработчиков не рассматриваются как доверенные. Дизайн учитывает это тремя способами:

  • Разработчики держат краткосрочные JWT вместо сырых ключей upstream. Ветвь CLI-к-шлюзу использует грант устройства RFC 8628, и обмен авторизацией шлюза с IdP запускает PKCE в конфигурации по умолчанию, поэтому перехваченный код авторизации IdP бесполезен.
  • Страница проверки устройства применяет same-origin POST и ограничение скорости для каждого IP согласно RFC 8628 §5.1. См. Сопротивление brute-force пользовательского кода.
  • Исходящие запросы проходят через защиту от подделки запроса на стороне сервера (SSRF), которая разрешает DNS, блокирует link-local и адреса облачных метаданных плюс loopback по умолчанию и закрепляет соединение на разрешенный IP, поэтому управляемые оператором URL, такие как IdP и назначения OTLP, не могут быть перенаправлены на конечные точки облачных метаданных. Диапазоны приватных RFC 1918 намеренно разрешены, потому что IdP и сборщики OTLP обычно живут на приватных IP. Установите CLAUDE_GATEWAY_ALLOW_LOOPBACK=1 в окружении шлюза только когда что-то, что шлюз должен достичь, легитимно живет на loopback, такое как локальная разработка IdP или сборщик OTLP sidecar на localhost. Переменная ослабляет блокировку loopback для каждого настроенного оператором URL и также пропускает предупреждение при загрузке, которое проверяет, может ли pod достичь конечной точки облачных метаданных, поэтому предпочитайте давать сборщику его собственный внутренний адрес.

Если вы добавляете свои собственные элементы управления выходом, шлюз должен достичь сервера метаданных всякий раз, когда он использует учетные данные метаданных экземпляра, такие как workload identity.

Две угрозы выходят за рамки, потому что это ваша инфраструктура для защиты:

  • Скомпрометированный хост шлюза: хост как содержит upstream учетные данные, так и распределяет управляемые параметры каждому подключенному разработчику, поэтому контроль над конфигурацией шлюза сравним с контролем над вашим MDM. Диалог одобрения CLI для параметров, способных к shell, ограничивает молчаливые изменения, но не заменяет безопасность хоста.
  • Вредоносный поставщик OIDC: поставщик подписывает id_tokens, которым шлюз доверяет, поэтому он может утверждать любую идентификацию. Проверка и защита вашего IdP — это ваша ответственность.

Сопротивление brute-force пользовательского кода

user_code, который разработчик вводит на странице проверки /device, — это 8 символов, взятых из алфавита из 20 символов, что дает 20⁸ или около 2,56×10¹⁰ комбинаций, и он истекает через 10 минут.

Шлюз применяет ограничения скорости для каждого IP на конечных точках грантов устройства, настраиваемые через rate_limits. Поднимите лимиты, если много разработчиков входят с одного общего корпоративного NAT адреса. Лимиты применяются только к потоку входа, а не к inference.

Позиция соответствия

  • Резидентность данных: собственная плоскость данных шлюза не отправляет ничего Anthropic, если только API Anthropic не является настроенным upstream; когда это так, ваше существующее соглашение об обработке данных применяется к пути inference. Телеметрия, аудит, идентификация и параметры идут только к назначениям, которые вы настраиваете.
  • Трафик хост-процесса: хост-процесс — это Claude Code CLI. claude gateway работает под теми же правилами третьих сторон, что и развертывания Amazon Bedrock и Google Cloud's Agent Platform, и не отправляет ничего Anthropic. До v2.1.227 хост-процесс отправлял телеметрию запуска, такую как версия продукта и платформа, которую установка CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 в окружении контейнера отключала. Эти выпуски также отправляли один запрос HEAD при загрузке, без тела или учетных данных, на /api/hello на https://api.anthropic.com, или на ANTHROPIC_BASE_URL когда окружение установило его, если только окружение также не установило переменную прокси, такую как HTTPS_PROXY или сертификат клиента mTLS. Они игнорировали ответ, поэтому блокировка этого запроса на брандмауэре выхода не влияла на шлюз.
  • Аналитика клиента: CLI отключает свою собственную аналитику использования и отчеты об ошибках при входе в шлюз. До первого входа CLI все еще отправляет события запуска Anthropic, включая на машинах, чьи управляемые параметры принуждают вход в шлюз. Чтобы отключить и их, доставьте DISABLE_TELEMETRY в тех же управляемых параметрах на стороне клиента, которые принуждают вход в шлюз.
  • Отчеты об ошибках: CLI отключает отчеты об ошибках всякий раз, когда его запросы модели идут на любую конечную точку, отличную от первоклассного API Anthropic, такую как Amazon Bedrock или пользовательский ANTHROPIC_BASE_URL.
  • Машины клиентов: CLI разработчиков все еще отправляют проверки имени хоста WebFetch и проверки версии Anthropic, если не установлены CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 и skipWebFetchPreflight: true. См. использование данных.
  • Рейтинги опроса: при входе в шлюз CLI отключает загрузку рейтингов, привязанную к Anthropic, вместе с потоками аналитики, поэтому он не отправляет рейтинги Anthropic.
  • Обмен транскриптом: выбор Yes на подсказке обмена транскриптом опроса записывает локальный файл в ~/.claude/feedback-bundles/ вместо загрузки Anthropic.
  • Обновления клиента: проверки обновлений отделены от трафика шлюза. Закрепите версии через вашу собственную дистрибуцию и установите DISABLE_UPDATES, если ноутбуки не должны получать выпуски. DISABLE_AUTOUPDATER останавливает только фоновые обновления, в то время как claude update все еще работает.
  • TLS: обслуживайте public_url по HTTPS в production, либо из собственного слушателя шлюза через listen.tls, либо из TLS-завершающего ingress перед простыми HTTP репликами, с установленным listen.public_url в обоих случаях. Шлюз не отказывает простой HTTP. IdP должен обслуживать HTTPS в production, и Postgres поддерживает ?sslmode=require. Установите Strict-Transport-Security на вашем ingress.
  • Раскрытие уязвимостей: следуйте Отчету о проблемах безопасности

Устранение неполадок

Для вопросов и обратной связи используйте поддержку Claude Code или откройте issue в репозитории Claude Code на GitHub. При сообщении о проблеме включите:

  • Проблема шлюза: stderr шлюза для соответствующего окна, ваш gateway.yaml с редактированными секретами, версию шлюза, показанную на целевой странице в / и в заголовке ответа x-cc-gateway-version на /managed/settings, и что недавно изменилось
  • Проблема входа: разработчик запускает claude --debug-file ./claude-debug.txt, воспроизводит и отправляет этот файл плюс журнал аудита шлюза для того же окна
  • Проблема inference: запрошенная модель, настроенные upstreams и журнал аудита шлюза для запроса, который записывает, какой upstream обслужил его и статус ответа

stderr шлюза включает поток событий аудита, журнал аудита записывает идентификаторы разработчиков, а файл отладки записывает выходные данные hook и MCP сервера с машины разработчика. Проверьте и удалите эту информацию перед публикацией в общедоступную проблему.

Симптом Причина Исправление
/login разработчика показывает стандартный выбор аккаунта вместо экрана Cloud gateway forceLoginMethod или forceLoginGatewayUrl не установлены в управляемых параметрах на этой машине Разверните файл управляемых параметров на устройство; /login читает URL шлюза оттуда
Запросы разработчика не удаются с Not signed in to the Cloud gateway — run /login. Управляемые параметры машины устанавливают forceLoginMethod: "gateway" или forceLoginGatewayUrl, и сеанс не имеет входа в шлюз. Оставшийся вход claude.ai не удовлетворяет требованию. Попросите разработчика запустить /login и завершить вход в шлюз. См. также Administrator policy requires a Cloud gateway sign-in.
Claude Desktop сообщает, что его конфигурация bootstrap не может быть получена /user/bootstrap вернул 404: политика, соответствующая пользователю, не содержит ключ desktop, или политика не совпадает. Журнал аудита шлюза записывает каждое отклонение как desktop_bootstrap.denied с причиной. Добавьте блок desktop к политике, которая соответствует пользователю, или к базовому слою match: {}; пустого desktop: {} достаточно. См. Claude Desktop overlay.
Запуск показывает Gateway login is configured in managed settings, but this Claude Code build does not include Cloud gateway support. Установленная сборка Claude Code предшествует поддержке шлюза Попросите разработчика обновить Claude Code до выпуска, который включает поддержку Cloud gateway
Запуск или /login сообщает Claude Code may not be enabled for your organization после 403 при загрузке управляемых параметров Шлюз или что-то перед ним ответили на запрос /managed/settings с 403. Собственный маршрут параметров шлюза никогда не отвечает 403. Статус поступает из проверок IP access_control или из прокси или WAF перед шлюзом. Журнал аудита записывает отклонение проверки IP как access.denied с причиной. Разработчик остается вошедшим. Проверьте журнал аудита на access.denied в момент сбоя и исправьте списки access_control или фронтенд, затем попросите разработчика запустить claude снова
CLI /login: Gateway hosts must be on your organization's private network; <host> resolves to the public (or unrecognized) address <ip> Имя хоста шлюза разрешается на по крайней мере один публичный IP адрес. Claude Code проверяет каждый разрешенный адрес и требует, чтобы каждый был приватным. Частая причина — dual-stack имя, где одно семейство разрешается на публичный адрес, включая AWS внутренние dual-stack балансировщики нагрузки, которые возвращают публичные AAAA адреса. Попросите имя шлюза разрешаться только на приватные адреса на машинах разработчиков. Для dual-stack имени удалите публичный диапазон записи или обслуживайте отдельное внутреннее DNS имя. См. предпосылку приватной сети.
CLI /login: Gateway login would go through proxy <proxy>, which is not on a private network HTTPS_PROXY или HTTP_PROXY применяется к хосту шлюза и имя хоста прокси разрешается на публичный адрес. Прокси, чье имя хоста разрешается только на приватные адреса, разрешен и не вызывает эту ошибку Добавьте хост шлюза в NO_PROXY на машине разработчика, чтобы соединение было прямым, или используйте прокси, чье имя хоста разрешается на приватные адреса. Сообщение называет точную запись NO_PROXY для добавления
CLI /login: Could not resolve the configured HTTP proxy Имя хоста в HTTPS_PROXY или HTTP_PROXY не разрешается с машины разработчика, обычно потому что она не подключена к корпоративной сети Попросите разработчика подключиться к вашей сети или VPN и повторить попытку, или исправьте URL прокси
CLI /login: Could not resolve gateway host <host> Машина не может разрешить внутреннее DNS имя шлюза, обычно потому что она не в корпоративной сети Попросите разработчика подключиться к вашей сети или VPN, затем повторите попытку /login
Загрузка выходит с ошибкой валидации конфигурации, называющей store.postgres_url Postgres не настроен; шлюз требует Postgres Установите store.postgres_url. Для локальной разработки используйте одноразовый контейнер: docker run --rm -p 5432:5432 -e POSTGRES_HOST_AUTH_METHOD=trust postgres.
Загрузка выходит: requires the native binary Запуск под Node вместо нативного бинарного файла Установите Claude Code с одним из методов автономной установки
Загрузка выходит с ошибкой обнаружения OIDC после config.load oidc.issuer недоступен или цепь TLS не доверена Проверьте, что издатель доступен из pod и обслуживает /.well-known/openid-configuration. Установите ca_cert_pem для приватной PKI. Если pod достигает IdP только через forward proxy, установите oidc.use_proxy: true; на версиях до v2.1.227 предоставьте pod прямой маршрут к каждой конечной точке IdP вместо этого.
Загрузка выходит с ошибкой разрешения Postgres Роль базы данных не имеет прав DDL на своей схеме Предоставьте роли CREATE на схему шлюза, чтобы она могла создавать и изменять свои таблицы при загрузке
/oauth/callback показывает "Sign-in could not be completed" Домен email отклонен, валидация id_token не удалась или email_verified явно false, что шлюз всегда отклоняет без переопределения Проверьте allowed_email_domains и что IdP возвращает проверенное утверждение email. Для email_verified: false исправьте проверку на стороне IdP. Если ваш IdP выдает email под другим именем утверждения, установите oidc.email_claim.
Лог: token exchange failed request_id=<id>: id_token missing email claim IdP не включает email в id_token по умолчанию. Это отклонение срабатывает только когда установлен allowed_email_domains; без него отсутствующий email создает сеанс без email Настройте IdP для выдачи email в id_token. Okta: добавьте email к утверждениям ID-token пользовательского сервера авторизации. Entra: добавьте email как опциональное утверждение на регистрацию приложения. PingFederate: включите политику OpenID Connect, которая выдает email. Если IdP обслуживает email из конечной точки userinfo, но не будет включать его в id_token, такой как сервер авторизации организации Okta, установите oidc.userinfo_fallback: true.
Лог: refresh failed request_id=<id>: invalid_token (…) (at userinfo_no_id_token, …), и разработчики видят Cloud gateway session expired каждые session.ttl_hours IdP принял refresh token, но не вернул id_token с ним, поэтому шлюз попросил конечную точку userinfo IdP для утверждений пользователя. IdP отклонил обновленный access token там. Шлюз отвечает temporarily_unavailable, поэтому Claude Code сохраняет refresh token, но не может обновить сеанс. Версии шлюза до v2.1.260 логируют ту же строку без деталей (at …). Установите oidc.scope_on_refresh: true, доступно в шлюзе v2.1.260 или позже, чтобы запрос refresh запрашивал openid снова. Некоторые IdP, такие как Okta, возвращают id_token при refresh только при запросе. На PingFederate включите Return ID Token On Refresh Grant под Applications > OAuth > OpenID Connect Policy Management вместо этого. Ключ не изменяет поведение PingFederate. Для других IdP, которые все еще его опускают, проверьте, принимает ли конечная точка userinfo access tokens, выданные refresh. Как временное решение, поднимите session.ttl_hours. См. Identity provider setup для компромисса deprovisioning.
Каждый запрос Amazon Bedrock возвращает 502; лог показывает Could not load credentials from any providers На EC2 hop limit IMDSv2 по умолчанию 1 блокирует запрос метаданных экземпляра изнутри контейнера. Загрузка и /readyz проходят в любом случае, потому что AWS SDK разрешает учетные данные экземпляра при первом запросе, а не при построении клиента Поднимите hop limit с aws ec2 modify-instance-metadata-options --instance-id <id> --http-put-response-hop-limit 2 или установите его в шаблоне запуска. Изменение применяется к каждому контейнеру на экземпляре. Предпочитайте роли задач ECS, где доступны, которые читают учетные данные из конечной точки учетных данных контейнера ECS и избегают изменения полностью, или применяйте изменение на выделенном экземпляре шлюза, чтобы ограничить воздействие.
Ошибка IdP: unknown or unsupported scope IdP отклоняет области, которые он не распознает Установите oidc.scopes на точный список, который принимает ваш IdP; он должен включать openid. По умолчанию openid profile email offline_access.
Сеансы не молчаливо обновляются после установки oidc.scopes offline_access был удален из переопределения Добавьте offline_access обратно, если ваш IdP его поддерживает. Без refresh token разработчики повторно запускают вход в браузер каждые session.ttl_hours.
Браузер показывает "This request came from another site and was blocked" Cross-site form POST, заблокирован как защита CSRF. Ожидается для встроенных или проксированных страниц Откройте ссылку проверки напрямую
Chrome блокирует кнопку Approve с "Refused to send form data … violates … Content Security Policy directive: form-action", но та же страница работает в Safari или Firefox Chrome применяет form-action ко всей цепи перенаправления. Ваш IdP перенаправляет дальше на второй хост, который не в списке разрешений. Добавьте каждое дополнительное происхождение в цепи перенаправления в oidc.form_action_origins. Откройте Chrome DevTools → Console на странице Approve, чтобы увидеть, какое происхождение было заблокировано.
Вход завершается в IdP, но callback не удается, с ошибкой CSP в Chrome или "this sign-in link has expired" в Safari IdP вернул код через response_mode=form_post, который автоматически отправляет его cross-origin через POST на /oauth/callback. Chrome блокирует это под строгой CSP; Safari позволяет отправку, но callback читает только строку запроса. Убедитесь, что ваш IdP соблюдает response_mode=query, который шлюз явно запрашивает, чтобы callback был простым перенаправлением
Вход работает локально, но не удается за ALB public_url все еще называет локальное или внутреннее происхождение http://, поэтому IdP получает неправильный redirect_uri Установите listen.public_url на внешнее происхождение https:// и зарегистрируйте <public_url>/oauth/callback с IdP
Разработчик видит подсказку доверия повторно Сертификат TLS ротируется для каждой реплики или для каждого запроса Используйте стабильный сертификат на ingress или завершите TLS один раз и запустите реплики по простому HTTP внутри
CLI /login: "Could not verify the gateway's TLS certificate" или SELF_SIGNED_CERT_IN_CHAIN Цепь TLS шлюза подписана приватным CA, не в хранилище доверия хоста CLI Claude Code читает хранилище доверия ОС по умолчанию на нативном бинарном файле и на Node 22.15 или позже; CLAUDE_CODE_CERT_STORE управляет этим поведением. Если CA установлен в хранилище доверия ОС, убедитесь, что разработчики используют текущий runtime. В противном случае установите NODE_EXTRA_CA_CERTS на сертификат CA PEM перед запуском. Подсказка отпечатка первого подключения все еще применяется.
CLI /login завершает вход в браузер, затем сеанс заканчивается с Cloud gateway sign-in was not completed и несоответствием сертификата TLS При первом запросе после входа шлюз представил сертификат, который не соответствует отпечатку, который Claude Code закрепил, поэтому Claude Code не сохранил учетные данные шлюза. Обычные причины — реплики за одним адресом, которые обслуживают разные сертификаты, или что-то на пути сети, которое перехватывает TLS. Обслуживайте один сертификат для имени хоста, например завершив TLS один раз на ingress, затем попросите разработчика запустить /login снова. Если этот сертификат отличается от закрепленного, Claude Code показывает подсказку доверия снова с предупреждением, что сертификат изменился.
CLI /login останавливается с The gateway's TLS certificate changed during sign-in: it no longer matches the one you trusted Запрос входа достиг сервера, чей сертификат не соответствует тому, который разработчик принял, когда /login начался: реплики за одним адресом, обслуживающие разные сертификаты, перехват TLS на пути или ротация сертификата во время входа. Обслуживайте один сертификат для имени хоста, затем попросите разработчика начать вход снова и проверить новый сертификат на подсказке доверия.

Сообщение Cloud gateway sign-in was not completed называет имя хоста шлюза. Когда Claude Code имеет оба отпечатка, сообщение также показывает первые 16 символов каждого.

Если Claude Code сообщает couldn't load your organization's managed settings после входа в шлюз, Claude Code называет причину, перезагружается на месте и возобновляет разговор. Если Claude Code не может перезагрузиться, например в фоновом сеансе, Claude Code завершает сеанс и сохраняет вход.