Claude Platform Docs
Управляемые агентыКорпоративная конфигурация

Идентификация агентов и учётные данные

Настройте самостоятельно размещённый сервер Claude Managed Agents так, чтобы он подписывал краткосрочный токен с именем каждого агента, храните учётные данные хранилища в своём менеджере секретов и не допускайте секреты в песочницы с помощью шлюза исходящего трафика.

На этой странице показано, как позволить системам за пределами вашего сервера доверять агенту и где хранить учётные данные, которые используют ваши агенты:

  • Идентификация агентов: позвольте серверу или шлюзу MCP предоставлять каждому агенту собственный доступ. Сервер подписывает краткосрочный токен с именем агента.
  • Менеджер секретов: сервер хранит учётные данные хранилища в AWS Secrets Manager, Google Cloud Secret Manager, HashiCorp Vault или Azure Key Vault.
  • Учётные данные в переменных окружения: позвольте командам агента обращаться к сервису, в то время как песочница содержит лишь заполнитель. Шлюз исходящего трафика подставляет реальное значение в запросы агента.

Идентификация агентов

Ваш сервер может подписывать краткосрочный JSON Web Token (JWT), который указывает агента, и отправлять его вместе с вызовами MCP этого агента. Получатель — сервер или шлюз MCP — проверяет токен по открытым ключам, которые вы публикуете, и затем может предоставить каждому агенту собственный доступ.

Настройка издателя

  1. Выберите URL издателя. На шаге 3 вы публикуете по этому URL свои открытые ключи, а получатели загружают их с него. Подойдёт статический веб-хостинг. Не используйте адрес вашего сервера, потому что сервер не отдаёт ключи по путям, которые запрашивают получатели. Используйте URL https:// без пути и завершающей косой черты, на имени хоста, которое вы сможете сохранить за собой.

  2. Создайте ключ подписи. Выполните эти команды в верхнем каталоге распакованного архива:

    mkdir -m 700 agent-identity
    openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out agent-identity/signing-key.pem
  3. Опубликуйте открытые ключи. Эта команда записывает их в issuer-files/.well-known/. Разместите issuer-files в корне имени хоста издателя с типом содержимого application/json.

    CMA_AGENT_IDENTITY__ISSUER=https://agents.example.com \
    CMA_AGENT_IDENTITY__KEY_FILE=./agent-identity/signing-key.pem \
      ./cma-server export-issuer -out issuer-files
  4. Передайте серверу ключ.

    1. Если в архиве есть каталог compose, переместите в него каталог ключа: mv agent-identity compose/agent-identity.
    2. В docker-compose.yml удалите строку volumes: *server_mounts сервиса cma-server и раскомментируйте блок volumes: под ней. Если вы изменили список x-server-mounts, внесите то же изменение в этот блок, потому что сервис cma-server больше не читает этот список.
    3. В каталоге, где находится agent-identity, выполните sudo chown -R root:root agent-identity, если только вы не используете Docker Desktop на macOS или rootless Docker.
  5. Измените файл настроек. Укажите имя хоста получателя в mcp.allowed_hostnames и добавьте этот раздел:

    agent_identity:
      issuer: https://agents.example.com
      key_file: /run/cma-server/agent-identity/signing-key.pem
      direct:
        audiences:
          - audience: https://mcp-gateway.example.com
            urls:
              - https://mcp-gateway.example.com

    Каждый audience указывает одного получателя в виде URL https://. Его urls — это префиксы URL серверов MCP, которые могут получать токен для него.

  6. Перезапустите сервер. В стеке Compose вместо перезапуска выполните docker compose up -d из каталога Compose-файла.

Чтобы не хранить закрытый ключ в файлах, используйте key_secret (ваш менеджер секретов) или kms_key (AWS KMS или Google Cloud KMS). Обе настройки описаны в справочнике по конфигурации.

Отправка токена на сервер MCP

В разделе коннектор MCP описаны поля записи сервера MCP агента. Добавьте в эту запись поле auth:

mcp_servers:
  - type: url
    name: tickets
    url: https://mcp-gateway.example.com/tickets
    auth:
      type: agent_token
      audience: https://mcp-gateway.example.com

