1. Введение
По мере внедрения генеративного ИИ в организациях архитектуры быстро эволюционируют от автономных монолитных чат-ботов к распределенным многоагентным системам (Agent-to-Agent / A2A) . В этих современных топологиях высокоуровневые агенты-оркестраторы координируют сложные бизнес-процессы, делегируя задачи специализированным агентам-обработчикам, серверам инструментов Model Context Protocol (MCP) и внутренним корпоративным базам данных в рамках независимых проектов Google Cloud.
Однако масштабируемая эксплуатация многоагентных систем влечет за собой серьезные проблемы в области безопасности, управления и функционирования:
- Распространение теневых агентов и инструментов: Когда команды разработчиков развертывают агентов в изолированных проектах без централизованного каталога, организации теряют представление о том, какие инструменты и субагенты существуют.
- Неконтролируемый исходящий трафик между проектами: предоставление агентам возможности использовать прямые, непроверяемые сетевые маршруты создает риски утечки данных и обходит периметры безопасности.
- Хрупкие жестко закодированные интеграции: Жесткое кодирование URL-адресов агентов и идентификаторов механизмов вывода создает ненадежные зависимости, которые могут нарушиться при обновлениях или повторном развертывании.
- Отсутствие принципа наименьших привилегий при идентификации: общие учетные записи служб не обеспечивают криптографическую неопровержимость на уровне отдельных экземпляров агентов.
Для решения этих задач платформа Gemini Enterprise Agent Platform предоставляет единую плоскость управления и контроля подключения, состоящую из четырех основных компонентов:
- Agent Gateway (
networkservices.googleapis.com) : управляемый региональный прокси-сервер для управления сетью и обеспечения соблюдения политик. Работая в режиме исходящего трафикаAGENT_TO_ANYWHERE, он перехватывает исходящий трафик агентов, делегирует оценку авторизации расширениям безопасности и направляет запросы через периметр проекта. - Agent Registry (
agentregistry.googleapis.com) : Единый корпоративный каталог сервисов. Он предоставляет централизованный, проверенный каталог всех доступных инструментов, серверов MCP и агентов-партнеров в масштабах всей организации, обеспечивая динамическое автоматическое обнаружение в режиме реального времени без каких-либо жестко заданных конечных точек. - Идентификация агентов и управление IAP v2 (
iap.googleapis.comиiam.googleapis.com) : криптографическая система идентификации и доступа. Выполняющие агенты получают уникальные, подтвержденные URN машин SPIFFE (principal://...). Исходящий трафик проверяется на соответствие централизованным унифицированным политикам доступа IAM (UAP/IAP v2), подтверждающим универсальное разрешениеiap.googleapis.com/resources.egressViaIAPс использованием расширенных условий каталога Common Expression Language (CEL) (destination.agent_registry.*). - Agent Runtime (Reasoning Engines) : Полностью управляемая бессерверная платформа выполнения для агентских приложений на основе Python, включающая собственные привязки конфигурации (
agent_gateway_config) к центральным шлюзам.
Бизнес-сценарий Codelab: Закупки продуктов питания и напитков в рамках нескольких проектов
В этом практическом занятии вы создадите и будете управлять реальной экосистемой закупок для нескольких проектов, охватывающей три отдельных проекта Google Cloud:
- Проект централизованного управления (
PROJECT_GOVERNANCE): находится в ведении центрального ИТ-отдела и отдела безопасности, включает в себя центральный шлюз агентов, центральный реестр агентов и унифицированные политики доступа IAM. - Проект «Организатор потребительских процессов» (
PROJECT_CONCIERGE): находится в ведении отдела закупок и включает в себя агента по организации закупок , который динамически находит поставщиков и направляет заказы клиентов. - Проект поставщика домена (
PROJECT_SELLERS): Принадлежит внешним или ведомственным поставщикам и размещает агенты для продавцов бургеров и пиццы .
Рис. 1. Архитектура централизованного управления несколькими проектами.
Почему необходимо централизованное управление всеми проектами?
В крупных корпоративных организациях продуктовые команды и группы анализа данных создают агентов ИИ в рамках десятков независимых проектов Google Cloud. Предоставление каждой команде прямого контроля над регистрацией инструментов, исходящими сетевыми маршрутами и механизмами безопасности приводит к неконтролируемому разрастанию инструментов, непоследовательным политикам DLP, неконтролируемому исходящему трафику VPC и фрагментированным журналам аудита.
Централизованное управление в рамках всего проекта разделяет разработку политик и их выполнение агентами:
- Централизованное управление ИТ-инфраструктурой и службой безопасности разрабатывает политики безопасности, проверяет инструменты и отслеживает исходящий трафик в рамках единого проекта централизованного управления .
- В своих независимых проектах по разработке среды выполнения агентов команды разработчиков и приложений сосредотачиваются исключительно на бизнес-логике, напрямую подключаясь к центральному шлюзу без операционных издержек, связанных с управлением локальными VPC, межсетевыми соединениями или разрозненными механизмами политик.
Рис. 2. Трехуровневая архитектура управления проектами и ее границы.
Двухуровневая модель определения области действия идентификации в унифицированных политиках доступа
Когда агенты взаимодействуют через Центральный шлюз агентов, Identity-Aware Proxy (IAP v2) оценивает доступ на основе идентификатора агента вызывающего абонента — криптографически подтвержденного идентификатора на основе SPIFFE, автоматически выдаваемого контейнеру среды выполнения, — в соответствии с глобальной политикой доступа IAM:
- Уровень 1: Базовые API Google Cloud (крупномасштабные через
principalSet://в Правиле 1): Авторизация исходящего трафика в масштабе всего проекта, позволяющая всем средам выполнения агентов в периферийных проектах обращаться к стандартным API Google (aiplatform,iamcredentials,telemetry,agentregistry) для обнаружения, генерации токенов и вывода информации. - Уровень 2: Бизнес-инструменты и сервисы A2A (детальная настройка через
principal://в правилах 2 и 3): Строгий доступ с минимальными привилегиями, привязанный к отдельным экземплярам механизма рассуждений, обеспечиваемый условиями Common Expression Language (CEL), нацеленными на конкретные зарегистрированные сервисы реестра агентов (destination.agent_registry.agent.name).
Что вы строите
- Централизованный шлюз агентов (
centralized-agw) вPROJECT_GOVERNANCE - Расширение службы авторизации IAP v2 и политика авторизации в строгом режиме ENFORCE (
failOpen: false) - Базовая политика унифицированного доступа IAM (
uap-rules.json) и привязка политик проекта. - Разрешения IAM для агентов межпроектных сервисов (
ar_agw_cross_project_sa) - Общий централизованный промежуточный сегмент Google Cloud Storage (GCS).
- Изолированные агенты по продаже бургеров и пиццы в
PROJECT_SELLERS - В проекте
PROJECT_CONCIERGEреализована функция «Приобретение консьерж-агента с динамическим REST-автообнаружением». - Регистрация сервисов в Центральном реестре агентов с использованием межпроектных mTLS-URL-адресов
- Динамические обновления политики исходящего трафика IAP v2 с проверкой в реальном времени и аудитом в Cloud Logging.
Рис. 3. Пошаговая последовательность реализации.
Чему вы научитесь
- Как настроить разрешения IAM для агентов сервисов, работающих в разных проектах, для централизованных шлюзов.
- Как направлять исходящий трафик Agent Runtime через центральный шлюз Agent Gateway в многопроектных средах
- Как делегировать авторизацию Agent Gateway прокси-серверу с поддержкой идентификации (IAP v2) с помощью расширений службы (
iapPolicyVersion: "V2") - Как создавать и связывать политики унифицированного доступа IAM (UAP) с правилами Common Expression Language (CEL), регулирующими зарегистрированные целевые объекты реестра агентов (
destination.agent_registry.*). - Как исключить использование жестко закодированных идентификаторов и URL-адресов агентов при автоматическом обнаружении во время выполнения с помощью реестра агентов.
- Как протестировать блокировку с нулевым доверием на реальном периметре (
HTTP 403 Forbidden) и проверить обновления политик в режиме реального времени в Cloud Logging.
Что вам нужно
- 3 проекта Google Cloud с включенной функцией выставления счетов:
-
PROJECT_GOVERNANCE: Централизованное управление, шлюз, реестр и политики доступа IAM. -
PROJECT_CONCIERGE: Агент по организации консьерж-услуг в сфере закупок -
PROJECT_SELLERS: Агенты по продаже бургеров и пиццы.
-
- Пользователь или сервисная учетная запись IAM с
roles/ownerили административными правами во всех 3 проектах. - Организация Google Cloud (для сопоставления доменов доверия SPIFFE)
- Google Cloud Shell или локальный компьютер с установленными
gcloudCLI,python(версия 3.11 и выше) иuv
На этом вводная часть завершается... далее переходим к разделу «Настройка и среда» .
2. Настройка
Несмотря на то, что эта архитектура охватывает 3 отдельных проекта Google Cloud, вы можете выполнять 100% команд развертывания, загрузки репозиториев и операций подготовки из одного терминала Cloud Shell, настроенного на PROJECT_GOVERNANCE . Каждый скрипт развертывания и команда gcloud явно указывают на соответствующий целевой проект с помощью флагов CLI ( --project ).
Для начала откройте командную строку вашего проекта Google Cloud:
- Cloud Shell доступен по адресу
shell.cloud.google.comили - Локальный терминал с установленным интерфейсом командной строки
gcloud
Укажите контекст вашего проекта
# set terminal project context to Central Governance Project
gcloud config set project SET_YOUR_GOVERNANCE_PROJECT_ID_HERE
# login to gcloud cli
gcloud auth login
# login for application default credentials
gcloud auth application-default login
Обновите интерфейс командной строки gcloud (рекомендуется).
# update gcloud components
gcloud components update --quiet
Установка переменных среды оболочки
Введите идентификаторы, относящиеся к вашему проекту.
# 1. Project Identifiers
export PROJECT_GOVERNANCE="SET_YOUR_GOVERNANCE_PROJECT_ID_HERE"
export PROJECT_CONCIERGE="SET_YOUR_CONCIERGE_PROJECT_ID_HERE"
export PROJECT_SELLERS="SET_YOUR_SELLERS_PROJECT_ID_HERE"
Эти переменные оболочки будут вычислены автоматически.
# 2. Regional & Gateway Settings
export REGION="us-central1"
export AGW_NAME="centralized-agw"
export UAP_POLICY_NAME="uap-policy-${AGW_NAME}"
export UAP_BINDING_NAME="uap-binding-${AGW_NAME}"
# 3. Retrieve Project Numbers
export PROJECT_NUMBER_GOVERNANCE=$(gcloud projects describe ${PROJECT_GOVERNANCE} --format="value(projectNumber)")
export PROJECT_NUMBER_CONCIERGE=$(gcloud projects describe ${PROJECT_CONCIERGE} --format="value(projectNumber)")
export PROJECT_NUMBER_SELLERS=$(gcloud projects describe ${PROJECT_SELLERS} --format="value(projectNumber)")
# 4. Obtain Organization ID
export ORG_ID=$(gcloud projects get-ancestors ${PROJECT_GOVERNANCE} --format="value(id, type)" | grep organization | awk '{print $1}')
# 5. Set Application Default Credentials (ADC) Quota Project
gcloud auth application-default set-quota-project ${PROJECT_GOVERNANCE}
echo "Governance Project: ${PROJECT_GOVERNANCE} (${PROJECT_NUMBER_GOVERNANCE})"
echo "Concierge Project: ${PROJECT_CONCIERGE} (${PROJECT_NUMBER_CONCIERGE})"
echo "Sellers Project: ${PROJECT_SELLERS} (${PROJECT_NUMBER_SELLERS})"
echo "Organization ID: ${ORG_ID}"
echo "UAP Policy Name: ${UAP_POLICY_NAME}"
echo "UAP Binding Name: ${UAP_BINDING_NAME}"
Создайте локальную директорию для файлов конфигурации.
# create config folder
mkdir -p cfg
Назначьте роль администратора политики доступа для унифицированных политик доступа.
# grant Access Policy Admin and Project IAM Admin to current user in Governance Project
for ROLE in "roles/iam.accessPolicyAdmin" "roles/resourcemanager.projectIamAdmin"; do
gcloud projects add-iam-policy-binding ${PROJECT_GOVERNANCE} \
--member="user:$(gcloud config get-value account)" \
--role="${ROLE}" \
--condition=None
done
Включите журналы доступа к данным аудита облака для IAP v2.
По умолчанию Google Cloud отключает журналы аудита доступа к данным, чтобы предотвратить непредвиденные расходы на хранение. Поскольку IAP v2 отправляет решения об авторизации ( granted=true и granted=false ) в виде журналов аудита доступа к данным, включите ведение журналов ADMIN_READ , DATA_READ и DATA_WRITE для iap.googleapis.com в PROJECT_GOVERNANCE :
# 1. export current IAM policy for PROJECT_GOVERNANCE
gcloud projects get-iam-policy ${PROJECT_GOVERNANCE} \
--format=json > cfg/gov_iam_policy.json
# 2. append auditConfigs for iap.googleapis.com
python3 -c "
import json
with open('cfg/gov_iam_policy.json') as f:
policy = json.load(f)
audit_configs = [c for c in policy.get('auditConfigs', []) if c.get('service') != 'iap.googleapis.com']
audit_configs.append({
'service': 'iap.googleapis.com',
'auditLogConfigs': [
{'logType': 'ADMIN_READ'},
{'logType': 'DATA_READ'},
{'logType': 'DATA_WRITE'}
]
})
policy['auditConfigs'] = audit_configs
with open('cfg/gov_iam_policy.json', 'w') as f:
json.dump(policy, f, indent=2)
"
# 3. apply updated policy
gcloud projects set-iam-policy ${PROJECT_GOVERNANCE} cfg/gov_iam_policy.json
# 4. verify auditConfigs applied
gcloud projects get-iam-policy ${PROJECT_GOVERNANCE} --format="yaml(auditConfigs)"
Включите необходимые API Google Cloud.
# enable google apis (agent platform & security bundle, part 1)
for PROJ in ${PROJECT_GOVERNANCE} ${PROJECT_CONCIERGE} ${PROJECT_SELLERS}; do
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 \
agentidentity.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 \
--project=${PROJ}
done
# enable google apis (agent platform bundle, part 2)
for PROJ in ${PROJECT_GOVERNANCE} ${PROJECT_CONCIERGE} ${PROJECT_SELLERS}; do
gcloud services enable \
securitycenter.googleapis.com \
saasservicemgmt.googleapis.com \
storage.googleapis.com \
telemetry.googleapis.com \
texttospeech.googleapis.com \
--project=${PROJ}
done
# enable google apis (foundational & agent runtime build bundle, part 3)
for PROJ in ${PROJECT_GOVERNANCE} ${PROJECT_CONCIERGE} ${PROJECT_SELLERS}; do
gcloud services enable \
artifactregistry.googleapis.com \
cloudbuild.googleapis.com \
cloudresourcemanager.googleapis.com \
iamcredentials.googleapis.com \
serviceusage.googleapis.com \
run.googleapis.com \
orgpolicy.googleapis.com \
--project=${PROJ}
done
Проверьте включение API во всех проектах.
Обеспечение того, чтобы во всех трех проектах ( PROJECT_GOVERNANCE , PROJECT_CONCIERGE и PROJECT_SELLERS ) были включены абсолютно одинаковые API, обеспечивает операционную согласованность и предотвращает сбои при создании токенов во время выполнения, ошибки каталогизации схемы или потери телеметрии.
Запустите следующий скрипт проверки в Cloud Shell, чтобы убедиться в единообразии API во всех трех проектах:
# validate that all required APIs are enabled across all 3 projects
python3 - << 'EOF'
import subprocess
import os
import sys
REQUIRED_APIS = [
"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",
"agentidentity.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",
"securitycenter.googleapis.com",
"saasservicemgmt.googleapis.com",
"storage.googleapis.com",
"telemetry.googleapis.com",
"texttospeech.googleapis.com",
"artifactregistry.googleapis.com",
"cloudbuild.googleapis.com",
"cloudresourcemanager.googleapis.com",
"iamcredentials.googleapis.com",
"serviceusage.googleapis.com",
"run.googleapis.com",
"orgpolicy.googleapis.com"
]
projects = {
"GOVERNANCE": os.environ.get("PROJECT_GOVERNANCE", ""),
"CONCIERGE": os.environ.get("PROJECT_CONCIERGE", ""),
"SELLERS": os.environ.get("PROJECT_SELLERS", "")
}
enabled = {}
for role, proj in projects.items():
if not proj:
print(f"Error: Environment variable for {role} is not set.")
sys.exit(1)
res = subprocess.run(
["gcloud", "services", "list", "--enabled", f"--project={proj}", "--format=value(config.name)"],
capture_output=True, text=True, check=True
)
enabled[role] = set(res.stdout.strip().splitlines())
print(f"\n{'API Name':<36} | {'GOVERNANCE':<12} | {'CONCIERGE':<12} | {'SELLERS':<12}")
print("-" * 78)
all_synced = True
for api in REQUIRED_APIS:
g_status = "ENABLED" if api in enabled["GOVERNANCE"] else "MISSING"
c_status = "ENABLED" if api in enabled["CONCIERGE"] else "MISSING"
s_status = "ENABLED" if api in enabled["SELLERS"] else "MISSING"
if "MISSING" in (g_status, c_status, s_status):
all_synced = False
print(f"{api:<36} | {g_status:<12} | {c_status:<12} | {s_status:<12}")
print("-" * 78)
if all_synced:
print("✅ All 29 required APIs are ENABLED and synchronized across all three projects.\n")
else:
print("❌ Discrepancies detected. Please re-run the enablement commands for missing services.\n")
sys.exit(1)
EOF
Пример выходных данных проверки:
Вы должны увидеть, что все API включены.
✅ All 30 required APIs are ENABLED and synchronized across all three projects.
Настройка организационных политик
Политики организации Google Cloud по умолчанию устанавливают ограничения, которые ограничивают привязку политик доступа IAM v3 к ресурсам ( constraints/iam.managed.disableAccessPolicyBinding ).
Отмените любые унаследованные ограничения политики организации на уровне проекта, явно установив параметр enforce: false в значение allow.
# disable iam v3 constraint (allow v3 access policies)
gcloud org-policies set-policy /dev/stdin << EOF
name: projects/${PROJECT_NUMBER_GOVERNANCE}/policies/iam.managed.disableAccessPolicyBinding
spec:
rules:
- enforce: false
EOF
# verify org policy constraints on project
gcloud org-policies describe iam.managed.disableAccessPolicyBinding \
--project=${PROJECT_GOVERNANCE} --effective
На этом завершается этап настройки... далее переходим к разделу «Регистрация основных API Google» .
3. Реестр агентов
Регистрация службы конечных точек основных API Google
Для работы Agent Gateway необходимо зарегистрировать URL-адреса Google API в Центральном реестре агентов, чтобы агенты, настроенные с помощью agent_gateway_config , могли безопасно направлять исходящий трафик к основным серверным службам Google Cloud (таким как aiplatform , учетные данные IAM и телеметрия).
Создайте core-gapi-services в реестре агентов.
# register core google api endpoints in agent registry with standard and :443 port variants
gcloud agent-registry services create core-gapi-services \
--project=${PROJECT_GOVERNANCE} \
--location=${REGION} \
--display-name="gapi.core.services" \
--description="Core Google Cloud APIs and Service Endpoints" \
--endpoint-spec-type=no-spec \
--interfaces=protocolBinding=JSONRPC,url=https://telemetry.googleapis.com \
--interfaces=protocolBinding=JSONRPC,url=https://telemetry.mtls.googleapis.com \
--interfaces=protocolBinding=JSONRPC,url=https://${REGION}-aiplatform.googleapis.com \
--interfaces=protocolBinding=JSONRPC,url=https://${REGION}-aiplatform.googleapis.com:443 \
--interfaces=protocolBinding=JSONRPC,url=https://${REGION}-aiplatform.mtls.googleapis.com \
--interfaces=protocolBinding=JSONRPC,url=https://${REGION}-aiplatform.mtls.googleapis.com:443 \
--interfaces=protocolBinding=JSONRPC,url=https://aiplatform.googleapis.com \
--interfaces=protocolBinding=JSONRPC,url=https://aiplatform.googleapis.com:443 \
--interfaces=protocolBinding=JSONRPC,url=https://aiplatform.mtls.googleapis.com \
--interfaces=protocolBinding=JSONRPC,url=https://aiplatform.mtls.googleapis.com:443 \
--interfaces=protocolBinding=JSONRPC,url=https://cloudresourcemanager.googleapis.com \
--interfaces=protocolBinding=JSONRPC,url=https://iamcredentials.googleapis.com \
--interfaces=protocolBinding=JSONRPC,url=https://iamcredentials.mtls.googleapis.com \
--interfaces=protocolBinding=JSONRPC,url=https://agentregistry.googleapis.com \
--interfaces=protocolBinding=JSONRPC,url=https://agentregistry.mtls.googleapis.com \
--interfaces=protocolBinding=JSONRPC,url=https://agentregistry.googleapis.com:443 \
--interfaces=protocolBinding=JSONRPC,url=https://agentregistry.mtls.googleapis.com:443
Получение идентификатора ресурса конечной точки основных API.
# capture the underlying Agent Registry endpoint ID
export ENDPOINT_ID=$(gcloud agent-registry services describe core-gapi-services \
--project=${PROJECT_GOVERNANCE} \
--location=${REGION} \
--format="value(registryResource)" | awk -F'/' '{print $NF}')
echo "Core APIs Endpoint ID: ${ENDPOINT_ID}"
Понимание различий между principalSet и principal в идентификации агента.
В Google Cloud IAM и Gemini Enterprise Agent Platform идентификаторы машин, выдаваемые исполняемым контейнерам агентов, используют криптографически подтвержденные SPIFFE URN, оцениваемые Identity-Aware Proxy (IAP v2). При настройке унифицированных политик доступа IAM можно выбрать либо конкретный principal , либо principalSet на основе атрибутов:
Измерение | | |
Синтаксис IAM | | |
Гранулярность | Детальная идентификация (на уровне экземпляра): определяет конкретный экземпляр контейнера механизма рассуждений. | Крупномасштабный (на уровне проекта): определяет все механизмы рассуждений, имеющие общий атрибут проекта. |
Узор для урны | | |
Вариант использования в агентской платформе | Уровень 2 (Бизнес-инструменты и A2A): Авторизация конкретных агентов оркестратора для вызова инструментов целевого домена (например, «Консьерж по закупкам» > «Продавец бургеров»). | Уровень 1 (Базовая инфраструктура): Предоставление всем агентам в проекте исходящего доступа к API Google Cloud ( |
Влияние на жизненный цикл | Если агент удаляется и создается заново, для его нового идентификатора движка потребуется обновить привязку политики IAM. | Автоматически применяется к новым агентам, развернутым в этом проекте, без дополнительных обновлений IAM. |
Декларативное управление с использованием унифицированных политик доступа (UAP / IAP v2)
В устаревшей версии IAP v1 политики исходящего трафика прикреплялись непосредственно к отдельным ресурсам реестра агентов с помощью gcloud beta iap web add-iam-policy-binding . В версии IAP v2 и с использованием унифицированных политик доступа привязки для каждого ресурса исключены в пользу единой централизованной политики доступа IAM ( cfg/uap-rules.json ).
Базовая авторизация исходящего трафика для core-gapi-services будет настроена как Правило 1 в Единой политике доступа в Разделе 5, что гарантирует наличие базовых маршрутов исходящего трафика для всех контейнеров агентов до развертывания.
Для получения более подробной технической информации об идентификаторах субъектов и механизмах идентификации рабочих нагрузок см.:
- Google Cloud IAM: идентификаторы и наборы основных элементов.
- Как работает идентификация агента
- Настройка политик унифицированного доступа IAM для Agent Gateway
На этом завершается регистрация основных конечных точек API... далее переходим к разделу «Развертывание централизованного шлюза агентов» .
4. Шлюз агентов
Разверните централизованный шлюз агентов.
Разверните централизованный шлюз агентов ( centralized-agw ) в режиме исходящего трафика AGENT_TO_ANYWHERE внутри проекта $PROJECT_GOVERNANCE .
Определение манифеста конфигурации шлюза
Создайте cfg/${AGW_NAME}.yaml для управления исходящим трафиком:
# generate agent gateway config yaml
cat > cfg/${AGW_NAME}.yaml << EOF
name: ${AGW_NAME}
protocols:
- MCP
googleManaged:
governedAccessPath: AGENT_TO_ANYWHERE
registries:
- "//agentregistry.googleapis.com/projects/${PROJECT_GOVERNANCE}/locations/${REGION}"
EOF
Настройка шлюза агента импорта
# import and create agent gateway
gcloud network-services agent-gateways import ${AGW_NAME} \
--source="cfg/${AGW_NAME}.yaml" \
--location=${REGION} \
--project=${PROJECT_GOVERNANCE}
Проверьте данные шлюза агента.
# show agent gateway status
gcloud network-services agent-gateways describe ${AGW_NAME} \
--location=${REGION} \
--project=${PROJECT_GOVERNANCE}
Пример выходных данных:
agentGatewayCard:
mtlsEndpoint: projects/${AGW_TP_ID}/regions/us-central1/serviceAttachments/unitkind1-swp-mtls-psc-sa
rootCertificates:
- |
-----BEGIN CERTIFICATE-----
MIIDwzCCAqugAwIBAgITNQuWGopdOZaHdcK7r7AYFhonqDANBgkqhkiG9w0BAQsF
...
-----END CERTIFICATE-----
serviceExtensionsServiceAccount: service-${PROJ_NO}@gcp-sa-dep.iam.gserviceaccount.com
createTime: 'YYYY-MM-DDT12:34:56.789098765Z'
googleManaged:
governedAccessPath: AGENT_TO_ANYWHERE
name: projects/${PROJECT_GOVERNANCE}/locations/us-central1/agentGateways/centralized-agw
protocols:
- MCP
registries:
- //agentregistry.googleapis.com/projects/${PROJECT_GOVERNANCE}/locations/us-central1
updateTime: 'YYYY-MM-DDT12:34:56.789098765Z'
На этом развертывание шлюза завершено... далее переходим к разделу «Настройка авторизации» .
5. Авторизация
Настройка авторизации шлюза агентов и базового UAP.
Шлюз агентов обеспечивает безопасность и управление исходящим трафиком инструментов и агентов с помощью политик авторизации ( networksecurity.authzPolicies ), интегрированных с политиками унифицированного доступа (UAP) Identity-Aware Proxy (IAP v2) .
Обзор архитектуры авторизации
Рис. 4. Обзор архитектуры авторизации
Архитектура авторизации состоит из трех взаимосвязанных уровней:
- Расширение службы IAP (
authzExtension) : Региональный ресурс, настроенный с использованиемservice: iap.googleapis.com,metadata: iapPolicyVersion: "V2"иfailOpen: falseдля строгого обеспечения нулевого доверия на периметре сети. - Политика авторизации шлюза (
authzPolicy) : Региональный ресурс, нацеленный на ваш шлюз агента сpolicyProfile: REQUEST_AUTHZиaction: CUSTOM, перенаправляющий проверки авторизации в расширение IAP Authz. - Единая политика доступа и привязка IAM (
accessPolicy&policyBinding) : глобальный ресурс IAM v3, оцениваемый IAP. Он проверяет универсальное разрешениеiap.googleapis.com/resources.egressViaIAPна соответствие идентификаторам SPIFFE вызывающего абонента и условиям каталога CEL.
Шаг 1: Создайте и импортируйте расширение аутентификации IAP v2.
Создайте манифест расширения службы с iapPolicyVersion: "V2" и failOpen: false в строгом режиме ENFORCE :
# create authz extension config file in ENFORCE mode
cat > cfg/${AGW_NAME}-svc-ext-authz-iap.yaml << EOF
name: ${AGW_NAME}-svc-ext-authz-iap
service: iap.googleapis.com
failOpen: false
timeout: 1s
metadata:
iapPolicyVersion: "V2"
EOF
Импортируйте расширение Authz:
# import IAP v2 authz extension
gcloud service-extensions authz-extensions import ${AGW_NAME}-svc-ext-authz-iap \
--source=cfg/${AGW_NAME}-svc-ext-authz-iap.yaml \
--location=${REGION} \
--project=${PROJECT_GOVERNANCE}
Убедитесь, что расширение Authz активно:
# describe authz extension
gcloud service-extensions authz-extensions describe ${AGW_NAME}-svc-ext-authz-iap \
--location=${REGION} \
--project=${PROJECT_GOVERNANCE}
Пример выходных данных:
createTime: 'YYYY-MM-DDT12:34:56.789098765Z'
failOpen: false
metadata:
iapPolicyVersion: V2
name: projects/${PROJECT_GOVERNANCE}/locations/us-central1/authzExtensions/centralized-agw-svc-ext-authz-iap
service: iap.googleapis.com
timeout: 1s
Шаг 2: Создание и импорт политики авторизации шлюза.
Создайте конфигурацию политики авторизации, которая подключается к шлюзу агентов и делегирует проверку запросов расширению аутентификации IAP:
# create authz policy manifest
cat > cfg/${AGW_NAME}-authz-policy-profile-iap.yaml << EOF
name: ${AGW_NAME}-authz-policy-profile-iap
target:
resources:
- "projects/${PROJECT_GOVERNANCE}/locations/${REGION}/agentGateways/${AGW_NAME}"
policyProfile: REQUEST_AUTHZ
action: CUSTOM
customProvider:
authzExtension:
resources:
- "projects/${PROJECT_GOVERNANCE}/locations/${REGION}/authzExtensions/${AGW_NAME}-svc-ext-authz-iap"
EOF
Импортируйте политику авторизации:
# import authz policy
gcloud beta network-security authz-policies import ${AGW_NAME}-authz-policy-profile-iap \
--source=cfg/${AGW_NAME}-authz-policy-profile-iap.yaml \
--location=${REGION} \
--project=${PROJECT_GOVERNANCE}
Проверьте наличие активной политики авторизации:
# describe authz policy
gcloud beta network-security authz-policies describe ${AGW_NAME}-authz-policy-profile-iap \
--location=${REGION} \
--project=${PROJECT_GOVERNANCE}
Шаг 3: Разработка первоначальной унифицированной политики доступа (Правило 1: Основные API Google)
Создайте файл cfg/uap-rules.json , добавив правило 1, разрешающее трем principalSet проектов доступ к core-gapi-services :
# create initial unified access policy rules manifest
cat > cfg/uap-rules.json << EOF
[
{
"description": "Rule 1: Allow agent runtimes across all 3 projects to reach Core Google APIs",
"effect": "ALLOW",
"principals": [
"principalSet://agents.global.org-${ORG_ID}.system.id.goog/attribute.platformContainer/aiplatform/projects/${PROJECT_NUMBER_GOVERNANCE}",
"principalSet://agents.global.org-${ORG_ID}.system.id.goog/attribute.platformContainer/aiplatform/projects/${PROJECT_NUMBER_CONCIERGE}",
"principalSet://agents.global.org-${ORG_ID}.system.id.goog/attribute.platformContainer/aiplatform/projects/${PROJECT_NUMBER_SELLERS}"
],
"operation": {
"permissions": [
"iap.googleapis.com/resources.egressViaIAP"
]
},
"conditions": {
"iap.googleapis.com": {
"expression": \
"destination.is_registered == true && \
destination.agent_registry.resource_type == 'ENDPOINT' && ( \
destination.agent_registry.endpoint.name == 'projects/${PROJECT_GOVERNANCE}/locations/${REGION}/endpoints/core-gapi-services' || \
destination.agent_registry.endpoint.name == 'projects/${PROJECT_GOVERNANCE}/locations/${REGION}/endpoints/${ENDPOINT_ID}' || \
destination.agent_registry.endpoint.name == 'projects/${PROJECT_NUMBER_GOVERNANCE}/locations/${REGION}/endpoints/${ENDPOINT_ID}')"
}
}
}
]
EOF
Шаг 4: Создайте и привяжите политику доступа IAM.
Создайте глобальную политику доступа IAM:
# create global IAM access policy
gcloud iam access-policies create ${UAP_POLICY_NAME} \
--details-rules=cfg/uap-rules.json \
--project=${PROJECT_GOVERNANCE} \
--location=global
Привяжите политику доступа к PROJECT_GOVERNANCE :
# bind access policy to governance project
gcloud iam policy-bindings create ${UAP_BINDING_NAME} \
--policy="projects/${PROJECT_GOVERNANCE}/locations/global/accessPolicies/${UAP_POLICY_NAME}" \
--target-resource="//cloudresourcemanager.googleapis.com/projects/${PROJECT_GOVERNANCE}" \
--project=${PROJECT_GOVERNANCE} \
--location=global
Убедитесь, что привязка политики активна:
# verify policy binding
gcloud iam policy-bindings describe ${UAP_BINDING_NAME} \
--project=${PROJECT_GOVERNANCE} \
--location=global
Пример выходных данных:
name: projects/${PROJECT_GOVERNANCE}/locations/global/policyBindings/uap-binding-centralized-agw
policy: projects/${PROJECT_GOVERNANCE}/locations/global/accessPolicies/uap-policy-centralized-agw
policyKind: ACCESS_POLICY
target:
resource: //cloudresourcemanager.googleapis.com/projects/${PROJECT_GOVERNANCE}
Теперь исходящий трафик базовых API Google Cloud безопасно авторизуется во всех трех проектах в строгом режиме ENFORCE .
На этом завершается настройка авторизации шлюза... далее переходим к разделу «Настройка разрешений IAM для разных проектов» .
6. Межпроектное управление идентификацией и доступом (IAM)
Настройка разрешений IAM для разных проектов
В этой многопроектной топологии среды выполнения агентов находятся в периферийных проектах ( PROJECT_CONCIERGE и PROJECT_SELLERS ), а центральный шлюз агентов и реестр агентов — в PROJECT_GOVERNANCE .
Поскольку проекты Google Cloud представляют собой изолированные периметры безопасности, доступ между проектами должен быть явно предоставлен на двух операционных уровнях:
- Плоскость управления (время развертывания): При развертывании контейнера агента, настроенного с
--agent-gateway-config, служба выполнения агентов проекта-спицы (service-) должен подключить контейнер к центральному шлюзу. Мы создаем минимальную пользовательскую роль (@gcp-sa-aiplatform.iam.gserviceaccount.com ar_agw_cross_project_sa), предоставляющуюnetworkservices.agentGateways.use,getиoperations.getвPROJECT_GOVERNANCE. - Плоскость данных (выполнение во время выполнения):
- Обнаружение в каталоге: Для динамического определения целевых конечных точек агентов периферийным устройствам требуется
roles/agentregistry.viewerвPROJECT_GOVERNANCE. - Целевой вызов: Агенту Concierge необходимы
roles/aiplatform.userвPROJECT_SELLERSдля выполнения запросов к механизмам обработки данных продавцов.
- Обнаружение в каталоге: Для динамического определения целевых конечных точек агентов периферийным устройствам требуется
Создайте пользовательскую роль IAM в PROJECT_GOVERNANCE
# create custom role in central governance project
gcloud iam roles create ar_agw_cross_project_sa \
--project=${PROJECT_GOVERNANCE} \
--title="Runtime Agent Gateway Cross-Project SA" \
--description="Custom role for cross-project service agents to access Central Agent Gateway" \
--permissions="networkservices.agentGateways.get,networkservices.agentGateways.use,networkservices.operations.get" \
--stage="GA"
Назначение пользовательской роли агентам службы выполнения агентов
# 1. ensure aiplatform service identities are provisioned across all projects
for PROJ in ${PROJECT_GOVERNANCE} ${PROJECT_CONCIERGE} ${PROJECT_SELLERS}; do
gcloud beta services identity create --service=aiplatform.googleapis.com --project=${PROJ}
done
# 2. derive aiplatform service agent emails
export CONCIERGE_AI_SA="service-${PROJECT_NUMBER_CONCIERGE}@gcp-sa-aiplatform.iam.gserviceaccount.com"
export CONCIERGE_RE_SA="service-${PROJECT_NUMBER_CONCIERGE}@gcp-sa-aiplatform-re.iam.gserviceaccount.com"
export CONCIERGE_COMPUTE_SA="${PROJECT_NUMBER_CONCIERGE}-compute@developer.gserviceaccount.com"
export SELLERS_AI_SA="service-${PROJECT_NUMBER_SELLERS}@gcp-sa-aiplatform.iam.gserviceaccount.com"
export SELLERS_RE_SA="service-${PROJECT_NUMBER_SELLERS}@gcp-sa-aiplatform-re.iam.gserviceaccount.com"
export SELLERS_COMPUTE_SA="${PROJECT_NUMBER_SELLERS}-compute@developer.gserviceaccount.com"
# 3. grant custom role & network viewer to Concierge and Sellers Service Agents
for SA in ${CONCIERGE_AI_SA} ${SELLERS_AI_SA}; do
gcloud projects add-iam-policy-binding ${PROJECT_GOVERNANCE} \
--member="serviceAccount:${SA}" \
--role="projects/${PROJECT_GOVERNANCE}/roles/ar_agw_cross_project_sa" \
--condition=None
gcloud projects add-iam-policy-binding ${PROJECT_GOVERNANCE} \
--member="serviceAccount:${SA}" \
--role="roles/networkservices.viewer" \
--condition=None
done
# 4. grant agent registry viewer on Governance Project for dynamic autodiscovery
for MEMBER in "serviceAccount:${CONCIERGE_AI_SA}" "serviceAccount:${CONCIERGE_RE_SA}" "serviceAccount:${CONCIERGE_COMPUTE_SA}" "serviceAccount:${SELLERS_AI_SA}" "serviceAccount:${SELLERS_RE_SA}" "serviceAccount:${SELLERS_COMPUTE_SA}" "principalSet://agents.global.org-${ORG_ID}.system.id.goog/attribute.platformContainer/aiplatform/projects/${PROJECT_NUMBER_CONCIERGE}" "principalSet://agents.global.org-${ORG_ID}.system.id.goog/attribute.platformContainer/aiplatform/projects/${PROJECT_NUMBER_SELLERS}"; do
gcloud projects add-iam-policy-binding ${PROJECT_GOVERNANCE} \
--member="${MEMBER}" \
--role="roles/agentregistry.viewer" \
--condition=None
done
# 5. grant agent project viewer on Governance Project for dynamic autodiscovery
for SA in ${CONCIERGE_COMPUTE_SA} ${CONCIERGE_AI_SA}; do
gcloud projects add-iam-policy-binding ${PROJECT_GOVERNANCE} \
--member="serviceAccount:${SA}" \
--role="roles/viewer" \
--condition=None
done
# 6. grant aitplatform user on Sellers project to Concierge for cross-project A2A invocation
for MEMBER in "serviceAccount:${CONCIERGE_AI_SA}" "serviceAccount:${CONCIERGE_RE_SA}" "serviceAccount:${CONCIERGE_COMPUTE_SA}" "principalSet://agents.global.org-${ORG_ID}.system.id.goog/attribute.platformContainer/aiplatform/projects/${PROJECT_NUMBER_CONCIERGE}"; do
gcloud projects add-iam-policy-binding ${PROJECT_SELLERS} \
--member="${MEMBER}" \
--role="roles/aiplatform.user" \
--condition=None
done
На этом завершается настройка IAM в рамках всего проекта... далее переходим к разделу «Развертывание агентов продавцов и консьержей» .
7. Среда выполнения агента
Внедрите агентов по продажам и консьерж-сервисам.
Код многоагентного приложения и скрипты развертывания, используемые в этом практическом занятии, хранятся в удаленном репозитории Google Cloud GitHub . Следующие шаги клонируют репозиторий локально, скопируют необходимые файлы в текущую структуру рабочих каталогов, очистят временные файлы и установят зависимости с помощью uv .
Получение удаленных артефактов
# clone remote repository to temp local dir
git clone https://github.com/GoogleCloudPlatform/cloud-networking-solutions.git ./temp_agw_cuj_arun_multiproject
# copy multi-agent application files to current working directory
cp -r temp_agw_cuj_arun_multiproject/codelabs/agw-cuj-arun-multiproject ./cross-project-multiagent
# remove temporary directory
rm -rf temp_agw_cuj_arun_multiproject
# install dependencies
uv sync --directory ./cross-project-multiagent
Создать общий центральный промежуточный контейнер
# create shared central staging bucket
gcloud storage buckets create gs://${PROJECT_GOVERNANCE}-shared-staging \
--project=${PROJECT_GOVERNANCE} \
--location=${REGION}
# grant cross-project read/write access to runtime service agents
gcloud storage buckets add-iam-policy-binding gs://${PROJECT_GOVERNANCE}-shared-staging \
--member="serviceAccount:service-${PROJECT_NUMBER_CONCIERGE}@gcp-sa-aiplatform.iam.gserviceaccount.com" \
--role="roles/storage.objectAdmin"
gcloud storage buckets add-iam-policy-binding gs://${PROJECT_GOVERNANCE}-shared-staging \
--member="serviceAccount:service-${PROJECT_NUMBER_SELLERS}@gcp-sa-aiplatform.iam.gserviceaccount.com" \
--role="roles/storage.objectAdmin"
Как работает привязка шлюза агентов между проектами
На этом этапе вы развернете агентов продавцов в периферийном проекте ( PROJECT_SELLERS ), настроив их таким образом, чтобы исходящий трафик проходил через центральный шлюз агентов в PROJECT_GOVERNANCE :
# !-- for example purposes -- NOT a command to execute --!
# snippet from deploy_burger.py
burger_config = {
"staging_bucket": staging_bucket_uri,
"gcs_dir_name": "burger_agent",
"display_name": "burger-seller-agent-adk",
"identity_type": "AGENT_IDENTITY",
"agent_gateway_config": {
"agent_to_anywhere_config": {
"agent_gateway": f"projects/{args.governance_project}/locations/{args.region}/agentGateways/{args.gateway}"
}
},
}
deployed_burger = client.agent_engines.create(agent=burger_playground, config=burger_config)
Поскольку правило 1 было установлено ранее в нашей Единой политике доступа, запросы на инициализацию контейнеров к API Google Cloud разрешены через шлюз без прерывания.
Внедрить агентов по продаже бургеров и пиццы в PROJECT_SELLERS
# 1. deploy Burger Seller Agent to PROJECT_SELLERS
uv run --directory ./cross-project-multiagent python deploy_burger.py \
--project=${PROJECT_SELLERS} \
--region=${REGION} \
--governance-project=${PROJECT_GOVERNANCE} \
--gateway=projects/${PROJECT_GOVERNANCE}/locations/${REGION}/agentGateways/${AGW_NAME}
# 2. deploy Pizza Seller Agent to PROJECT_SELLERS
uv run --directory ./cross-project-multiagent python deploy_pizza.py \
--project=${PROJECT_SELLERS} \
--region=${REGION} \
--governance-project=${PROJECT_GOVERNANCE} \
--gateway=projects/${PROJECT_GOVERNANCE}/locations/${REGION}/agentGateways/${AGW_NAME}
Проверка маршрутизации платежного шлюза продавца
# retrieve deployed seller reasoning engine IDs
export BURGER_ENGINE_ID=$(grep BURGER_SELLER_AGENT_ID cross-project-multiagent/burger_agent.env | awk -F'/' '{print $NF}')
export PIZZA_ENGINE_ID=$(grep PIZZA_SELLER_AGENT_ID cross-project-multiagent/pizza_agent.env | awk -F'/' '{print $NF}')
echo "Burger Engine ID: ${BURGER_ENGINE_ID}"
echo "Pizza Engine ID: ${PIZZA_ENGINE_ID}"
# inspect runtime configuration for both Seller Agents
for ENGINE_ID in ${BURGER_ENGINE_ID} ${PIZZA_ENGINE_ID}; do
curl -s -X GET "https://${REGION}-aiplatform.googleapis.com/v1beta1/projects/${PROJECT_SELLERS}/locations/${REGION}/reasoningEngines/${ENGINE_ID}" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" \
| jq '{displayName: .displayName, identityType: .spec.identityType, effectiveIdentity: .spec.effectiveIdentity, agentGatewayConfig: .spec.deploymentSpec.agentGatewayConfig}'
done
Внедрить агента по сопровождению закупок в PROJECT_CONCIERGE
# deploy Purchasing Concierge to PROJECT_CONCIERGE
uv run --directory ./cross-project-multiagent python deploy_concierge_adk.py \
--project=${PROJECT_CONCIERGE} \
--region=${REGION} \
--staging-bucket=gs://${PROJECT_GOVERNANCE}-shared-staging \
--gateway-name=${AGW_NAME} \
--gateway-project=${PROJECT_GOVERNANCE}
Проверка маршрутизации платежного шлюза
# retrieve Concierge engine ID
export CONCIERGE_ENGINE_ID=$(grep CONCIERGE_AGENT_ID cross-project-multiagent/concierge_agent.env | awk -F'/' '{print $NF}')
echo "Concierge Engine ID: ${CONCIERGE_ENGINE_ID}"
# inspect runtime configuration for Purchasing Concierge
curl -s -X GET "https://${REGION}-aiplatform.googleapis.com/v1beta1/projects/${PROJECT_CONCIERGE}/locations/${REGION}/reasoningEngines/${CONCIERGE_ENGINE_ID}" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" \
| jq '{displayName: .displayName, identityType: .spec.identityType, effectiveIdentity: .spec.effectiveIdentity, agentGatewayConfig: .spec.deploymentSpec.agentGatewayConfig}'
В выходных данных должны отображаться идентификатор среды выполнения агента Concierge и проект, а также привязка к шлюзу агента проекта Governance.
{
"displayName": "purchasing-concierge-adk",
"identityType": "AGENT_IDENTITY",
"effectiveIdentity": "agents.global.org-${ORG_ID}.system.id.goog/resources/aiplatform/projects/${PROJECT_CONCIERGE}/locations/us-central1/reasoningEngines/${CONCIERGE_ENGINE_ID}",
"agentGatewayConfig": {
"agentToAnywhereConfig": {
"agentGateway": "projects/${PROJECT_GOVERNANCE}/locations/us-central1/agentGateways/centralized-agw"
}
}
}
На этом развертывание агентов завершается... далее переходим к разделу « Регистрация агентов в Центральном реестре агентов» .
8. Межпроектный реестр
Регистрация агентов в Центральном реестре агентов
Зарегистрируйте всех трех агентов в Центральном реестре агентов в PROJECT_GOVERNANCE , используя региональные mTLS-конечные точки для всех проектов и числовые номера проектов.
Зарегистрируйте услуги в качестве агентов, не являющихся агентами A2A, в реестре агентов.
# 1. register Burger Seller Agent
gcloud agent-registry services create burger-seller-agent \
--project=${PROJECT_GOVERNANCE} \
--location=${REGION} \
--display-name="Burger Seller Agent" \
--description="Specialist agent that sells burgers and fries" \
--agent-spec-type=no-spec \
--interfaces=protocolBinding=JSONRPC,url=https://${REGION}-aiplatform.mtls.googleapis.com/v1/projects/${PROJECT_NUMBER_SELLERS}/locations/${REGION}/reasoningEngines/${BURGER_ENGINE_ID}:query \
--interfaces=protocolBinding=JSONRPC,url=https://${REGION}-aiplatform.mtls.googleapis.com/v1beta1/projects/${PROJECT_NUMBER_SELLERS}/locations/${REGION}/reasoningEngines/${BURGER_ENGINE_ID}:query
# 2. register Pizza Seller Agent
gcloud agent-registry services create pizza-seller-agent \
--project=${PROJECT_GOVERNANCE} \
--location=${REGION} \
--display-name="Pizza Seller Agent" \
--description="Specialist agent that sells pizzas and pasta" \
--agent-spec-type=no-spec \
--interfaces=protocolBinding=JSONRPC,url=https://${REGION}-aiplatform.mtls.googleapis.com/v1/projects/${PROJECT_NUMBER_SELLERS}/locations/${REGION}/reasoningEngines/${PIZZA_ENGINE_ID}:query \
--interfaces=protocolBinding=JSONRPC,url=https://${REGION}-aiplatform.mtls.googleapis.com/v1beta1/projects/${PROJECT_NUMBER_SELLERS}/locations/${REGION}/reasoningEngines/${PIZZA_ENGINE_ID}:query
# 3. register Purchasing Concierge Agent
gcloud agent-registry services create purchasing-concierge-adk \
--project=${PROJECT_GOVERNANCE} \
--location=${REGION} \
--display-name="Purchasing Concierge Agent" \
--description="Orchestrator concierge agent that routes purchasing requests" \
--agent-spec-type=no-spec \
--interfaces=protocolBinding=JSONRPC,url=https://${REGION}-aiplatform.mtls.googleapis.com/v1/projects/${PROJECT_NUMBER_CONCIERGE}/locations/${REGION}/reasoningEngines/${CONCIERGE_ENGINE_ID}:query \
--interfaces=protocolBinding=JSONRPC,url=https://${REGION}-aiplatform.mtls.googleapis.com/v1beta1/projects/${PROJECT_NUMBER_CONCIERGE}/locations/${REGION}/reasoningEngines/${CONCIERGE_ENGINE_ID}:query
Получение идентификаторов базового агента из реестра
# capture underlying Agent Registry Agent UUIDs
export BURGER_AGENT_ID=$(gcloud agent-registry services describe burger-seller-agent --project=${PROJECT_GOVERNANCE} --location=${REGION} --format="value(registryResource)" | awk -F'/' '{print $NF}')
export PIZZA_AGENT_ID=$(gcloud agent-registry services describe pizza-seller-agent --project=${PROJECT_GOVERNANCE} --location=${REGION} --format="value(registryResource)" | awk -F'/' '{print $NF}')
export CONCIERGE_AGENT_ID=$(gcloud agent-registry services describe purchasing-concierge-adk --project=${PROJECT_GOVERNANCE} --location=${REGION} --format="value(registryResource)" | awk -F'/' '{print $NF}')
echo "Burger Agent ID: ${BURGER_AGENT_ID}"
echo "Pizza Agent ID: ${PIZZA_AGENT_ID}"
echo "Concierge Agent ID: ${CONCIERGE_AGENT_ID}"
На этом настройка реестра завершена... далее переходим к разделу «Настройка политик исходящего трафика A2A» .
9. Политика UAP
Настройка политик исходящего трафика A2A в унифицированной политике доступа.
В архитектуре Agent Gateway с параметром Default Deny в строгом режиме ENFORCE :
- Правило 1 (Базовые API Google Cloud): Позволяет контейнерам агентов во всех 3 проектах обращаться к
core-gapi-services. - Правило 2 (Агент продавца бургеров: РАЗРЕШИТЬ): Разрешает экземпляру Агента по сопровождению закупок вызывать Агента продавца бургеров.
- Агент продавца пиццы (по умолчанию ЗАПРЕЩЕН): Намеренно исключен из правил политики. В режиме
ENFORCE(failOpen: false) любая попытка консьержа вызвать продавца пиццы будет немедленно прервана на периметре шлюза сHTTP 403 Forbidden.
Сформулируйте идентичность консьерж-агента.
# formulate the exact SPIFFE machine identity for the Concierge Agent
export CONCIERGE_SPIFFE_PRINCIPAL="principal://agents.global.org-${ORG_ID}.system.id.goog/resources/aiplatform/projects/${PROJECT_NUMBER_CONCIERGE}/locations/${REGION}/reasoningEngines/${CONCIERGE_ENGINE_ID}"
echo "Concierge SPIFFE Principal: ${CONCIERGE_SPIFFE_PRINCIPAL}"
Обновите манифест в соответствии с правилами 1 и 2.
Создайте новый cfg/uap-rules-update-2.json , чтобы включить в него Правило 1 (Основные API) и теперь Правило 2 (Агент продавца Burger):
# create addendum to update policy manifest with Rule 2 for Burger Agent
cat > cfg/uap-rules-update-2.json << EOF
[
{
"description": "Rule 2: Allow Purchasing Concierge to invoke Burger Seller Agent via Central Gateway",
"effect": "ALLOW",
"principals": [
"${CONCIERGE_SPIFFE_PRINCIPAL}"
],
"operation": {
"permissions": [
"iap.googleapis.com/resources.egressViaIAP"
]
},
"conditions": {
"iap.googleapis.com": {
"expression": \
"destination.is_registered == true && \
destination.agent_registry.resource_type == 'AGENT' && ( \
destination.agent_registry.agent.name == 'projects/${PROJECT_GOVERNANCE}/locations/${REGION}/agents/burger-seller-agent' || \
destination.agent_registry.agent.name == 'projects/${PROJECT_GOVERNANCE}/locations/${REGION}/agents/${BURGER_AGENT_ID}' || \
destination.agent_registry.agent.name == 'projects/${PROJECT_NUMBER_GOVERNANCE}/locations/${REGION}/agents/${BURGER_AGENT_ID}')"
}
}
}
]
EOF
Примените обновленную политику доступа.
# update IAM access policy with Burger rule
gcloud iam access-policies update ${UAP_POLICY_NAME} \
--add-details-rules=cfg/uap-rules-update-2.json \
--project=${PROJECT_GOVERNANCE} \
--location=global
Проверьте сведения о политике доступа IAM.
# inspect updated access policy
gcloud iam access-policies describe ${UAP_POLICY_NAME} \
--project=${PROJECT_GOVERNANCE} \
--location=global
Пример выходных данных:
details:
rules:
- conditions:
iap.googleapis.com:
expression: destination.is_registered == true && destination.agent_registry.resource_type
== 'ENDPOINT' && (destination.agent_registry.endpoint.name == 'projects/${PROJECT_GOVERNANCE}/locations/us-central1/endpoints/core-gapi-services'
|| destination.agent_registry.endpoint.name == 'projects/${PROJECT_NUMBER_GOVERNANCE}/locations/us-central1/endpoints/${ENDPOINT_ID}')
description: 'Rule 1: Allow agent runtimes across all 3 projects to reach Core
Google APIs'
effect: ALLOW
operation:
permissions:
- iap.googleapis.com/resources.egressViaIAP
principals:
- principalSet://agents.global.org-${ORG_ID}.system.id.goog/attribute.platformContainer/aiplatform/projects/${PROJECT_NUMBER_GOVERNANCE}
- principalSet://agents.global.org-${ORG_ID}.system.id.goog/attribute.platformContainer/aiplatform/projects/${PROJECT_NUMBER_CONCIERGE}
- principalSet://agents.global.org-${ORG_ID}.system.id.goog/attribute.platformContainer/aiplatform/projects/${PROJECT_NUMBER_SELLERS}
- conditions:
iap.googleapis.com:
expression: (destination.is_registered == true) && (destination.agent_registry.resource_type
== 'AGENT') && (destination.agent_registry.agent.name == 'projects/${PROJECT_GOVERNANCE}/locations/us-central1/agents/burger-seller-agent'
|| destination.agent_registry.agent.name == 'projects/${PROJECT_NUMBER_GOVERNANCE}/locations/us-central1/agents/${BURGER_AGENT_ID}')
description: 'Rule 2: Allow Purchasing Concierge to invoke Burger Seller Agent
via Central Gateway'
effect: ALLOW
operation:
permissions:
- iap.googleapis.com/resources.egressViaIAP
principals:
- principal://agents.global.org-${ORG_ID}.system.id.goog/resources/aiplatform/projects/${PROJECT_NUMBER_CONCIERGE}/locations/us-central1/reasoningEngines/${CONCIERGE_ENGINE_ID}
name: projects/${PROJECT_GOVERNANCE}/locations/global/accessPolicies/uap-policy-centralized-agw
На этом завершается настройка политики... далее переходим к разделу «Тестирование и проверка политик управления» .
10. Проверьте правила.
Тестирование и проверка политик управления с помощью облачного логирования.
В этом разделе вы протестируете взаимодействие между агентами (A2A) в рамках нескольких проектов в среде разработки Agent Runtime AI Playground, понаблюдаете за реальной блокировкой HTTP 403 Forbidden в строгом режиме ENFORCE , внесете изменения в унифицированную политику доступа в режиме реального времени и проверите мгновенное подтверждение заказов.
Шаг 1: Откройте среду выполнения Agent Runtime AI Playground в PROJECT_CONCIERGE
- Откройте консоль Google Cloud .
- В верхней панели выбора проекта переключитесь на
PROJECT_CONCIERGE. - В меню навигации перейдите в раздел «Платформа агентов» > «Агенты» > «Развертывания» .
- Нажмите на
purchasing-concierge-adk. - Выберите «Игровая площадка» , чтобы открыть интерактивный чат в правой части экрана.
Шаг 2: Проверка заказа бургера (Соответствие правилу 2 -> 200 OK)
В окне чата Playground отправьте следующее сообщение с запросом на оформление заказа:
I would like 10 Classic Cheeseburgers. Place this order now.
Если требуется подтверждение, отправьте следующий ответ:
Confirmed, please place the order.
В качестве альтернативы, можно провести тестирование программно из Cloud Shell / терминала:
uv run --directory ./cross-project-multiagent python -c "
import vertexai
from vertexai.preview import reasoning_engines
vertexai.init(project='${PROJECT_CONCIERGE}', location='${REGION}')
agent = reasoning_engines.ReasoningEngine('projects/${PROJECT_CONCIERGE}/locations/${REGION}/reasoningEngines/${CONCIERGE_ENGINE_ID}')
response = agent.query(input={'message': 'I would like 22 Spicy Cajun Burgers please. Place this order now.'})
print(response)
"
А если потребуется подтверждение, используйте эту команду:
uv run --directory ./cross-project-multiagent python -c "
import vertexai
from vertexai.preview import reasoning_engines
vertexai.init(project='${PROJECT_CONCIERGE}', location='${REGION}')
agent = reasoning_engines.ReasoningEngine('projects/${PROJECT_CONCIERGE}/locations/${REGION}/reasoningEngines/${CONCIERGE_ENGINE_ID}')
response = agent.query(input='Yes please place the order now.')
print(response['text'])
"
Что происходит за кулисами:
- Динамическое обнаружение: Во время запуска сессии менеджер по закупкам запросил Центральный реестр агентов в
PROJECT_GOVERNANCE(черезcore-gapi-servicesчерез Agent Gateway, авторизованный правилом 1), чтобы обнаружить региональную конечную точку mTLS дляburger-seller-agent. - Разрешение намерений и вызов A2A: Gemini внутри системы Purchasing Concierge анализирует намерение заказа еды и вызывает агента продавца бургеров через исходящий RPC-вызов по адресу
https://${REGION}-aiplatform.mtls.googleapis.com/.../reasoningEngines/${BURGER_ENGINE_ID}. - Перехват трафика шлюзом и распространение SPIFFE: исходящий трафик перехватывается
agent_gateway_configи направляется на центральный шлюз агента вPROJECT_GOVERNANCE, неся криптографический идентификатор SPIFFE консьержа (principal://...). - Оценка политики IAP v2: Центральный шлюз агента вызывает расширение авторизации IAP (
authzExtension). IAP v2 оценивает правило 2 в унифицированной политике доступа IAM. Поскольку вызывающий объект соответствует${CONCIERGE_SPIFFE_PRINCIPAL}, а целевой объект соответствуетburger-seller-agent, IAP возвращаетALLOW(granted: true). - Выполнение запросов между проектами: Шлюз агентов передает авторизованный запрос между проектами в
PROJECT_SELLERS, где механизм обработки запросов продавцов Burger обрабатывает заказ и возвращает подтверждение.
Ожидаемый ответ:
Your order for 10 Classic Cheeseburger(s) has been placed!
Here is a summary of your order:
- 10x Classic Cheeseburger @ IDR 85,000/each = IDR 850,000
Total: IDR 850,000
Your Order ID is: e8f9c732-f347-4cc4-acff-cfe09ccbeddd
Шаг 3: Проверьте журналы аудита Agent Gateway и IAP v2 (HTTP 200 / ALLOWED)
Запросить журналы запросов Agent Gateway в PROJECT_GOVERNANCE :
# query Agent Gateway logs for successful 200 OK requests
gcloud logging read "
logName=\"projects/${PROJECT_GOVERNANCE}/logs/networkservices.googleapis.com%2Fgateway_requests\"
AND jsonPayload.authzPolicyInfo.result=\"ALLOWED\"
" \
--project="${PROJECT_GOVERNANCE}" \
--limit=10 \
--format="table(
timestamp.date('%H:%M:%S'):label=TIME,
httpRequest.requestMethod:label=METHOD,
httpRequest.status:label=STATUS,
jsonPayload.authzPolicyInfo.result:label=AUTHZ,
httpRequest.requestUrl:label=URL
)"
Журналы должны фиксировать исходящий трафик, исходящий от обоих периферийных проектов ( PROJECT_CONCIERGE и PROJECT_SELLERS ), с полями исходящего трафика для вызовов Gemini ( generateContent ), телеметрии Cloud Trace ( /v1/traces ) и запросов учетных данных IAM — при этом трафик должен прозрачно перехватываться и авторизоваться в соответствии с Правилом 1 ( core-gapi-services ).
Запросите журналы доступа к данным аудита облака IAP v2, чтобы проверить версию политики POLICY_VERSION_V2 :
# query IAP v2 audit logs with shortened principal and resource fields
gcloud logging read "
logName=\"projects/${PROJECT_GOVERNANCE}/logs/cloudaudit.googleapis.com%2Fdata_access\"
AND protoPayload.serviceName=\"iap.googleapis.com\"
" \
--project="${PROJECT_GOVERNANCE}" \
--limit=5 \
--format="table(
timestamp.date('%H:%M:%S'):label=TIME,
protoPayload.authenticationInfo.principalSubject.sub('\.global\..*\/reasoningEngines\/', '.[...]/reasoningEngines/'):label=CALLER,
protoPayload.authorizationInfo[0].granted:label=GRANTED,
protoPayload.metadata.destination.agent_registry.resource_type.basename():label=TYPE,
protoPayload.metadata.destination.agent_registry.resource_id.basename():label=RESOURCE_ID,
protoPayload.authorizationInfo[0].permission.basename():label=PERMISSION
)"
Пример выходных данных:
TIME CALLER GRANTED TYPE RESOURCE_ID PERMISSION
HH:MM:SS principal://agents.[...]/reasoningEngines/${CONCIERGE_ENGINE_ID} True Endpoint ${ENDPOINT_ID} resources.egressViaIAP
HH:MM:SS principal://agents.[...]/reasoningEngines/${BURGER_ENGINE_ID} True Endpoint ${ENDPOINT_ID} resources.egressViaIAP
HH:MM:SS principal://agents.[...]/reasoningEngines/${CONCIERGE_ENGINE_ID} True Endpoint ${ENDPOINT_ID} resources.egressViaIAP
HH:MM:SS principal://agents.[...]/reasoningEngines/${BURGER_ENGINE_ID} True Endpoint ${ENDPOINT_ID} resources.egressViaIAP
Шаг 4: Проверка заказа пиццы (По умолчанию — отказ -> HTTP 403 Forbidden ENFORCED)
В том же окне чата Playground отправьте следующий запрос на заказ пиццы:
I would like 10 BBQ Chicken Pizzas. Place this order now.
Если требуется подтверждение, отправьте следующий ответ:
Confirmed, please place the order.
В качестве альтернативы, можно провести тестирование программно из Cloud Shell / терминала:
uv run --directory ./cross-project-multiagent python -c "
import vertexai
from vertexai.preview import reasoning_engines
vertexai.init(project='${PROJECT_CONCIERGE}', location='${REGION}')
agent = reasoning_engines.ReasoningEngine('projects/${PROJECT_CONCIERGE}/locations/${REGION}/reasoningEngines/${CONCIERGE_ENGINE_ID}')
response = agent.query(input='I would like 8 Hawaiian pizzas, please. Place this order now.')
print(response)
"
А если потребуется подтверждение, используйте эту команду:
uv run --directory ./cross-project-multiagent python -c "
import vertexai
from vertexai.preview import reasoning_engines
vertexai.init(project='${PROJECT_CONCIERGE}', location='${REGION}')
agent = reasoning_engines.ReasoningEngine('projects/${PROJECT_CONCIERGE}/locations/${REGION}/reasoningEngines/${CONCIERGE_ENGINE_ID}')
response = agent.query(input='Yes please place the order now.')
print(response['text'])
"
Ожидаемый ответ:
I apologize, but I am unable to process that request at the moment. It seems
there was an issue connecting to the pizza seller agent. Please try again later.
Что происходит за кулисами:
- Динамическое обнаружение: Служба поддержки закупок определила конечную точку
pizza-seller-agentиз Центрального реестра агентов во время запуска. - Разрешение намерений и вызов A2A: Gemini внутри системы Purchasing Concierge пытается перенаправить запрос на заказ пиццы на конечную точку продавца пиццы в
PROJECT_SELLERS. - Перехват шлюза: исходящий RPC-вызов перехватывается функцией
agent_gateway_configи направляется на центральный шлюз агентов. - Оценка политики IAP v2 (запрет по умолчанию): Центральный шлюз агентов вызывает IAP v2. Поскольку в Единой политике доступа отсутствует правило , соответствующее
pizza-seller-agent, IAP возвращаетDENY(granted: false). - Строгая блокировка периметра: поскольку расширение аутентификации находится в режиме ENFORCE (
failOpen: false), центральный шлюз агента немедленно разрывает исходящее соединение и возвращаетHTTP 403 Forbidden. Трафик никогда не покидает шлюз и никогда не достигаетPROJECT_SELLERS.
Шаг 5: Проверьте журналы шлюза агента на наличие заблокированных запросов (HTTP 403 / DENIED)
# query Agent Gateway logs for blocked 403 requests
gcloud logging read "
logName=\"projects/${PROJECT_GOVERNANCE}/logs/networkservices.googleapis.com%2Fgateway_requests\"
AND httpRequest.status=403
" \
--project="${PROJECT_GOVERNANCE}" \
--limit=5 \
--format="table(
timestamp.date('%H:%M:%S'):label=TIME,
httpRequest.requestMethod:label=METHOD,
httpRequest.status:label=STATUS,
jsonPayload.authzPolicyInfo.result:label=AUTHZ,
httpRequest.requestUrl:label=URL
)"
Пример вывода журнала отказов:
TIME METHOD STATUS AUTHZ URL
HH:MM:SS POST 403 DENIED https://us-central1-aiplatform.mtls.googleapis.com/v1beta1/projects/${PROJECT_SELLERS}/locations/us-central1/reasoningEngines/${PIZZA_ENGINE_ID}:query
Запросите журналы аудита доступа к данным IAP v2 для получения информации о решении об отказе:
# query IAP v2 audit logs with shortened principal and resource fields
gcloud logging read "
logName=\"projects/${PROJECT_GOVERNANCE}/logs/cloudaudit.googleapis.com%2Fdata_access\"
AND protoPayload.serviceName=\"iap.googleapis.com\"
" \
--project="${PROJECT_GOVERNANCE}" \
--limit=5 \
--format="table(
timestamp.date('%H:%M:%S'):label=TIME,
protoPayload.authenticationInfo.principalSubject.sub('\.global\..*\/reasoningEngines\/', '.[...]/reasoningEngines/'):label=CALLER,
protoPayload.authorizationInfo[0].granted:label=GRANTED,
protoPayload.metadata.destination.agent_registry.resource_type.basename():label=TYPE,
protoPayload.metadata.destination.agent_registry.resource_id.basename():label=RESOURCE_ID,
protoPayload.authorizationInfo[0].permission.basename():label=PERMISSION
)"
Пример выходных данных из журнала аудита, помеченных как "Отказано":
TIME CALLER GRANTED TYPE RESOURCE_ID PERMISSION
HH:MM:SS principal://agents.[...]/reasoningEngines/${PIZZA_ENGINE_ID} True Endpoint ${REGISTRY_ID} resources.egressViaIAP
HH:MM:SS principal://agents.[...]/reasoningEngines/${PIZZA_ENGINE_ID} True Endpoint ${REGISTRY_ID} resources.egressViaIAP
HH:MM:SS principal://agents.[...]/reasoningEngines/${CONCIERGE_ENGINE_ID} False Agent ${REGISTRY_ID} resources.egressViaIAP
HH:MM:SS principal://agents.[...]/reasoningEngines/${PIZZA_ENGINE_ID} True Endpoint ${REGISTRY_ID} resources.egressViaIAP
Шаг 6: Динамическое предоставление исходящего доступа агенту Pizza Agent
Создайте новый cfg/uap-rules-update-3.json , чтобы включить в него Правило 1 (Основные API), Правило 2 (Агент продавца Burger) и теперь Правило 3 (Агент продавца Pizza).
# create addendum to update policy manifest with Rule 3 for Pizza Agent
cat > cfg/uap-rules-update-3.json << EOF
[
{
"description": "Rule 3: Allow Purchasing Concierge to invoke Pizza Seller Agent via Central Gateway",
"effect": "ALLOW",
"principals": [
"${CONCIERGE_SPIFFE_PRINCIPAL}"
],
"operation": {
"permissions": [
"iap.googleapis.com/resources.egressViaIAP"
]
},
"conditions": {
"iap.googleapis.com": {
"expression": \
"destination.is_registered == true && \
destination.agent_registry.resource_type == 'AGENT' && ( \
destination.agent_registry.agent.name == 'projects/${PROJECT_GOVERNANCE}/locations/${REGION}/agents/pizza-seller-agent' || \
destination.agent_registry.agent.name == 'projects/${PROJECT_GOVERNANCE}/locations/${REGION}/agents/${PIZZA_AGENT_ID}' || \
destination.agent_registry.agent.name == 'projects/${PROJECT_NUMBER_GOVERNANCE}/locations/${REGION}/agents/${PIZZA_AGENT_ID}')"
}
}
}
]
EOF
Внесите изменения в политику в режиме реального времени:
# update IAM access policy with Pizza rule
gcloud iam access-policies update ${UAP_POLICY_NAME} \
--add-details-rules=cfg/uap-rules-update-3.json \
--project=${PROJECT_GOVERNANCE} \
--location=global
Шаг 7: Повторно запросите информацию у Pizza Agent (немедленный ответ 200 OK, успешное выполнение)
В окне чата Playground повторно отправьте запрос на заказ пиццы:
I would like 10 BBQ Chicken Pizzas. Place this order now.
Если требуется подтверждение, отправьте следующий ответ:
Confirmed, please place the order.
В качестве альтернативы, можно провести тестирование программно из Cloud Shell / терминала:
uv run --directory ./cross-project-multiagent python -c "
import vertexai
from vertexai.preview import reasoning_engines
vertexai.init(project='${PROJECT_CONCIERGE}', location='${REGION}')
agent = reasoning_engines.ReasoningEngine('projects/${PROJECT_CONCIERGE}/locations/${REGION}/reasoningEngines/${CONCIERGE_ENGINE_ID}')
response = agent.query(input='I would like 11 Veggie pizzas, please. Place this order now.')
print(response)
"
А если потребуется подтверждение, используйте эту команду:
uv run --directory ./cross-project-multiagent python -c "
import vertexai
from vertexai.preview import reasoning_engines
vertexai.init(project='${PROJECT_CONCIERGE}', location='${REGION}')
agent = reasoning_engines.ReasoningEngine('projects/${PROJECT_CONCIERGE}/locations/${REGION}/reasoningEngines/${CONCIERGE_ENGINE_ID}')
response = agent.query(input='Yes please place the order now.')
print(response['text'])
"
Ожидаемый ответ:
Your order has been placed!
**Order ID:** 8d6c13d7-31dc-4d80-b6a7-80d1e50b6411
**Order Details:**
* 10 x BBQ Chicken Pizza @ IDR 130,000 each = IDR 1,300,000
**Total: IDR 1,300,000**
Что происходит за кулисами:
- Динамическое обновление политики: обновление унифицированной политики доступа IAM вступает в силу немедленно в тестовом модуле IAP без простоев и без повторного развертывания каких-либо контейнеров.
- Вызов A2A: Консьерж отправляет запрос через центральный шлюз агентов.
- Оценка политики IAP v2 (утверждение): IAP v2 соответствует правилу 3, проверяет личность вызывающего абонента и целевое выражение CEL и возвращает
ALLOW(granted: true). - Выполнение заказов в рамках нескольких проектов: Центральный шлюз агента направляет авторизованный трафик в
PROJECT_SELLERS, где продавец пиццы обрабатывает заказ.
Шаг 8: Проверьте журналы шлюза агента на наличие одобренных запросов на доставку пиццы.
# query Agent Gateway logs for successful 200 OK requests
gcloud logging read "
logName=\"projects/${PROJECT_GOVERNANCE}/logs/networkservices.googleapis.com%2Fgateway_requests\"
AND jsonPayload.authzPolicyInfo.result=\"ALLOWED\"
" \
--project="${PROJECT_GOVERNANCE}" \
--limit=10 \
--format="table(
timestamp.date('%H:%M:%S'):label=TIME,
httpRequest.requestMethod:label=METHOD,
httpRequest.status:label=STATUS,
jsonPayload.authzPolicyInfo.result:label=AUTHZ,
httpRequest.requestUrl:label=URL
)"
Пример вывода журнала разрешенных запросов:
TIME METHOD STATUS AUTHZ URL
HH:MM:SS POST 200 ALLOWED https://us-central1-aiplatform.mtls.googleapis.com/v1beta1/projects/${PROJECT_SELLERS}/locations/us-central1/publishers/google/models/gemini-2.5-flash:generateContent
HH:MM:SS POST 200 ALLOWED https://us-central1-aiplatform.mtls.googleapis.com/v1beta1/projects/${PROJECT_SELLERS}/locations/us-central1/reasoningEngines/${PIZZA_ENGINE_ID}:query
На этом тестирование и проверка завершены... далее переходим к разделу "Очистка" .
11. Уборка
Чтобы избежать списания средств с вашего аккаунта Google Cloud за ресурсы, используемые в этом практическом занятии, выполняйте шаги по завершению работы строго в обратном порядке зависимостей:
1. Очистка развертываний системы логического вывода.
Выполните прилагаемый скрипт cleanup_old_deployments.py в обоих проектах среды выполнения, чтобы удалить механизмы логического вывода и дождаться завершения их длительных операций:
# delete all Reasoning Engines deployed in Concierge and Sellers projects
uv run --directory ./cross-project-multiagent python cleanup_old_deployments.py --project=${PROJECT_CONCIERGE} --region=${REGION}
uv run --directory ./cross-project-multiagent python cleanup_old_deployments.py --project=${PROJECT_SELLERS} --region=${REGION}
В качестве альтернативы, вы можете перечислять и удалять механизмы логического вывода непосредственно в коде:
uv run --directory ./cross-project-multiagent python -c '
import vertexai
import os
from vertexai.preview import reasoning_engines
region = os.environ.get("REGION", "us-central1")
for proj in [os.environ.get("PROJECT_CONCIERGE"), os.environ.get("PROJECT_SELLERS")]:
if not proj:
continue
print(f"Cleaning reasoning engines in {proj}...")
vertexai.init(project=proj, location=region)
for eng in reasoning_engines.ReasoningEngine.list():
print(f" Deleting {eng.resource_name} ({eng.display_name})...")
eng.delete()
'
2. Удалить службы реестра агентов.
# delete agent registry services in Central Governance Project
for SERVICE in burger-seller-agent pizza-seller-agent purchasing-concierge-adk core-gapi-services; do
gcloud agent-registry services delete ${SERVICE} \
--project=${PROJECT_GOVERNANCE} \
--location=${REGION} \
--quiet || true
done
3. Удалите привязку политики унифицированного доступа IAM и саму политику доступа.
# 1. delete IAM policy binding
gcloud -q iam policy-bindings delete ${UAP_BINDING_NAME} \
--project=${PROJECT_GOVERNANCE} \
--location=global || true
# 2. delete IAM access policy
gcloud -q iam access-policies delete ${UAP_POLICY_NAME} \
--project=${PROJECT_GOVERNANCE} \
--location=global || true
4. Удалите шлюз агента и политики безопасности.
# 1. delete authorization policy
gcloud beta network-security authz-policies delete ${AGW_NAME}-authz-policy-profile-iap \
--location=${REGION} \
--project=${PROJECT_GOVERNANCE} --quiet || true
# 2. delete authorization extension
gcloud service-extensions authz-extensions delete ${AGW_NAME}-svc-ext-authz-iap \
--location=${REGION} \
--project=${PROJECT_GOVERNANCE} --quiet || true
# 3. delete agent gateway
gcloud network-services agent-gateways delete ${AGW_NAME} \
--project=${PROJECT_GOVERNANCE} \
--location=${REGION} --quiet || true
5. Удалите межпроектные привязки IAM и пользовательские роли.
# 1. remove custom role and network viewer bindings for spoke service agents
for NUM in "${PROJECT_NUMBER_CONCIERGE}" "${PROJECT_NUMBER_SELLERS}"; do
SA="service-${NUM}@gcp-sa-aiplatform.iam.gserviceaccount.com"
gcloud projects remove-iam-policy-binding ${PROJECT_GOVERNANCE} \
--member="serviceAccount:${SA}" \
--role="projects/${PROJECT_GOVERNANCE}/roles/ar_agw_cross_project_sa" --quiet || true
gcloud projects remove-iam-policy-binding ${PROJECT_GOVERNANCE} \
--member="serviceAccount:${SA}" \
--role="roles/networkservices.viewer" --quiet || true
done
# 2. remove registry viewer permissions across both spoke projects
for NUM in "${PROJECT_NUMBER_CONCIERGE}" "${PROJECT_NUMBER_SELLERS}"; do
for MEMBER in \
"serviceAccount:service-${NUM}@gcp-sa-aiplatform.iam.gserviceaccount.com" \
"serviceAccount:service-${NUM}@gcp-sa-aiplatform-re.iam.gserviceaccount.com" \
"serviceAccount:${NUM}-compute@developer.gserviceaccount.com" \
"principalSet://agents.global.org-${ORG_ID}.system.id.goog/attribute.platformContainer/aiplatform/projects/${NUM}"; do
gcloud projects remove-iam-policy-binding ${PROJECT_GOVERNANCE} \
--member="${MEMBER}" \
--role="roles/agentregistry.viewer" --quiet || true
done
done
# 3. remove project viewer permissions
for MEMBER in \
"serviceAccount:${PROJECT_NUMBER_CONCIERGE}-compute@developer.gserviceaccount.com" \
"serviceAccount:service-${PROJECT_NUMBER_CONCIERGE}@gcp-sa-aiplatform.iam.gserviceaccount.com"; do
gcloud projects remove-iam-policy-binding ${PROJECT_GOVERNANCE} \
--member="${MEMBER}" \
--role="roles/viewer" --quiet || true
done
# 4. remove spoke-to-spoke delegation in Sellers project
for MEMBER in \
"serviceAccount:service-${PROJECT_NUMBER_CONCIERGE}@gcp-sa-aiplatform.iam.gserviceaccount.com" \
"serviceAccount:service-${PROJECT_NUMBER_CONCIERGE}@gcp-sa-aiplatform-re.iam.gserviceaccount.com" \
"serviceAccount:${PROJECT_NUMBER_CONCIERGE}-compute@developer.gserviceaccount.com" \
"principalSet://agents.global.org-${ORG_ID}.system.id.goog/attribute.platformContainer/aiplatform/projects/${PROJECT_NUMBER_CONCIERGE}"; do
gcloud projects remove-iam-policy-binding ${PROJECT_SELLERS} \
--member="${MEMBER}" \
--role="roles/aiplatform.user" --quiet || true
done
# 5. delete custom IAM role after all bindings have been unlinked
gcloud iam roles delete ar_agw_cross_project_sa \
--project=${PROJECT_GOVERNANCE} --quiet || true
Если вы назначили roles/iam.accessPolicyAdmin и roles/resourcemanager.projectIamAdmin на этапе настройки, удалите их из активной учетной записи пользователя, чтобы восстановить принцип минимальных привилегий:
# 6. remove Access Policy Admin and Project IAM Admin roles from user
for ROLE in "roles/iam.accessPolicyAdmin" "roles/resourcemanager.projectIamAdmin"; do
gcloud projects remove-iam-policy-binding ${PROJECT_GOVERNANCE} \
--member="user:$(gcloud config get-value account)" \
--role="${ROLE}" \
--condition=None --quiet || true
done
6. Восстановить журнал аудита и ограничения организационной политики.
# 1. Export current Central Governance IAM policy
gcloud projects get-iam-policy ${PROJECT_GOVERNANCE} --format=json > cfg/gov_iam_policy.json
# 2. Filter out iap.googleapis.com from auditConfigs
python3 -c "
import json
with open('cfg/gov_iam_policy.json') as f:
policy = json.load(f)
if 'auditConfigs' in policy:
# Remove iap.googleapis.com; if nothing else remains, clear the list
policy['auditConfigs'] = [
ac for ac in policy['auditConfigs'] if ac.get('service') != 'iap.googleapis.com'
]
with open('cfg/gov_iam_policy.json', 'w') as f:
json.dump(policy, f, indent=2)
"
# 3. Apply the updated policy to revert audit logging to default
gcloud projects set-iam-policy ${PROJECT_GOVERNANCE} cfg/gov_iam_policy.json
7. Отменить ограничения организационной политики.
# revert iam v3 access policy binding org policy on project to org level setting
gcloud org-policies delete iam.managed.disableAccessPolicyBinding --project=${PROJECT_GOVERNANCE}
8. Удалите общий промежуточный сегмент GCS и локальные артефакты.
# delete central staging bucket
gcloud storage rm -r gs://${PROJECT_GOVERNANCE}-shared-staging
# remove local configuration manifests, environment files, and application
rm -rf cfg/ cross-project-multiagent/ *.env
На этом завершается этап очистки... далее переходим к заключению !
12. Заключение
Поздравляем! Вы успешно развернули и управляете многопроектной архитектурой взаимодействия агентов (A2A) в Google Cloud, используя Vertex AI Agent Runtime, Central Agent Gateway, Agent Registry и IAM Unified Access Policies (UAP).
Краткое изложение основных понятий
- Централизованный исходящий периметр: маршрутизация периферийных контейнеров среды выполнения (
PROJECT_CONCIERGE,PROJECT_SELLERS) через центральный шлюз агентов вPROJECT_GOVERNANCEс использованиемagentGatewayConfig. - Декларативное управление (UAP): Заменены разрозненные привязки для каждого ресурса единой, подлежащей аудиту политикой доступа IAM, оцениваемой на шлюзе с помощью IAP v2.
- Криптографическая идентификация: Обеспечение минимального уровня привилегий при исходящем трафике с использованием идентификаторов SPIFFE контейнеров (
principal://...) вместо долгоживущих ключей. - Динамическое обнаружение сервисов: разрешение конечных точек агентов-партнеров во время выполнения через Центральный реестр агентов, что исключает использование жестко закодированных URL-адресов и идентификаторов проектов.
- Runtime Policy Agility: Transitioned
pizza-seller-agentfrom Default Deny (403 Forbidden) to Allowed (200 OK) in real time via policy update, with zero container restarts.

Cosmopup says: "Agents are great—they do all the cross-project work while I focus on my primary objective: napping!"
Next Steps & Documentation
- Gemini Enterprise Agent Platform Overview
- Configure and Deploy Agent Gateway
- Agent Identity & SPIFFE Attestation Deep Dive
- IAM Unified Access Policies & CEL Attributes
- Agent Registry Service Catalog Overview
- Model Armor Guardrails & Sensitive Data Protection
- Private Service Connect Interfaces (PSC-I) with Agent Gateway