Вход Agent Gateway в Agent Runtime с использованием Model Armor

1. Введение

В этом практическом занятии рассматривается управление входящим трафиком Agent Gateway для агентов ИИ, размещенных на Agent Runtime .

Agent Gateway, работающий в режиме входящего трафика ( клиент-агент ), поддерживает управление обменом данными между клиентами — конечными пользователями, агентами на рабочих столах, средами разработки программного обеспечения, одноранговыми агентами и т. д. — и агентами, размещенными в среде выполнения Agent Runtime . Этот режим используется для защиты агентов от атак с внедрением входящих запросов или вредоносного контента, отправляемого клиентами. Весь входящий трафик обрабатывается с использованием расширений авторизации и Model Armor для защиты точки входа в сеть для всего взаимодействия с агентами.

Что вы строите

  • Шлюз агентов в режиме входящего трафика ( от клиента к агенту ).
  • Продление авторизации Model Armor
  • Агент Agent Runtime ADK с идентификацией агента
  • Данные файлов облачного хранилища запрашиваются агентом с помощью MCP.
  • Шаблоны Model Armor для отбора вопросов и ответов для магистерских программ по праву.
  • Шаблоны защиты конфиденциальных данных для обезличивания данных

рисунок1

Рис. 1. Архитектура Codelab

Чему вы научитесь

  • Как развернуть Agent Gateway для проверки входящего трафика к агенту.
  • Как настроить расширения авторизации и делегирование в Model Armor
  • Как создавать и развертывать пользовательские шаблоны Model Armor
  • Как создавать и развертывать пользовательские шаблоны защиты конфиденциальных данных
  • Как проверить и подтвердить эффективность политики отбора кандидатов на магистерские программы (LLM).

Что вам нужно

  • Проект Google Cloud с включенной функцией выставления счетов.
  • Права доступа IAM для предоставления сетевых сервисов, наборов данных BigQuery и ресурсов платформы агентов.
  • POSIX-совместимая оболочка ( bash или zsh ) с установленным Google Cloud CLI (компонент gcloud ).
  • Инструменты командной строки: git , curl , jq (процессор JSON), Python 3 и uv (менеджер пакетов Python).

2. Понятия

Роли управления движением и въезда

Agent Gateway функционирует как сетевой прокси-сервер, учитывающий действия агентов, но его операционная роль меняется в зависимости от направления трафика:

  • Режим «агент-в-любое место» (исходящий трафик): функционирует как исходящий прокси-сервер. Когда агент обращается к внешним инструментам баз данных, сторонним серверам MCP или API, исходящий шлюз управляет обнаружением сервисов, маршрутизацией, взаимным TLS ( mTLS ), динамическим внедрением учетных данных OAuth и контролем доступа к конечным точкам.
  • Режим взаимодействия клиента с агентом (входящий трафик): функционирует как шлюз безопасности на стороне клиента. Его основная задача — защита входа в среду выполнения агента путем перехвата и очистки входящих запросов на естественном языке до того, как они достигнут кода агента или моделей ИИ.

Входящий путь к среде выполнения агента

Клиентские запросы, направленные на агента, размещенного на Agent Runtime, перенаправляются на конечную точку API aiplatform.googleapis.com .

POST https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}:query

Этот входящий поток данных к конечной точке API представляет собой путь взаимодействия клиента с агентом .

Для обеспечения безопасности этого управляемого Google входящего канала связи Agent Gateway напрямую интегрируется с Google Front End ( GFE ) на уровне инфраструктуры обслуживания API. При развертывании управляемого агента в Agent Runtime Google автоматически привязывает политику авторизации входящего шлюза к входящим запросам клиентов на границе сети.

рисунок 2

Рис. 2. Управление входящим трафиком с помощью Agent Gateway к Agent Runtime.

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

Встроенная система очистки от угроз с помощью Model Armor

Проверка учетных данных вызывающего абонента и обеспечение контроля доступа IAM ( roles/aiplatform.user ) осуществляется собственными силами уровня хостинга API aiplatform . Сам входящий шлюз не выполняет авторизацию по идентификаторам, а фокусируется на безопасности контента с использованием расширений авторизации , настроенных с помощью профиля CONTENT_AUTHZ . Шлюз действует как точка принудительного применения политик , перехватывая запросы на естественном языке в процессе передачи, прежде чем они достигнут цикла рассуждений агента ИИ или базового LLM.

Когда на фронтенд-сервис поступает запрос от пользователя, шлюз инициирует вызов ext_proc (внешняя обработка) к региональной службе расширения авторизации Model Armor, которая передает вызов в плоскость данных Model Armor . Model Armor действует как межсетевой экран, обрабатывающий естественный язык, сравнивая текст с активными шаблонами для выявления угроз безопасности:

  • Непрямые инъекции и попытки взлома системы.
  • Вредоносные URL-адреса, оскорбительные выражения или небезопасный контент
  • Утечка персональных данных и PII информации

Если шаблон включает фильтры защиты конфиденциальных данных ( SDP ) , Model Armor выполняет дополнительный gRPC вызов к облачной службе SDP. Облачная служба SDP проверяет полезную нагрузку, используя указанный шаблон, выполняет любую запрошенную деидентификацию или редактирование и возвращает очищенный результат обратно по цепочке для безопасной пересылки.