Для каждого получения списка инструментов или вызова инструмента ваш сервер подписывает новый токен. Он отправляет токен как Authorization: Bearer <token> вместо учётных данных из хранилища. Ни модель, ни воркер его не получают.

Чтобы отправить и токен, и учётные данные хранилища, замените поле auth полем agent_token_header:

mcp_servers:
  - type: url
    name: tickets
    url: https://mcp-gateway.example.com/tickets
    agent_token_header:
      audience: https://mcp-gateway.example.com

Учётные данные хранилища передаются в заголовке Authorization, как и для записи без обоих этих полей. Токен передаётся в заголовке Agent-Identity-Token без префикса Bearer.

В SDK нет полей auth и agent_token_header. В коде SDK добавляйте поле в запись сервера MCP как дополнительное поле или отправляйте запрос как обычный JSON.

На этих страницах показано, как отправлять дополнительные поля:

Python SDK · TypeScript SDK · Go SDK · Java SDK · PHP SDK · Ruby SDK

На некоторых из этих страниц дополнительные поля показаны только на верхнем уровне запроса, а не внутри записи списка. В этом случае сделайте дополнительным полем сам mcp_servers. Отправляйте так весь список, указав auth или agent_token_header в его записи.

Чтобы прекратить выдачу токенов агенту, удалите запись из агента или архивируйте агента. Уже отправленный токен остаётся действительным до своего exp — по умолчанию не более 5 минут.

Что проверяет получатель

Получатель должен принимать запрос только при выполнении всех следующих условий:

  • Подпись проверяется ключом из вашего набора ключей <issuer>/.well-known/jwks.json. Нужный ключ — тот, идентификатор которого совпадает с kid в заголовке токена. Для ключа RSA алгоритм — RS256.
  • iss равен URL вашего издателя, а aud равен audience получателя.
  • exp находится в будущем, а iat не находится в будущем.
  • typ в заголовке токена равен agent+jwt, а token_use равен agent.

Затем применяйте следующие правила:

  • Стройте правила доступа для каждого агента на основе утверждения agent_id — идентификатора агента в API.
  • Принимайте повторяющийся jti, потому что одно получение списка или вызов может включать несколько запросов с одним и тем же токеном.
  • Шлюз должен вызывать каждый инструмент с собственными учётными данными и никогда не передавать токен дальше.

При использовании единого входа токен вызова инструмента также указывает вызывающую сторону, создавшую сессию, в утверждениях actor_sub и actor_iss. actor_sub не означает, что вызывающая сторона одобрила вызов. Каждый вызов выбирает модель.

Эти токены не имеют actor_sub:

  • Токен получения списка инструментов
  • Токен вызова субагента
  • Все токены сессии, созданной с помощью ключа API сервера

Если правило зависит от вызывающей стороны, отклоняйте вызов инструмента, у которого нет actor_sub.

Проверка шлюза MCP

Команда check-gateway отправляет шлюзу MCP действительные и недействительные токены. Передайте команде отдельный файл настроек, здесь check-gateway.yaml:

  1. Скопируйте в файл только разделы mcp и agent_identity настроек сервера, а также limits.mcp_call_timeout, если сервер его задаёт.
  2. В копии измените key_file на путь к ключу на машине, где вы запускаете команду, например ./agent-identity/signing-key.pem. Если вы переместили каталог в compose, это ./compose/agent-identity/signing-key.pem.

Для -agent укажите идентификатор агента, которому шлюз разрешает доступ. Если ключ принадлежит root, используйте sudo.

./cma-server check-gateway -config check-gateway.yaml -agent agent_011CYm1BLqPXpQRk5khsSXrs \
  -url https://mcp-gateway.example.com/tickets

Команда выводит по одной строке на каждый отправленный запрос вместе с ответом шлюза. Затем успешный запуск выводит строку, начинающуюся с check-gateway: PASS, и завершается с кодом 0. Неудачный запуск сообщает, что пошло не так, в строке, начинающейся с check-gateway:, и завершается с кодом 1.

Менеджер секретов

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

Добавьте блок для вашего менеджера секретов в файл настроек:

secret_store:
  type: aws_secrets_manager
  region: us-east-1
  prefix: cma-server/prod/

