Архитектура
Пример архитектуры с Amazon Bedrock в качестве upstream модели. Upstream Claude Platform on AWS занимает ту же позицию.
- Сервис Amazon ECS на AWS Fargate или Amazon EKS Deployment, запускающий контейнер gateway
- Репозиторий Amazon ECR для образа gateway
- Экземпляр Amazon RDS для PostgreSQL в приватных подсетях, не доступный публично, для хранилища gateway
- Секреты AWS Secrets Manager для ключа подписи JWT, секрета клиента OIDC и URL Postgres
- IAM-роль с
bedrock:InvokeModel,bedrock:InvokeModelWithResponseStreamиbedrock:CountTokens, присоединённая как роль задачи ECS или привязанная через IAM Roles for Service Accounts (IRSA) на EKS - Внутренний Application Load Balancer для HTTPS
Предварительные требования
Пошаговое руководство создаёт собственные ресурсы gateway, но строится на сетевой и инфраструктуре идентификации, которая у вас уже есть. Прежде чем начать, вам нужно:- Учётная запись AWS с разрешением на создание ресурсов выше
- AWS CLI v2 установлен и аутентифицирован, а также Docker установлен локально
- VPC с минимум двумя приватными подсетями в разных Availability Zones с исходящим доступом в интернет через NAT gateway; внутреннему load balancer нужны подсети в двух AZ, а gateway нужен исходящий доступ к Bedrock и вашему IdP
- Веб-приложение Okta OIDC с URI перенаправления
https://<gateway-host>/oauth/callback; см. Настройка поставщика идентификации - TLS имя хоста для gateway, обычно внутреннее имя DNS в приватной зоне Route 53, указывающее на load balancer, с сертификатом ACM для этого имени, импортированным или выданным AWS Private CA
Установите переменные окружения
Каждая команда на этой странице читает четыре значения из вашей оболочки:AWS_REGION, ACCOUNT_ID, VPC_ID и PRIVATE_SUBNETS.
Выберите регион США, где Bedrock обслуживает нужные вам модели Claude. Пошаговое руководство полагается на встроенный каталог моделей gateway, который разрешается в профили вывода us.anthropic.*, и политика IAM предоставляет эти ARN. В регионе, отличном от США, добавьте models: блок с ID профилей вывода этого региона и измените префикс ARN в политике IAM, чтобы он совпадал.
Если у вас нет ID VPC под рукой, перечислите ваши VPC с помощью aws ec2 describe-vpcs, затем перечислите подсети этого VPC, чтобы найти две приватные в разных Availability Zones:
Развёртывание gateway
Шаги ниже предусматривают полное развёртывание с командамиaws.
Создайте группы безопасности
- На ECS Fargate шаг развёртывания присоединяет
$ALB_SGк load balancer и$GW_SGк сервису. - На EKS AWS Load Balancer Controller создаёт свою собственную группу безопасности фронтенда для ALB, поэтому
$ALB_SGи$GW_SGне используются: аннотацияinbound-cidrsшага развёртывания ограничивает слушатель вашей корпоративной сетью, а группа безопасности базы данных допускает группу безопасности кластера вместо$GW_SG.
Создайте IAM-роли и отправьте форму использования
gateway-*, который в общей учётной записи также совпадал бы с несвязанными секретами; конечный -?????? совпадает ровно с случайным суффиксом из шести символов, который Secrets Manager добавляет к ARN каждого секрета. Конечный -* был бы простым глобом префикса и также совпадал бы с более длинными именами, такими как gateway-postgres-url-prod.Политика IAM предоставляет gateway разрешение на вызов Bedrock, и Bedrock включает доступ к модели по умолчанию в коммерческих регионах. Оставшиеся ворота на уровне учётной записи — это одноразовая форма использования Anthropic: если никто в вашей учётной записи её не отправил, откройте консоль Amazon Bedrock, выберите модель Anthropic из каталога моделей и заполните форму. Доступ предоставляется сразу после отправки; см. Claude Code на Amazon Bedrock для формы AWS Organizations и разрешений IAM, которые нужны отправителю.Трек EKS повторно использует оба документа политики на роли IRSA вместо двух ролей ECS; см. шаг развёртывания.Подготовьте Amazon RDS для PostgreSQL
rds.force_ssl=1, чтобы сервер отклонял открытые соединения. Версия движка закреплена один раз, потому что семейство группы параметров должно совпадать с основной версией движка, которую запускает экземпляр:--master-user-password виден в таблице процессов и в журналах аудита/EDR во время выполнения команды, то же самое воздействие, которое охватывает примечание шага секретов. На общем или контролируемом хосте передайте пароль через --cli-input-json из файла 0600 вместо этого, так же как это делает setup.sh пакета.Дождитесь, пока экземпляр запустится, что может занять несколько минут, затем прочитайте его приватный эндпоинт и соберите строку подключения, которую будет использовать gateway:sslmode=verify-full заставляет gateway проверять цепь сертификата сервера RDS и имя хоста, а не только шифровать. Якорь доверия — это пакет сертификатов AWS RDS, который шаг сборки образа ниже копирует в /etc/claude/rds-global-bundle.pem и доверяет через NODE_EXTRA_CA_CERTS. Не добавляйте параметр sslrootcert= в стиле libpq к URL: драйвер gateway читает только sslmode из строки запроса и передал бы sslrootcert Postgres как параметр запуска, который сервер отклоняет.Сервис ECS или поды EKS должны работать в этом VPC, чтобы они могли достичь приватного эндпоинта экземпляра, и группа безопасности claude-gateway-db допускает только группу безопасности gateway.Напишите gateway.yaml
upstreams указывает на Bedrock с auth: {}, поэтому gateway аутентифицируется через цепь учётных данных AWS по умолчанию из роли задачи на ECS или роли IRSA на EKS. См. справочник конфигурации для каждого поля.Два поля listen описывают, что находится перед gateway:public_url: внешний источникhttps://, требуется для любого привязывания, отличного от loopback; см. справочникlisten. Gateway строитredirect_uriIdP и его документ обнаружения только из этого значения, никогда из заголовковX-Forwarded-*.trusted_proxies: диапазоны источников фронтенда. Gateway соблюдаетX-Forwarded-Forтолько когда TCP-пир находится в этом списке, затем проходит цепь мимо доверенных переходов, поэтому ограничения частоты запросов на вход по IP и события аудита записывают IP разработчиков вместо load balancer.
trusted_proxies на CIDR этих подсетей. Это доверяет каждому хосту в этих подсетях как прокси. Не допускайте, чтобы источник входа ALB, ваша корпоративная CIDR, перекрывался с ними, и не делитесь подсетями с ненадёжными рабочими нагрузками, которые могли бы подделать IP клиентов через X-Forwarded-For.Атрибут сохранения клиентского порта ALB, routing.http.xff_client_port.enabled, может остаться в любой настройке: с ним включённым, ALB записывает клиента как 203.0.113.7:54321 или [2001:db8::1]:54321, и gateway читает оба с опущенным портом.oidc специфичен для Okta. Чтобы использовать Microsoft Entra ID вместо этого, установите issuer на https://login.microsoftonline.com/<tenant-id>/v2.0, удалите userinfo_fallback и scope groups, и обратите внимание, что Entra выдаёт Object ID группы, а не имена, поэтому managed.policies должны совпадать на GUID, или на App Roles с oidc.groups_claim: roles. См. Настройка поставщика идентификации.Сохраните секреты в AWS Secrets Manager
--secret-string видны в таблице процессов и в журналах аудита/EDR во время выполнения каждой команды. На общем или контролируемом хосте поместите значение в файл 0600 и передайте --secret-string file://<path> вместо этого. setup.sh пакета держит значения секретов вне argv процесса так же, передавая временные файлы 0600 в --cli-input-json.gateway.yaml не содержит значений секретов, потому что все учётные данные разрешаются при загрузке через ${VAR} или ${file:...} расширение. Как всё достигает контейнера, отличается по треку:- На ECS, сборка следующего шага копирует
gateway.yamlв образ в/etc/claude/gateway.yaml, и определение задачи внедряет три секрета как переменные окружения через его полеsecrets, поэтому YAML ссылается на${GATEWAY_JWT_SECRET},${OIDC_CLIENT_SECRET}и${GATEWAY_POSTGRES_URL}. - На EKS, смонтируйте
gateway.yamlиз ConfigMap и секреты как файлы в/secrets, на которые ссылаются как${file:/secrets/...}. Получите Kubernetes Secrets из Secrets Manager с External Secrets Operator или поставщиком AWS драйвера Secrets Store CSI, или создайте их напрямую с помощьюkubectl.
Соберите и отправьте образ в Amazon ECR
linux-x64 glibc в ./claude в контексте сборки. Напишите свой собственный Dockerfile согласно этим требованиям или начните с Dockerfile пакета, который копирует заполненный gateway.yaml из предыдущих шагов в образ в /etc/claude/gateway.yaml. На ECS эта встроенная копия — это то, как конфигурация достигает контейнера, поэтому сборка идёт после написания файла. Трек EKS вместо этого монтирует gateway.yaml из ConfigMap при развёртывании, поэтому встроенная копия там не используется.Образ также содержит пакет сертификатов AWS RDS как якорь доверия для sslmode=verify-full строки подключения, поэтому загрузите его в контекст сборки сначала. AWS ротирует пакет (новые региональные CA добавляются), поэтому загружайте его при каждой сборке, а не закрепляйте контрольную сумму или фиксируйте его:Dockerfile пакета уже включает обе:<version>, который закрепляет шаг развёртывания, не может позже молча переуказываться на другой образ:linux/amd64, поэтому платформа должна совпадать здесь; для Fargate на ARM64 (Graviton), соберите linux/arm64 с двоичным файлом linux-arm64 и установите cpuArchitecture на ARM64 вместо этого:Развёртывание
- ECS Fargate
- EKS
--ip-address-type ipv4 имеет значение: внутренний двойной стек ALB публикует записи AAAA общественного диапазона, которые проверка приватной сети /login отклоняет:--ssl-policy закрепляет современный минимум TLS, так как его опущение возвращается к устаревшему значению по умолчанию ELBSecurityPolicy-2016-08, которое всё ещё принимает TLS 1.0/1.1.ALB закрывает соединение после 60 секунд без данных по умолчанию. Keepalive пинги gateway держат потоки внутри этого значения по умолчанию, поэтому повышение таймаута добавляет запас выше частоты пингов; строка Устранение неполадок о разорванных потоках охватывает механизм и более старые gateway. Команды ниже добавляют слушатель и повышают таймаут:GET /readyz проверяет, что хранилище доступно, поэтому задача, которая не может достичь Postgres, никогда не входит в ротацию. Чтобы держать задачи проходящими проверку через короткий сбой базы данных, такой как отказ RDS, установите store.readiness_grace_seconds, как описано в Поведение при сбое, которое также охватывает альтернативу /healthz.Задачи работают в приватных подсетях без публичного IP, поэтому весь исходящий трафик (в Bedrock, ваш IdP, Secrets Manager, ECR и CloudWatch Logs) проходит через NAT gateway. Чтобы держать трафик Bedrock вне публичного пути, создайте интерфейсный эндпоинт VPC bedrock-runtime и укажите base_url upstream на него, как показано в справочнике upstream Bedrock; IdP всё ещё нуждается в исходящем доступе в интернет.Завершите, дав разработчикам приватно разрешаемое имя хоста: в приватной зоне Route 53 создайте псевдоним внутреннего имени DNS gateway на ALB и установите listen.public_url на это имя хоста. Собственное имя *.elb.amazonaws.com ALB разрешается на приватные адреса на внутреннем ALB, но оно не может нести ваш сертификат ACM, поэтому используйте своё имя.Обновите URI перенаправления авторизованного клиента OAuth на <public_url>/oauth/callback перед первым входом. После изменения public_url, пересоберите и отправьте образ под новым тегом, зарегистрируйте новую редакцию определения задачи и переразвёртывайте. На ECS настройка живёт во встроенном gateway.yaml образа, и gateway строит свой публичный источник только из этой настройки, игнорируя X-Forwarded-Host и X-Forwarded-Proto. X-Forwarded-For соблюдается для IP клиентов только когда установлен listen.trusted_proxies.Отправьте URL gateway на машины разработчиков
/login до тех пор, пока URL gateway не будет на их машинах. Разверните полный фрагмент управляемых настроек с forceLoginMethod, forceLoginGatewayUrl и явным включением parentSettingsBehavior: "merge" на каждом устройстве через MDM. Нет опции gateway в средстве выбора входа для разработчика, чтобы выбрать вручную.Справочник Terraform
Сопутствующий пакет вexamples/gateway/aws упаковывает эту страницу как код:
setup.shскриптирует пошаговое руководство по подготовке выше с теми же командамиaws, на треке ECS Fargate. Это идемпотентно: существующие ресурсы обнаруживаются и пропускаются, поэтому повторный запуск безопасен, и любое значение по умолчанию может быть переопределено через переменную окружения. Вы всё ещё создаёте секрет клиента Okta OIDC и сертификат ACM сами: запуск без них пропускает развёртывание ECS/ALB, называет отсутствующие входы и печатает командуcreate-secret; создайте оба и переразвёртывайте. Форма использования Bedrock и псевдоним Route 53 печатаются как следующие шаги, а не запускаются автоматически, и push MDM клиента остаётся ручным шагом с этой страницы.gateway.yaml.example— это шаблон конфигурации из шага gateway.yaml, с дополнительными ключами, включёнными в комментарии. Скопируйте его вgateway.yamlи замените каждыйREPLACE_MEперед сборкой.Dockerfileсобирает образ среды выполнения из предварительно собранного двоичного файлаlinux-x64и копирует ваш заполненныйgateway.yamlв/etc/claude/gateway.yaml, плюс пакет сертификатов AWS RDS, который якорируетsslmode=verify-fullхранилища.setup.shзагружает пакет только когда его ещё нет в контексте сборки; удалите файл и пересоберите под новым тегом, чтобы подобрать ротацию AWS CA. Файл конфигурации не содержит значений секретов, так как каждое учётное данные разрешается при загрузке через расширение${VAR}. Редактирование конфигурации, следовательно, означает пересборку под новым тегом;setup.shавтоматизирует это, помечая образы хешем файла.terraform/предусматривает ту же область ECS Fargate декларативно: группы безопасности, роли IAM, репозиторий ECR, экземпляр RDS, секреты Secrets Manager и сервис ECS за внутренним ALB. VPC и приватные подсети остаются предварительными условиями, переданными как переменные. Terraform создаёт репозиторий ECR, но не собирает образ, и определение сервиса ссылается на образ, поэтому применение — это два прохода: целевое применение для репозитория, затем сборка и отправка, затем полное применение.terraform/README.mdпакета охватывает переменные, удалённое состояние и разборку.
Troubleshooting
Для ошибок загрузки gateway и входа см. независимую от платформы таблицу troubleshooting. Записи ниже специфичны для AWS.Телеметрия
Шлюз предоставляет вам метрики использования для каждого разработчика без какой-либо конфигурации OTEL для каждой машины. Claude Code выдает метрики OpenTelemetry (OTLP), логи и трассировки с согласия пользователя; Мониторинг использования охватывает всё, что сообщает CLI. В сессиях, вошедших через/login, CLI помечает каждый экспорт аутентифицированными атрибутами идентификации IdP user.id, user.email и user.groups, поэтому использование суммируется для каждого разработчика.
Сам шлюз является аутентифицированным реле OTLP. Установите telemetry.forward_to вместе с listen.public_url, и он отправляет параметры экспортера OTEL каждому подключённому клиенту и пересылает их трафик OTLP дословно каждому указанному вами месту назначения. Каждое место назначения независимо выбирает метрики, логи и трассировки, а по умолчанию используются только метрики; см. справочник telemetry для полей для каждого сигнала и их компромиссов по чувствительности. Шлюз не буферизирует, не агрегирует и не хранит телеметрию, поэтому место, где приземляются данные, полностью зависит от конфигурации экспортера сборщика.
Телеметрия клиента отключена по умолчанию; конфигурирование telemetry.forward_to — это то, что включает её для подключённых разработчиков, и каждый интерактивный клиент показывает диалог одобрения безопасности для отправленных параметров, как описано в справочнике конфигурации. На AWS каждый сигнал отображается на место назначения следующим образом.
Метрики, логи и трассировки клиента
Направьтеtelemetry.forward_to на сборщик OpenTelemetry, такой как AWS Distro for OpenTelemetry (ADOT) collector, и экспортируйте оттуда в Amazon CloudWatch, Amazon Managed Service for Prometheus или любой бэкенд OTLP.
Запустите сборщик как собственный внутренний сервис, доступный через https://; справочник telemetry охватывает исключение обратного цикла и CLAUDE_GATEWAY_ALLOW_LOOPBACK.
Логи шлюза
На ECS Fargate дополнительная настройка не требуется: драйверawslogs доставляет stderr шлюза, который содержит его события аудита и операционные логи, в группу логов /ecs/claude-gateway, созданную выше. На EKS логи подов по умолчанию не попадают в CloudWatch, поэтому журнал аудита теряется до тех пор, пока вы не установите сбор логов: надстройка Amazon CloudWatch Observability с включённым захватом логов контейнера или DaemonSet Fluent Bit. В любом случае запрашивайте логи с помощью CloudWatch Logs Insights и управляйте сигналами тревоги из фильтров метрик.
Метрики контейнера
Включите Container Insights на кластере с помощьюaws ecs update-cluster-settings --cluster claude-gateway --settings name=containerInsights,value=enabled для CPU, памяти и сети для каждой задачи. На EKS установите надстройку Amazon CloudWatch Observability.
Расходы
Телеметрия показывает использование постфактум; лимиты расходов — это живое представление и принудительное применение шлюза для каждого разработчика.Атрибуция затрат
Шлюз подписывает каждый запрос Bedrock своим собственным принципалом, ролью задачи ECS или ролью IRSA EKS, поэтому по умолчанию AWS видит все эти расходы под одним принципалом IAM. Есть два способа разделить это в собственных данных выставления счетов AWS, и они комбинируются.Per developer с assume_role
Создайте вторую роль IAM, которая содержит разрешения Bedrock и доверяет принципалу шлюза, предоставьте этому принципалу sts:AssumeRole на ней и установите assume_role с session_name: email на восходящем потоке Bedrock. Шлюз затем принимает эту роль один раз в час на разработчика с именем сеанса, установленным на их адрес электронной почты, и подписывает их запросы результатом. Требуется шлюз, работающий на Claude Code v2.1.281 или позже. Роль также может находиться в другой учетной записи AWS: см. Bedrock в другой учетной записи AWS. В Terraform, рядом с ролью задачи в пакете Terraform:
assume_role, шлюз подписывает каждый вызов Bedrock, включая бесплатный вызов CountTokens для измерения расходов, учетными данными предполагаемой роли, поэтому принципалу шлюза требуется собственная политика Bedrock только для восходящего потока без assume_role.
Поскольку шлюз вызывает STS во время запроса, приватные подсети должны иметь путь к sts.<region>.amazonaws.com. NAT-шлюз из предварительных условий предоставляет один, как и конечная точка VPC интерфейса STS, которая отвечает на этот хост-имя. Каждый активный разработчик стоит один вызов STS в час на реплику шлюза.
Запросы каждого разработчика достигают AWS как принципал arn:aws:sts::<account>:assumed-role/<role>/<email>. Чтобы увидеть расходы на принципала, используйте экспорт выставления счетов, который включает данные принципала IAM; страница AWS IAM principal cost allocation охватывает, как это включить и какие инструменты выставления счетов это показывают.
Per team с application inference profiles
Этот маршрут использует только разделыmodels и managed. Создайте один Bedrock application inference profile на команду и модель, пометьте каждый профиль командой и активируйте эту метку как метку распределения затрат. Затем дайте каждой команде свой идентификатор модели в gateway.yaml и привяжите каждую группу IdP к идентификаторам своей команды:
--model platform-claude-opus-4-8, используя идентификатор своей команды, потому что сеанс, запущенный без него, запускает модель по умолчанию, которую шлюз отказывает для них.
Шлюз применяет availableModels на каждый запрос, не только в средстве выбора модели, и AWS группирует расходы по метке, которую вы активировали. Без catch-all match: {}, разработчик, который не соответствует никакой политике, получает каждую модель в каталоге и может выставить счет за профиль любой команды.
Затраты:
- Конфигурация растёт пропорционально количеству команд, умноженному на количество моделей
- Роль, которая подписывает запросы Bedrock этого восходящего потока, также должна иметь разрешение вызывать ARN
application-inference-profile/*. Эта роль является принципалом шлюза, или сassume_roleроль, которую он принимает.
Позвольте разработчику выбирать, на какую команду относить расходы
Чтобы разработчик, работающий на две команды, мог выбирать, на какую команду относятся расходы каждой сессии, создайте для этой пары команд отдельную группу IdP и отдельную политику.Добавьте группу для пары
team-platform-and-data. Если он уже вошёл в систему, попросите его снова выполнить /login или дождитесь следующего тихого обновления, чтобы шлюз увидел новую группу.Разместите её политику первой
Запускайте каждую сессию с идентификатором команды
claude --model data-claude-opus-4-8.team-platform. Его сессии с идентификатором команды data завершаются ошибкой is not in your role's availableModels allowlist, в которой указана модель Claude Code по умолчанию, а не введённый им идентификатор. Если вместо этого перечислить обе группы команд в groups одной политики, любой участник любой из команд сможет относить расходы на профиль любой команды.
В собственных лимитах расходов шлюза у разработчика есть одна общая сумма и один лимит на период, по умолчанию наименьший из лимитов его групп, независимо от того, какой идентификатор использует сессия. Чтобы более низкий лимит одной команды не останавливал работу для другой, задайте для разработчика индивидуальный лимит.
Следующие шаги
- Справочник конфигурации: каждая опция
gateway.yaml, включаяmanaged.policiesиtelemetry - Развёртывание и операции: настройка IdP, проверки здоровья, ротация секрета JWT, обновления и модель безопасности
- Обзор Claude apps gateway: быстрый старт и подключение разработчиков
- Примеры AWS для Claude apps gateway: примеры развёртывания, поддерживаемые AWS, охватывающие диапазон сред клиентов