Если обнаруживается нарушение политики или совпадение с неотредактированными конфиденциальными данными, шлюз блокирует или редактирует полезную нагрузку на границе сети, прежде чем она попадет в среду выполнения. В результате работающее приложение ИИ-агента остается защищенным и никогда не обрабатывает вредоносные или неотредактированные полезные нагрузки.

На этом завершается раздел, посвященный концепциям... далее переходим к разделу «Настройка» .

3. Настройка

Необходимые роли IAM

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

Категория

Требуемая роль IAM (ID)

Описание

управление API

roles/serviceusage.serviceUsageAdmin

Включите сервисы Google Cloud API

Сетевые устройства и шлюзы

roles/networkservices.admin

Шлюз агента предоставления услуг

Расширения сервисов

roles/serviceextensions.admin

Настройка расширений маршрутизации

Сетевая безопасность

roles/networksecurity.admin

Разверните политики авторизации.

Защита конфиденциальных данных

roles/dlp.admin

Управление проверкой SDP и обезличивание шаблонов

Модель брони

roles/modelarmor.admin

Создавайте и управляйте шаблонами безопасности.

Агентская платформа

roles/aiplatform.admin

Развертывание рабочих нагрузок среды выполнения агента

Облачное хранилище

roles/storage.admin

Управление развертыванием и хранилищами данных клиентов.

Администрирование IAM

roles/resourcemanager.projectIamAdmin

Привяжите разрешения на уровне проекта к идентификатору агента.

Журналы и аудит

roles/logging.viewer

Проверьте трассировки и журналы аудита.

В качестве альтернативы можно использовать общую базовую роль, например, roles/admin или устаревшую роль roles/owner .

Получите доступ к своему проекту

В этом практическом занятии используется один проект Google Cloud. Шаги настройки выполняются с помощью командной строки gcloud и команд оболочки Linux.

Для начала откройте командную строку вашего проекта Google Cloud:

Укажите идентификатор вашего проекта.

gcloud config set project SET_YOUR_PROJECT_ID_HERE

Аутентификация сессии

# login to gcloud cli
gcloud auth login
# login for gcloud api
gcloud auth application-default login

Установка переменных среды оболочки

# set custom var for slug (eg, "foo") and region preference
export SLUG="foo"
export REGION="us-central1"
echo ${SLUG}
echo ${REGION}
# create project vars (automatic)
export PROJ_ID=$(gcloud config list --format="value(core.project)")
export PROJ_NO=$(gcloud projects describe ${PROJ_ID} --format="value(projectNumber)")
export ORG_ID=$(gcloud projects get-ancestors ${PROJ_ID} --format="value(id)" | tail -n 1)
export USER_IDENTITY=$(gcloud config get-value account)
echo ${PROJ_ID}
echo ${PROJ_NO}
echo ${ORG_ID}
echo ${USER_IDENTITY}
# create resource vars (automatic)
export AGW_NAME="agw-${SLUG}-${REGION}-cta"
export AGW_URI="projects/${PROJ_ID}/locations/${REGION}/agentGateways/${AGW_NAME}"
export RE_AGENT_NAME="agent-crm"
export RE_AGENT_ID_SET="principalSet://agents.global.org-${ORG_ID}.system.id.goog/attribute.platformContainer/aiplatform/projects/${PROJ_NO}"
export STAGING_BUCKET="agent-staging-${PROJ_NO}"
export DATA_BUCKET="customer-data-${PROJ_NO}"
export MCP_URL="https://storage.mtls.googleapis.com/storage/mcp"
echo ${AGW_NAME}
echo ${AGW_URI}
echo ${RE_AGENT_NAME}
echo ${RE_AGENT_ID_SET}
echo ${STAGING_BUCKET}
echo ${DATA_BUCKET}
echo ${MCP_URL}
# create local dir for config files
mkdir -p cfg

Если вы используете самостоятельную установку Google Cloud SDK (т.е. вне Cloud Shell), обновите компоненты до последней версии.

# update gcloud cli
gcloud components update

Включить API-сервисы

# enable google apis (agent platform bundle, part 1)
gcloud services enable \
  agentregistry.googleapis.com \
  aiplatform.googleapis.com \
  apphub.googleapis.com \
  apptopology.googleapis.com \
  cloudapiregistry.googleapis.com \
  cloudtrace.googleapis.com \
  compute.googleapis.com \
  dataform.googleapis.com \
  iam.googleapis.com \
  iamconnectors.googleapis.com \
  iap.googleapis.com \
  logging.googleapis.com \
  modelarmor.googleapis.com \
  monitoring.googleapis.com \
  networksecurity.googleapis.com \
  networkservices.googleapis.com \
  notebooks.googleapis.com \
  observability.googleapis.com
# enable google apis (agent platform bundle, part 2)
gcloud services enable \
  securitycenter.googleapis.com \
  saasservicemgmt.googleapis.com \
  storage.googleapis.com \
  telemetry.googleapis.com \
  texttospeech.googleapis.com