Предоставление доступа

Выделите серверу одно удостоверение и ограничьте его префиксом. В каталоге iam/ архива есть файл для каждого менеджера секретов:

  • AWS Secrets Manager: замените заполнители в aws-secrets-manager-policy.json и прикрепите политику к удостоверению, от имени которого работает сервер.
  • Google Cloud Secret Manager: выполните команды из комментариев в gcp-secret-manager-role.yaml.
  • Azure Key Vault: роль Azure охватывает всё хранилище ключей, а не префикс. Поэтому выделите развёртыванию собственное хранилище ключей, использующее управление доступом на основе ролей Azure. Замените SUBSCRIPTION_ID в azure-key-vault-role.json и создайте на его основе пользовательскую роль. Назначьте эту роль в хранилище ключей удостоверению, от имени которого работает сервер.
  • HashiCorp Vault: замените заполнители в hashicorp-vault-policy.hcl и прикрепите политику к удостоверению, от имени которого работает сервер.

В AWS и Google Cloud сервер проходит аутентификацию так же, как для инференса. В Azure Key Vault он проходит аутентификацию через Microsoft Entra ID, так же как для Microsoft Foundry.

Проверка настройки

Запускайте validate-store перед первым запуском и после любого изменения политики. Команда создаёт, читает и удаляет тестовый секрет под префиксом, не запуская сервер. Выполняйте команду там, где работает сервер, с окружением сервера:

  • Docker Compose: выполните её в контейнере сервера. На Arm замените в этой команде linux_amd64 на linux_arm64:

    docker compose exec cma-server /opt/cma-server/bin/linux_amd64/cma-server validate-store -config /etc/cma-server/config.yaml
  • На хосте:

    ./cma-server validate-store -config /etc/cma-server/config.yaml
  • Kubernetes: выполните ту же команду как Job от имени сервисной учётной записи сервера.

Успешный запуск завершается строкой pass и кодом выхода 0.

При использовании Azure Key Vault выполните эту проверку для своего хранилища ключей, прежде чем полагаться на него.

Ограничения менеджера секретов

  • Выберите настройки один раз. После любого из этих изменений сервер перестанет находить секреты, которые он записал до изменения:

    • Вы удаляете раздел secret_store.
    • Вы изменяете type, prefix, region, project, vault_url, mount или namespace. Последние два — необязательные настройки HashiCorp Vault.
    • Вы направляете address на другой Vault.

    Сервер снова найдёт эти секреты, только когда вы восстановите старые значения.

  • Одно удостоверение читает весь префикс. Если две группы не должны иметь доступа к учётным данным друг друга, выделите каждой группе собственное развёртывание. Каждому развёртыванию нужен собственный префикс или хранилище ключей и собственное удостоверение.

Учётные данные в переменных окружения

С помощью учётных данных в переменной окружения команды агента могут обращаться к сервису, в то время как песочница содержит лишь заполнитель вместо секрета. «Egress gateway» (шлюз исходящего трафика) подставляет реальное значение в запросы к хостам, перечисленным в учётных данных.

Шлюз, cma-egress, — это прокси из архива релиза, который находится между вашими песочницами и интернетом. По умолчанию он выключен, и ваш сервер принимает такие учётные данные, только если шлюз включён.

При включённом шлюзе к вашим песочницам применяются два ограничения:

  • Песочницы выходят в интернет только через шлюз.
  • Шлюз подключается только к хостам, перечисленным вами в настройке сервера egress.allowed_hostnames.

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

Если вы собрали собственный образ песочницы, запускайте воркер через cma-with-egress, как показано в разделе Сборка собственного образа песочницы.

Включение шлюза в стеке Compose

В каталоге, где находится docker-compose.yml, добавьте в .env две строки. Первая перечисляет хосты, к которым подключается шлюз, через запятую. Вторая загружает Compose-файл шлюза. Затем запустите стек:

echo 'CMA_EGRESS__ALLOWED_HOSTNAMES=api.github.com' >> .env
echo 'COMPOSE_FILE=docker-compose.yml:docker-compose.egress.yml' >> .env
docker compose up --build -d