# enable google apis (all the rest)
gcloud services enable \
  dlp.googleapis.com

На этом завершается этап настройки... далее переходим к разделу «Шлюз» .

4. Шлюз

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

В то время как политики исходящего трафика часто запускаются в режиме DRY_RUN на уровне шлюза, управление входящим контентом ( CONTENT_AUTHZ ) развертывается непосредственно в режиме принудительного применения. Детальное ведение журналов только для аудита или активная блокировка вместо этого контролируются на более высоком уровне в рамках отдельных шаблонов Model Armor.

Создать шлюз

# create agent gateway config file
cat > cfg/${AGW_NAME}.yaml <<EOF
name: ${AGW_NAME}
protocols:
  - MCP
googleManaged:
  governedAccessPath: CLIENT_TO_AGENT
EOF
# import agent gateway config file (create gateway)
gcloud network-services agent-gateways import ${AGW_NAME} \
  --source="cfg/${AGW_NAME}.yaml" \
  --location=${REGION}

Проверьте шлюз

# list agent gateways (in region)
gcloud network-services agent-gateways list --location=${REGION}
# show agent gateway details (verify deployment state)
gcloud network-services agent-gateways describe ${AGW_NAME} --location=${REGION}

На этом завершается вводная часть... далее переходим к разделу «Модельная броня» .

5. Модель брони

Шаблоны SDP

Создайте шаблон для проверки и обезличивания конфиденциальных данных ( SDP ) , который будет использоваться в шаблоне ответа Model Armor. Эта конфигурация помечает номера социального страхования США (SSN) для последующего удаления.

Создать шаблон проверки

Шаблон проверки выявляет конфиденциальную информацию ( US_SOCIAL_SECURITY_NUMBER ) в данных.

# create inspect template
curl -fsS -X POST "https://dlp.googleapis.com/v2/projects/${PROJ_ID}/locations/${REGION}/inspectTemplates" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "Content-Type: application/json" -H "x-goog-user-project: ${PROJ_ID}" \
  -d @- << EOF
{
  "templateId": "agw-ssn-inspect-template",
  "inspectTemplate": {
    "displayName": "ssn inspect template",
    "inspectConfig": {
      "infoTypes": [
        { "name": "US_SOCIAL_SECURITY_NUMBER" }
      ],
      "minLikelihood": "POSSIBLE"
    }
  }
}
EOF

Создать шаблон для обезличивания данных

Шаблон деидентификации определяет преобразование, которое должно быть применено к номерам социального страхования (SSN), найденным с помощью шаблона проверки. В данном случае преобразование заключается в замене номера социального страхования (SSN) на информационный тип.

# create de-identify template
curl -fsS -X POST "https://dlp.googleapis.com/v2/projects/${PROJ_ID}/locations/${REGION}/deidentifyTemplates" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "Content-Type: application/json" -H "x-goog-user-project: ${PROJ_ID}" \
  -d @- << EOF
{
  "templateId": "agw-ssn-redaction-template",
  "deidentifyTemplate": {
    "displayName": "SSN Redaction Template",
    "deidentifyConfig": {
      "infoTypeTransformations": {
        "transformations": [{
          "primitiveTransformation": { "replaceWithInfoTypeConfig": {} }
        }]
      }
    }
  }
}
EOF

Проверьте шаблоны SDP.

# get (describe) inspect template
curl -fsS -X GET "https://dlp.googleapis.com/v2/projects/${PROJ_ID}/locations/${REGION}/inspectTemplates" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "Content-Type: application/json" -H "x-goog-user-project: ${PROJ_ID}" | jq
# get (describe) de-identify template
curl -fsS -X GET "https://dlp.googleapis.com/v2/projects/${PROJ_ID}/locations/${REGION}/deidentifyTemplates" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "Content-Type: application/json" -H "x-goog-user-project: ${PROJ_ID}" | jq

Шаблоны для создания моделей брони

По умолчанию конечная точка API Model Armor — глобальная ( modelarmor.googleapis.com ). Однако ресурсы Model Armor для шаблонов и механизмов оценки локализованы для конкретных географических регионов. Региональный прокси-сервер Google Cloud (REP), или региональная конечная точка API, для Model Armor — https://modelarmor.${LOCATION}.rep.googleapis.com/ .

По умолчанию при запуске gcloud model-armor ... интерфейс командной строки пытается отправлять API-запросы на стандартную глобальную конечную точку ( https://modelarmor.googleapis.com/ ). Переопределение конечной точки API используется для перенаправления всех HTTP-запросов SDK/CLI для Model Armor непосредственно на региональный уровень API rep.googleapis.com , где фактически создаются, хранятся и запрашиваются эти привязанные к местоположению шаблоны.

Установить переопределение API

# set api endpoint override per location
gcloud config set api_endpoint_overrides/modelarmor "https://modelarmor.${REGION}.rep.googleapis.com/"

Проверьте переопределение API.

# view api overrides on active gcloud config
gcloud config list api_endpoint_overrides/

Создать шаблон фильтра запроса

Создайте шаблон фильтра запросов для блокировки разжигания ненависти, домогательств, контента сексуального характера и атак с внедрением URI. Будет включено логирование для сбора подробной информации о событиях, связанных с применением политики. Также можно настроить пользовательские коды ошибок и сообщения при блокировке запроса.

# create model armor template (request)
gcloud beta model-armor templates create ${AGW_NAME}-modar-req-template \
  --project=${PROJ_ID} \
  --location=${REGION} \
  --rai-settings-filters='[
    { "filterType": "HATE_SPEECH", "confidenceLevel": "MEDIUM_AND_ABOVE" },
    { "filterType": "HARASSMENT", "confidenceLevel": "MEDIUM_AND_ABOVE" },
    { "filterType": "SEXUALLY_EXPLICIT", "confidenceLevel": "MEDIUM_AND_ABOVE" }
  ]' \
  --pi-and-jailbreak-filter-settings-enforcement=enabled \
  --pi-and-jailbreak-filter-settings-confidence-level=medium-and-above \
  --template-metadata-enforcement-type=INSPECT_AND_BLOCK \
  --malicious-uri-filter-settings-enforcement=enabled \
  --template-metadata-custom-llm-response-safety-error-code=798 \
  --template-metadata-custom-llm-response-safety-error-message="ahoy! model response blocked by content filter :(" \
  --template-metadata-custom-prompt-safety-error-code=799 \
  --template-metadata-custom-prompt-safety-error-message="ahoy! the request was blocked by ye content filter... so rephrase the prompt and try again!" \
  --template-metadata-ignore-partial-invocation-failures \
  --template-metadata-log-operations \
  --template-metadata-log-sanitize-operations

Создать шаблон фильтра ответов

Создайте шаблон фильтра ответа, который будет блокировать то же содержимое, что и шаблон фильтра запроса. На стороне ответа настроена защита от утечки данных (DLP) для обезличивания номеров социального страхования (SSN) в сообщениях, возвращаемых клиенту от агента.

# create model armor template (response)
gcloud beta model-armor templates create ${AGW_NAME}-modar-resp-template \
  --project=${PROJ_ID} \
  --location=${REGION} \
  --rai-settings-filters='[
      { "filterType": "HATE_SPEECH", "confidenceLevel": "MEDIUM_AND_ABOVE" },
      { "filterType": "HARASSMENT", "confidenceLevel": "MEDIUM_AND_ABOVE" },
      { "filterType": "SEXUALLY_EXPLICIT", "confidenceLevel": "MEDIUM_AND_ABOVE" }
  ]' \
  --malicious-uri-filter-settings-enforcement=enabled \
  --advanced-config-inspect-template=projects/${PROJ_ID}/locations/${REGION}/inspectTemplates/agw-ssn-inspect-template \
  --advanced-config-deidentify-template=projects/${PROJ_ID}/locations/${REGION}/deidentifyTemplates/agw-ssn-redaction-template \
  --template-metadata-enforcement-type=INSPECT_AND_BLOCK \
  --template-metadata-custom-llm-response-safety-error-code=798 \
  --template-metadata-custom-llm-response-safety-error-message="ahoy! model response blocked by content filter :(" \
  --template-metadata-custom-prompt-safety-error-code=799 \
  --template-metadata-custom-prompt-safety-error-message="ahoy! the request was blocked by ye content filter... so rephrase the prompt and try again!" \
  --template-metadata-ignore-partial-invocation-failures \
  --template-metadata-log-operations \
  --template-metadata-log-sanitize-operations

Проверьте шаблоны брони модели.

# list model armor templates
gcloud model-armor templates list --location=${REGION}
# show request filter template details
gcloud model-armor templates describe ${AGW_NAME}-modar-req-template --location=${REGION}
# show response filter template details
gcloud model-armor templates describe ${AGW_NAME}-modar-resp-template --location=${REGION}

Разрешения IAM

Model Armor выполняет вызовы API для использования службы защиты конфиденциальных данных ( SDP ). Предоставьте службе Model Armor права доступа IAM для использования шаблонов SDP для проверки и обезличивания данных.

Привязка политики IAM для защиты конфиденциальных данных

# grant dlp (sdp) user role to the model armor service identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="serviceAccount:service-${PROJ_NO}@gcp-sa-modelarmor.iam.gserviceaccount.com" \
  --role="roles/dlp.user"

Проверьте права доступа IAM.

# show iam policy for all dlp (sdp) roles on project
gcloud projects get-iam-policy ${PROJ_ID} \
  --flatten="bindings[].members" \
  --filter="bindings.role:roles/dlp" \
  --format="table(bindings.role:label=ROLE, bindings.members:label=PRINCIPAL_IDENTITY)"

На этом завершается раздел, посвященный модельной броне... далее переходим к разделу «Авторизация» .

6. Авторизация

Разрешения IAM

Для проверки входящего трафика с помощью Model Armor агенту службы Service Extensions ( DEP ) требуются явные привязки IAM (даже между ресурсами в рамках одного проекта):

  • roles/modelarmor.calloutUser & roles/serviceusage.serviceUsageConsumer : Предоставлены для проекта шлюза, чтобы разрешить вызовы встроенной проверки.
  • roles/modelarmor.user : Предоставляется в рамках проекта шаблонов для доступа и оценки шаблонов Model Armor.