Если вы используете ещё один Compose-файл, добавьте его в строку COMPOSE_FILE. Переменная COMPOSE_FILE в вашей оболочке переопределяет переменную в .env, поэтому сбросьте переменную оболочки.

Файл шлюза задаёт остальные настройки egress сервера, поэтому не добавляйте раздел egress в compose.config.yaml.

Включение шлюза в Kubernetes

Эти шаги начинаются с развёртывания из раздела Развёртывание в Kubernetes. В них используются переменные REGISTRY, TAG и PLATFORM с той страницы и два её файла значений. Выполняйте команды из верхнего каталога архива, используя OpenSSL 3.0 или новее. Чарт песочниц не предоставляет шлюз в Azure Kubernetes Service (AKS).

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

  • Порт 9464, порт метрик: политика закрывает его. Если Prometheus собирает метрики с этого порта, задайте в cma-server-values.yaml для server.telemetry.prometheus.scraper.namespace пространство имён, в котором работает Prometheus.
  • Порт 8400, порт API: политика открывает его для любых источников. Если ваша собственная политика ограничивает доступ к порту 8400, это ограничение перестаёт работать. Сетевые политики суммируются, поэтому соединение проходит, если его разрешает хотя бы одна политика.
  1. Соберите и отправьте образ шлюза

    docker buildx build --platform "$PLATFORM" -f kubernetes/egress/Dockerfile -t "$REGISTRY/cma-egress:$TAG" --push .
  2. Создайте центр сертификации и ключ шлюза

    (umask 077 && openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes -days 825 \
      -subj "/CN=cma-server egress gateway" \
      -addext "basicConstraints=critical,CA:TRUE,pathlen:0" \
      -addext "keyUsage=critical,keyCertSign,cRLSign" \
      -keyout egress-ca.key -out egress-ca.crt)
    kubectl -n cma create secret tls cma-egress-ca --cert=egress-ca.crt --key=egress-ca.key
    kubectl -n cma-server create configmap cma-egress-ca --from-file=ca.crt=egress-ca.crt
    GATEWAY_KEY=$(openssl rand -hex 32)
    printf %s "$GATEWAY_KEY" | kubectl -n cma create secret generic cma-egress-gateway-key --from-file=gateway-key=/dev/stdin
    printf %s "$GATEWAY_KEY" | kubectl -n cma-server create secret generic cma-egress-gateway-key --from-file=gateway-key=/dev/stdin
    unset GATEWAY_KEY

    Затем удалите egress-ca.key — закрытый ключ центра сертификации. Любой, кто владеет им, может выдавать себя за любой веб-сайт перед вашими песочницами. Сертификат действителен 825 дней. См. раздел Обновление сертификата.

  3. Удалите песочницы предыдущих сессий

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

    kubectl -n cma scale deployment cma-dispatcher --replicas=0
    kubectl -n cma delete sandboxwarmpool cma-sandbox
    kubectl -n cma delete sandboxclaims --all

    В Google Kubernetes Engine (GKE) также выполните эту команду:

    kubectl -n cma delete sandboxes --all

    Повторяйте kubectl -n cma get sandboxes,pods,pvc, пока команда ничего не найдёт. helm upgrade на шаге «Включите сторону песочниц» снова запускает диспетчер.

  4. Включите сторону сервера

    Выберите для шлюза свободный адрес IPv4 в диапазоне Service кластера. Столбец CLUSTER-IP команды kubectl get svc -A показывает адреса из этого диапазона. Добавьте следующее в cma-server-values.yaml. Если в файле уже есть блок server, объедините эти строки с ним:

    egressGateway:
      enabled: true
      proxyAddress: 34.118.224.53:3128   # the address that you chose, and port 3128
    server:
      config:
        egress:
          allowed_hostnames:
            - api.github.com

    Затем выполните обновление:

    helm upgrade cma-server kubernetes/server/chart --namespace cma-server -f cma-server-values.yaml --wait
  5. Включите сторону песочниц

    Выполните kubectl -n cma-server get svc, чтобы вывести два объекта Service сервера. При новой установке они называются cma-server и cma-server-egress.

    В cma-values.yaml измените egress.mode на gateway и добавьте блок gateway в egress. Укажите в блоке два имени, которые вывела команда:

    egress:
      mode: gateway
      gateway:
        serviceIP: 34.118.224.53   # the address that you chose
        serverService: cma-server
        serverEgressService: cma-server-egress
        apiServerCIDRs:
          - 203.0.113.10/32        # the cluster's API endpoint

    Сохраните остальные значения egress в файле. Чтобы вывести адреса и порт конечной точки API, выполните kubectl get endpoints kubernetes -n default. Если порт не 443, также задайте egress.gateway.apiServerPort.

    helm upgrade cma kubernetes/chart --namespace cma -f cma-values.yaml --wait

    Если обновление останавливается из-за конфликта по .spec.replicas, выполните kubectl -n cma scale deployment cma-dispatcher --replicas=1, а затем снова запустите обновление.