Привязать политику IAM для Model Armor

# grant model armor callout user role to dep (service extension) service agent
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="serviceAccount:service-${PROJ_NO}@gcp-sa-dep.iam.gserviceaccount.com" \
  --role="roles/modelarmor.calloutUser"

# grant service usage consumer role to dep (service extension) service agent
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="serviceAccount:service-${PROJ_NO}@gcp-sa-dep.iam.gserviceaccount.com" \
  --role="roles/serviceusage.serviceUsageConsumer"

# grant model armor user role to dep (service extension) service agent
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="serviceAccount:service-${PROJ_NO}@gcp-sa-dep.iam.gserviceaccount.com" \
  --role="roles/modelarmor.user"

Проверьте права доступа IAM.

# show iam policy on project for dep (service extension) service agent
gcloud projects get-iam-policy ${PROJ_ID} \
  --flatten="bindings[].members" \
  --filter="bindings.members:serviceAccount:service-${PROJ_NO}@gcp-sa-dep.iam.gserviceaccount.com" \
  --format="table(bindings.members:label=PRINCIPAL_IDENTITY, bindings.role:label=ROLE)"

Расширение авторизации

Конфигурация расширения авторизации для Agent Gateway определяет параметры интеграции, которые будут применяться к входящему и исходящему трафику полезной нагрузки. Конфигурация определяет внешнюю службу обработки ( service ), которая ссылается на региональный API Model Armor и связывается с конкретными шаблонами запросов и ответов с помощью поля метаданных model_armor_settings .

Создать расширение авторизации

# create authz extension config file (enforced mode)
cat > cfg/${AGW_NAME}-svc-ext-authz-modar.yaml <<EOF
name: ${AGW_NAME}-svc-ext-authz-modar
service: modelarmor.${REGION}.rep.googleapis.com
metadata:
  model_armor_settings: '[
    {
      "request_template_id": "projects/${PROJ_ID}/locations/${REGION}/templates/${AGW_NAME}-modar-req-template",
      "response_template_id": "projects/${PROJ_ID}/locations/${REGION}/templates/${AGW_NAME}-modar-resp-template"
    }
  ]'
failOpen: true
timeout: 5s
EOF

Импорт расширения авторизации

# import authz extension file
gcloud service-extensions authz-extensions import ${AGW_NAME}-svc-ext-authz-modar \
  --source=cfg/${AGW_NAME}-svc-ext-authz-modar.yaml \
  --location=${REGION}

Проверить расширение авторизации

# list authz extensions
gcloud service-extensions authz-extensions list --location=${REGION}
# show authz extension details
gcloud service-extensions authz-extensions describe ${AGW_NAME}-svc-ext-authz-modar \
  --location=${REGION}

Политика авторизации

Политики авторизации используют профили политик для определения типа выполняемой оценки. В то время как профили на основе запросов ( REQUEST_AUTHZ ) оценивают заголовки HTTP, в данной конфигурации используется профиль авторизации на основе содержимого ( CONTENT_AUTHZ ) для привязки расширения Model Armor к шлюзу для глубокого анализа полезной нагрузки.

Создать политику авторизации

# create authz policy config file (attach dry-run authz extension)
cat > cfg/${AGW_NAME}-authz-policy-modar.yaml <<EOF
name: ${AGW_NAME}-authz-policy-modar
target:
  resources:
    - "projects/${PROJ_ID}/locations/${REGION}/agentGateways/${AGW_NAME}"
policyProfile: CONTENT_AUTHZ
action: CUSTOM
customProvider:
  authzExtension:
    resources:
      - "projects/${PROJ_ID}/locations/${REGION}/authzExtensions/${AGW_NAME}-svc-ext-authz-modar"
EOF

Политика авторизации импорта

# import authz policy config file (enable authz policy)
gcloud beta network-security authz-policies import ${AGW_NAME}-authz-policy-modar \
  --source=cfg/${AGW_NAME}-authz-policy-modar.yaml \
  --location=${REGION}

Проверить политику авторизации

# list authz policies
gcloud beta network-security authz-policies list --location=${REGION}
# show authz policy details
gcloud beta network-security authz-policies describe ${AGW_NAME}-authz-policy-modar \
  --location=${REGION}

На этом завершается раздел, посвященный авторизации... далее переходим к разделу «Кодовая база» .

7. Кодовая база

Код агента и данные файлов, используемые в этом практическом занятии, хранятся в удаленном репозитории Google Cloud GitHub . Следующие шаги клонируют репозиторий локально, скопируют необходимые файлы в текущую структуру рабочих каталогов, а затем очистят временные файлы.

Получение удаленных артефактов

# clone remote repository to temp local dir
git clone https://github.com/GoogleCloudPlatform/cloud-networking-solutions.git ./temp_agw_cuj_arun_ingress_modar
# copy agent runtime and endpoint definitions to working project dir
cp -r temp_agw_cuj_arun_ingress_modar/codelabs/agw-cuj-arun-ingress-modar/agent-crm ./agent-crm
# remove temporary directory
rm -rf temp_agw_cuj_arun_ingress_modar

Для загрузки, сборки и развертывания упакованного кода приложения агента и артефактов его зависимостей среда выполнения Agent Runtime использует хранилище для промежуточного хранения.

Создайте хранилище для подготовки данных.

# create storage bucket
gcloud storage buckets create gs://${STAGING_BUCKET}   --location=${REGION}   --uniform-bucket-level-access

Проверьте хранилище.

# list storage buckets
gcloud storage buckets list --format="value(storage_url)"

На этом завершается раздел, посвященный коду... далее переходим к разделу «Данные о клиентах GCS» .

Данные клиентов

Создайте сегмент Cloud Storage для хранения данных клиентов. Агент будет считывать данные напрямую, используя стандартную клиентскую библиотеку Google Cloud и вызывая конечную точку Cloud Storage MCP.

Создайте хранилище для данных клиентов.

# create storage bucket
gcloud storage buckets create gs://${DATA_BUCKET}   --location=${REGION}   --uniform-bucket-level-access

Проверьте хранилище.

# list storage buckets
gcloud storage buckets list --format="value(storage_url)"

Загрузка данных клиента

# copy local data to bucket
gcloud storage cp -r ./agent-crm/data/* gs://${DATA_BUCKET}/

Проверка данных клиента

# list bucket objects
gcloud storage ls gs://${DATA_BUCKET}/ --long

На этом завершается раздел, посвященный данным клиентов GCS... далее переходим к разделу, посвященному агентам ADK .

8. Агент ADK

Агент agent-crm ADK, развернутый в Agent Runtime, настроен в скрипте развертывания со следующими параметрами для интеграции с Agent Platform:

  • "identity_type": types.IdentityType.AGENT_IDENTITY для предоставления уникального основного идентификатора на основе SPIFFE для агента
  • "client_to_agent_config": {"agent_gateway": "${AGW_URI}"} для направления всего входящего трафика для агента на путь оценки и применения политик Agent Gateway.

Агенту также передается URL-адрес mTLS MCP-сервера Cloud Storage MCP и имя хранилища данных для вызова инструмента GCS MCP по защищенному соединению.

Развернуть агент

# deploy agent
uv --directory agent-crm run python3 deploy_agent.py \
  --project=${PROJ_ID} \
  --region=${REGION} \
  --src-dir=./agent \
  --staging-bucket=${STAGING_BUCKET} \
  --display-name="${RE_AGENT_NAME}" \
  --description="agent for customer data" \
  --mcp-server-url="${MCP_URL}" \
  --data-bucket=${DATA_BUCKET} \
  --enable-telemetry \
  --enable-agent-identity \
  --agent-gateway-ingress=${AGW_URI} \
  --allow-token-sharing

Проверка развертывания

Получение основных параметров развертывания

# fetch agent runtime (reasoning engine) resource id
export RE_ENGINE_ID=$(curl -s -X GET "https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  | jq -r --arg name "${RE_AGENT_NAME}" '.reasoningEngines[] | select(.displayName==$name) | .name | split("/") | last')
echo ${RE_ENGINE_ID}
# fetch agent runtime (reasoning engine) agent identity directly from reasoning engine
export RE_AGENT_IDENTITY="principal://$(curl -s \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  "https://${REGION}-aiplatform.googleapis.com/v1beta1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}" \
  | jq -r '.spec.effectiveIdentity')"
echo ${RE_AGENT_IDENTITY}

Проверьте конфигурацию шлюза.

# show agent runtime config details (gateway config)
curl -s -X GET "https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  | jq '{displayName: .displayName, name: .name, effectiveIdentity: .spec.effectiveIdentity, agentGatewayConfig: .spec.deploymentSpec.agentGatewayConfig}'

Разрешения IAM

Привязка политик IAM к идентификации агента

# grant mcp tool user role to agent set (all agent runtime agents in project)
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="${RE_AGENT_ID_SET}" \
  --role="roles/mcp.toolUser"
# grant storage object viewer role to agent identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="${RE_AGENT_IDENTITY}" \
  --role="roles/storage.objectViewer"

# grant aiplatform user role to agent identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="${RE_AGENT_IDENTITY}" \
  --role="roles/aiplatform.user"

# grant cloudtrace agent role to agent identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="${RE_AGENT_IDENTITY}" \
  --role="roles/cloudtrace.agent"

# grant cloud monitoring metric writer role to agent identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="${RE_AGENT_IDENTITY}" \
  --role="roles/monitoring.metricWriter"
# grant cloud logging log writer role to agent identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="${RE_AGENT_IDENTITY}" \
  --role="roles/logging.logWriter"

# grant telemetry writer role to agent identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="${RE_AGENT_IDENTITY}" \
  --role="roles/telemetry.writer"

# grant service usage consumer role to agent identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="${RE_AGENT_IDENTITY}" \
  --role="roles/serviceusage.serviceUsageConsumer"

# grant browser role to agent identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="${RE_AGENT_IDENTITY}" \
  --role="roles/browser"

Проверьте права доступа IAM.

# show agent identity roles on project
gcloud projects get-iam-policy ${PROJ_ID} \
  --flatten="bindings[].members" \
  --filter="bindings.members:${RE_AGENT_IDENTITY}" \
  --format="table(bindings.members.sub('^.*locations/', 'principal://agents.[...]/locations/'):label=PRINCIPAL_IDENTITY, bindings.role:label=ROLE)"
# show agent set roles on project
gcloud projects get-iam-policy ${PROJ_ID} \
  --flatten="bindings[].members" \
  --filter="bindings.members:${RE_AGENT_ID_SET}" \
  --format="table(bindings.members.sub('^.*platformContainer/', 'principalSet://agents.[...]/'):label=PRINCIPAL_IDENTITY, bindings.role:label=ROLE)"

На этом завершается раздел, посвященный агенту ADK... далее переходим к разделу «Тестирование» .

9. Тест

Отправляйте запросы из командной строки.

Проверьте безопасную подсказку.

# post query to agent streamQuery
curl --no-buffer -s -X POST "https://${REGION}-aiplatform.googleapis.com/v1beta1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}:streamQuery" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "Content-Type: application/json" -H "X-Goog-User-Project: ${PROJ_ID}" \
  -d @- <<EOF | jq -r --unbuffered 'if type == "array" then .[] else . end | select(.content.parts != null) | .content.parts[].text // empty'
{
  "input": {
    "message": "what are the names of our west customers?",
    "user_id": "test-user"
  }
}
EOF

Ответ должен выглядеть примерно так: "Наши клиенты на западе: Боб Джонсон и Элис Браун".

Проверьте триггер редактирования.

# post query to agent streamQuery
curl --no-buffer -s -X POST "https://${REGION}-aiplatform.googleapis.com/v1beta1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}:streamQuery" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "Content-Type: application/json" -H "X-Goog-User-Project: ${PROJ_ID}" \
  -d @- <<EOF | jq -r --unbuffered 'if type == "array" then .[] else . end | select(.content.parts != null) | .content.parts[].text // empty'
{
  "input": {
    "message": "what are ssn's for bob johnson and alice brown?",
    "user_id": "test-user"
  }
}
EOF

Проверьте еще одну безопасную подсказку.

# post query to agent streamQuery
curl --no-buffer -s -X POST "https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}:streamQuery" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "Content-Type: application/json" -H "X-Goog-User-Project: ${PROJ_ID}" \
  -d @- <<EOF | jq -r --unbuffered 'if type == "array" then .[] else . end | select(.content.parts != null) | .content.parts[].text // empty'
{
  "input": {
    "message": "what are bob johnson's and alice brown's email addresses?",
    "user_id": "test-user"
  }
}
EOF

Журналы аудита

Просмотреть журналы трассировки

При включенной телеметрии Agent Runtime передает структурированные события, представляющие запросы пользователей, параметры инструментов, схемы выполнения и результаты выбора модели.

# show agent runtime (reasoning engine) telemetry and trace logs
gcloud logging read \
  "logName:\"projects/${PROJ_ID}/logs/aiplatform.googleapis.com%2Freasoning_engine_stdout\" AND labels.managed-by=\"reasoning-engine\"" \
  --project=${PROJ_ID} \
  --limit=15 \
  --format="table(
    timestamp.date(format=\"%I:%M:%S %p\", tz=LOCAL):label=TIME,
    trace.basename().sub('^(.{8}).*$', '\\1'):label=TRACE_ID,
    labels.\"event.name\".scope(-1):label=EVENT,
    jsonPayload.content.role:label=ROLE,
    jsonPayload.content.parts[0].text:label=TEXT_CONTENT,
    jsonPayload.content.parts[0].function_call.name:label=TOOL_CALL
  )"

Параметр TRACE_ID объединяет пользовательский запрос, промежуточные вызовы инструментов и решения модели в единую временную шкалу:

TIME         TRACE_ID  EVENT                  ROLE   TEXT_CONTENT                                     TOOL_CALL
HH:MM:SS PM  3070a1fd  gen_ai.choice          model  Bob Johnson's SSN is 219-45-7895.
                                                     Alice Brown's SSN is 219-45-7896.
HH:MM:SS PM  3070a1fd  gen_ai.user.message    user
HH:MM:SS PM  3070a1fd  gen_ai.user.message    model                                                   read_customer_file
HH:MM:SS PM  3070a1fd  gen_ai.user.message    user
HH:MM:SS PM  3070a1fd  gen_ai.user.message    model                                                   read_customer_file
HH:MM:SS PM  3070a1fd  gen_ai.user.message    user
HH:MM:SS PM  3070a1fd  gen_ai.user.message    model                                                   list_customer_files
HH:MM:SS PM  3070a1fd  gen_ai.user.message    user   what are ssn's for bob johnson and alice brown?
HH:MM:SS PM  3070a1fd  gen_ai.system.message
HH:MM:SS PM  3070a1fd  gen_ai.choice          model                                                   read_customer_file

Просмотрите журналы дезинфекции Model Armor.

Эти журналы показывают в реальном времени двунаправленную обработку угроз и очистку данных, выполняемую Model Armor по мере прохождения трафика через Agent Gateway.

# show model armor logs
gcloud logging read \
  "logName:\"projects/${PROJ_ID}/logs/modelarmor.googleapis.com%2Fsanitize_operations\"" \
  --project=${PROJ_ID} \
  --limit=50 \
  --format="table(
    timestamp.date(format=\"%I:%M:%S %p\", tz=LOCAL):label=TIME,
    jsonPayload.sanitizationResult.sanitizationVerdict:label=VERDICT,
    jsonPayload.sanitizationInput.byteItem.byteData.decode(base64).decode(utf-8).sub('\n', ' \\\\\\\\n ').trailoff(123):label=INPUT_DATA
  )"

Обратите внимание на запись в журнале для очищенного и заблокированного запроса.

TIME         VERDICT                                 INPUT_DATA
HH:MM:SS PM  MODEL_ARMOR_SANITIZATION_VERDICT_ALLOW  Bob Johnson's email address is bob.j@example.com. \n Alice Brown's email address is alice.b...
HH:MM:SS PM  MODEL_ARMOR_SANITIZATION_VERDICT_ALLOW  what are bob johnson's and alice brown's email addresses?
HH:MM:SS PM  MODEL_ARMOR_SANITIZATION_VERDICT_BLOCK  6��
HH:MM:SS PM  MODEL_ARMOR_SANITIZATION_VERDICT_ALLOW  what are ssn's for bob johnson and alice brown?
HH:MM:SS PM  MODEL_ARMOR_SANITIZATION_VERDICT_ALLOW  Our west customers are: Bob Johnson and Alice Brown.
HH:MM:SS PM  MODEL_ARMOR_SANITIZATION_VERDICT_ALLOW  what are the names of our west customers?

На этом завершается раздел тестирования... далее переходим к разделу очистки .

10. Уборка

# remove agent iam bindings
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_IDENTITY}" --role="roles/storage.objectViewer"
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_IDENTITY}" --role="roles/aiplatform.user"
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_IDENTITY}" --role="roles/cloudtrace.agent"
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_IDENTITY}" --role="roles/monitoring.metricWriter"

# next
# remove more agent and agent set iam bindings
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_IDENTITY}" --role="roles/logging.logWriter"
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_IDENTITY}" --role="roles/telemetry.writer"
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_IDENTITY}" --role="roles/serviceusage.serviceUsageConsumer"
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_IDENTITY}" --role="roles/browser"

# next
# remove rest of iam bindings
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_ID_SET}" --role="roles/mcp.toolUser"
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="serviceAccount:service-${PROJ_NO}@gcp-sa-modelarmor.iam.gserviceaccount.com" --role="roles/dlp.user"

# next
# delete agent runtime (reasoning engine) agent
curl -s -X DELETE "https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}?force=true" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "Content-Type: application/json"

# next
# delete storage
gcloud -q storage rm --recursive gs://${STAGING_BUCKET}
gcloud -q storage rm --recursive gs://${DATA_BUCKET}

# next
# delete authz resources
gcloud -q beta network-security authz-policies delete ${AGW_NAME}-authz-policy-modar --location=${REGION}

gcloud -q beta service-extensions authz-extensions delete ${AGW_NAME}-svc-ext-authz-modar --location=${REGION} --async

# next
# remove dep (service extensions) service agent iam bindings
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} \
  --member="serviceAccount:service-${PROJ_NO}@gcp-sa-dep.iam.gserviceaccount.com" \
  --role="roles/modelarmor.calloutUser"

gcloud -q projects remove-iam-policy-binding ${PROJ_ID} \
  --member="serviceAccount:service-${PROJ_NO}@gcp-sa-dep.iam.gserviceaccount.com" \
  --role="roles/serviceusage.serviceUsageConsumer"

gcloud -q projects remove-iam-policy-binding ${PROJ_ID} \
  --member="serviceAccount:service-${PROJ_NO}@gcp-sa-dep.iam.gserviceaccount.com" \
  --role="roles/modelarmor.user"

# next
# delete model armor templates
gcloud -q model-armor templates delete ${AGW_NAME}-modar-resp-template --location=${REGION}
gcloud -q model-armor templates delete ${AGW_NAME}-modar-req-template --location=${REGION}

# unset model armor api endpoint override
gcloud config unset api_endpoint_overrides/modelarmor

# next
# delete sdp (dlp) templates
curl -fsS -X DELETE "https://dlp.googleapis.com/v2/projects/${PROJ_ID}/locations/${REGION}/deidentifyTemplates/agw-ssn-redaction-template" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "x-goog-user-project: ${PROJ_ID}"

curl -fsS -X DELETE "https://dlp.googleapis.com/v2/projects/${PROJ_ID}/locations/${REGION}/inspectTemplates/agw-ssn-inspect-template" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "x-goog-user-project: ${PROJ_ID}"

# next
# delete agent gateway ingress
gcloud -q network-services agent-gateways delete ${AGW_NAME} --location=${REGION} --async

# end

На этом завершается этап очистки... далее переходим к разделу «Заключение» .

11. Заключение

Поздравляем! Вы успешно развернули Agent Gateway и настроили входящий трафик для ИИ-агента!

космопап

Cosmopup считает, что Codelabs — это просто замечательно!

Что дальше?

Пожалуйста, оставляйте свои комментарии, вопросы или замечания, используя эту форму обратной связи .

Спасибо!