Добавление учётных данных

Создайте учётные данные в переменной окружения, как показано в разделе Добавление учётных данных. В руководствах по размещённому сервису сказано, что такие учётные данные не поддерживаются с самостоятельно размещаемыми песочницами. Это описывает размещённый сервис, а не ваш сервер.

Ваш сервер добавляет собственные правила. Он отклоняет запрос, нарушающий одно из них, с ошибкой 400, в которой указано поле. Два из этих правил:

  • networking должен иметь тип limited, а каждый хост в allowed_hosts должен быть в списке сервера egress.allowed_hostnames.
  • injection_location должен быть {"header": true} в JSON и не может быть опущен.

После добавления хоста в список сервера примените изменение. В Docker Compose выполните docker compose up -d. В Kubernetes выполните команду helm upgrade сервера и kubectl -n cma-server rollout restart deployment -l anthropic.com/role=server.

Проверка шлюза исходящего трафика

Создайте сессию с хранилищем учётных данных и попросите агента выполнить две команды. Этот пример предназначен для учётных данных с именем GITHUB_TOKEN, в которых указан api.github.com:

printenv GITHUB_TOKEN
curl -sS -H "Authorization: Bearer $GITHUB_TOKEN" https://api.github.com/user

Первая команда выводит заполнитель, начинающийся с cma_ph_. Вторая выводит профиль учётной записи GitHub, которой принадлежит токен, потому что шлюз заменил заполнитель токеном. Шлюз отклоняет запрос к хосту, которого нет в вашем списке, с ошибкой 403.

В Kubernetes, если каждый запрос получает ошибку 503, вероятно, сеть вашего кластера переписывает адреса подов, как это делает параметр --masquerade-all kube-proxy. Шлюз различает песочницы по адресам их подов, поэтому эти адреса должны доходить до него без изменений.

Обновление сертификата

В Kubernetes обновляйте сертификат, когда не выполняется ни одна сессия. Повторите весь шаг «Создайте центр сертификации и ключ шлюза» в разделе Включение шлюза в Kubernetes. Он заново создаёт центр сертификации и ключ шлюза, поэтому удалённый вами файл egress-ca.key не понадобится. Внесите одно изменение: добавьте --dry-run=client -o yaml | kubectl apply -f - в конец каждой из четырёх строк, выполняющих kubectl create. Например, строка, которая заканчивается на --from-file=gateway-key=/dev/stdin, после этого заканчивается на --from-file=gateway-key=/dev/stdin --dry-run=client -o yaml | kubectl apply -f -.

Затем перезапустите серверы и шлюз:

kubectl -n cma-server rollout restart deployment -l anthropic.com/role=server
kubectl -n cma rollout restart deployment/cma-egress

Ограничения шлюза исходящего трафика

  • Заголовки: шлюз подставляет значение только в заголовок запроса, но никогда не в URL или тело. По умолчанию единственный такой заголовок — Authorization. Чтобы разрешить другие, перечислите их вместе с Authorization в egress.swap_header_names или в CMA_EGRESS__SWAP_HEADER_NAMES в .env для стека Compose.
  • Программы, игнорирующие переменные прокси: песочницы находят шлюз через HTTPS_PROXY и связанные переменные. Инструменты Java, такие как Maven и Gradle, не читают эти переменные, поэтому ничего не могут достичь.

Эта страница была полезной?