مدیریت متمرکز Agent Gateway با ثبت Agent بین پروژه‌ای برای Agent Runtime

۱. مقدمه

همزمان با پذیرش هوش مصنوعی مولد توسط سازمان‌های سازمانی، معماری‌ها به سرعت از چت‌بات‌های مستقل و یکپارچه به سیستم‌های چندعاملی توزیع‌شده (عامل به عامل / A2A) در حال تکامل هستند. در این توپولوژی‌های مدرن، عامل‌های هماهنگ‌کننده سطح بالا، گردش‌های کاری پیچیده کسب‌وکار را با واگذاری وظایف به عامل‌های متخصص دامنه، سرورهای ابزار پروتکل زمینه مدل (MCP) و پایگاه‌های داده سازمانی پشتیبان در پروژه‌های مستقل Google Cloud هماهنگ می‌کنند.

با این حال، راه‌اندازی سیستم‌های چندعاملی در مقیاس بزرگ، چالش‌های امنیتی، مدیریتی و عملیاتی مهمی را به همراه دارد:

  • پراکندگی ابزار و عامل‌های سایه: وقتی تیم‌های توسعه، عامل‌ها را در پروژه‌های مجزا و بدون یک کاتالوگ متمرکز مستقر می‌کنند، سازمان‌ها دید خود را نسبت به ابزارها و زیرعامل‌های موجود از دست می‌دهند.
  • خروج بین پروژه‌های بدون نظارت: اجازه دادن به عامل‌ها برای هدایت مسیرهای شبکه بدون بازرسی، خطراتی مانند نشت داده‌ها و دور زدن مرزهای امنیتی را ایجاد می‌کند.
  • یکپارچه‌سازی‌های شکننده و سخت‌کد شده: سخت‌کد کردن URLهای عامل‌های پایین‌دستی و شناسه‌های موتور استدلال، وابستگی‌های شکننده‌ای ایجاد می‌کند که در طول ارتقاها یا استقرار مجدد از بین می‌روند.
  • فقدان هویت با حداقل امتیاز: حساب‌های کاربری سرویس اشتراکی، قابلیت عدم انکار رمزنگاری را در سطح نمونه عامل منفرد ارائه نمی‌دهند.

برای حل این چالش‌ها، پلتفرم Gemini Enterprise Agent یک صفحه کنترل و مدیریت اتصال یکپارچه متشکل از چهار ستون اصلی ارائه می‌دهد:

  1. دروازه عامل ( networkservices.googleapis.com ) : یک پروکسی مدیریت‌شده و منطقه‌ای برای شبکه و اجرای سیاست. این پروکسی که در حالت خروجی AGENT_TO_ANYWHERE عمل می‌کند، ترافیک خروجی عامل را رهگیری می‌کند، ارزیابی‌های مجوز را به افزونه‌های امنیتی واگذار می‌کند و درخواست‌ها را در محیط پروژه مسیریابی می‌کند.
  2. رجیستری عامل ( agentregistry.googleapis.com ) : کاتالوگ خدمات سازمانی واحد. این یک دایرکتوری متمرکز و بررسی‌شده از تمام ابزارهای موجود، سرورهای MCP و عامل‌های همتا در سراسر سازمان را فراهم می‌کند و امکان کشف خودکار پویا در زمان اجرا را بدون هیچ نقطه پایانی کدگذاری‌شده‌ای فراهم می‌کند.
  3. مدیریت هویت عامل و IAP نسخه ۲ ( iap.googleapis.com و iam.googleapis.com ) : یک چارچوب هویت و دسترسی رمزنگاری شده. عامل‌های اجرایی، URNهای ماشین SPIFFE منحصر به فرد و تأیید شده ( principal://... ) را دریافت می‌کنند. خروجی خروجی بر اساس سیاست‌های دسترسی یکپارچه IAM متمرکز (UAP / IAP نسخه ۲) ارزیابی می‌شود و مجوز جهانی iap.googleapis.com/resources.egressViaIAP را با استفاده از شرایط کاتالوگ غنی Common Expression Language (CEL) ( destination.agent_registry.* ) تأیید می‌کند.
  4. زمان اجرای عامل (موتورهای استدلال) : یک پلتفرم اجرایی کاملاً مدیریت‌شده و بدون سرور برای برنامه‌های عامل مبتنی بر پایتون، که شامل اتصالات پیکربندی بومی ( agent_gateway_config ) به دروازه‌های مرکزی است.

سناریوی تجاری Codelab: خرید چند پروژه‌ای مواد غذایی و آشامیدنی

در این آزمایشگاه کد، شما یک اکوسیستم خرید چند پروژه‌ای در دنیای واقعی خواهید ساخت و مدیریت خواهید کرد که شامل سه پروژه مجزای Google Cloud است:

  • پروژه مدیریت مرکزی ( PROJECT_GOVERNANCE ): متعلق به Central IT و SecOps، میزبان Central Agent Gateway، Central Agent Registry و سیاست‌های دسترسی یکپارچه IAM است.
  • پروژه هماهنگ‌کننده مصرف‌کننده ( PROJECT_CONCIERGE ): متعلق به تیم تدارکات، میزبان نماینده دربان خرید است که به صورت پویا فروشندگان را کشف کرده و سفارشات مشتری را هدایت می‌کند.
  • پروژه فروشنده دامنه ( PROJECT_SELLERS ): متعلق به فروشندگان خارجی یا دپارتمانی است که میزبان نماینده فروشنده برگر و نماینده فروشنده پیتزا است.

شکل1

شکل ۱. معماری مدیریت متمرکز چندپروژه‌ای

چرا مدیریت متمرکز بین پروژه‌ای؟

در سازمان‌های بزرگ، تیم‌های محصول و گروه‌های علوم داده، عوامل هوش مصنوعی را در ده‌ها پروژه مستقل Google Cloud ایجاد می‌کنند. دادن کنترل مستقیم به هر تیم بر ثبت ابزار، مسیرهای شبکه خروجی و گاردریل‌های امنیتی، باعث پراکندگی ابزار بررسی نشده، سیاست‌های DLP متناقض، خروجی VPC بدون نظارت و گزارش‌های حسابرسی پراکنده می‌شود.

مدیریت متمرکز بین پروژه‌ای، تدوین سیاست‌ها را از اجرای عامل‌ها جدا می‌کند:

  • متخصصان فناوری اطلاعات و امنیت مرکزی، سیاست‌های امنیتی را تدوین می‌کنند، ابزارها را بررسی می‌کنند و خروجی‌ها را در یک پروژه مدیریت متمرکز واحد، رصد می‌کنند.
  • تیم‌های محصول و برنامه در پروژه‌های مستقل Agent Runtime خود، صرفاً بر منطق کسب‌وکار تمرکز می‌کنند و مستقیماً به دروازه مرکزی متصل می‌شوند، بدون اینکه سربار عملیاتی مدیریت VPCهای محلی، اتصالات داخلی یا موتورهای سیاست‌گذاری پراکنده را متحمل شوند.

شکل ۲

شکل ۲. معماری و مرزهای مدیریت بین پروژه‌ای سه‌لایه

مدل تعیین محدوده هویت دو لایه در سیاست‌های دسترسی یکپارچه

وقتی عامل‌ها از طریق دروازه عامل مرکزی ارتباط برقرار می‌کنند، پروکسی آگاه از هویت (IAP نسخه ۲) دسترسی را بر اساس هویت عامل تماس‌گیرنده - یک هویت مبتنی بر SPIFFE که به صورت رمزنگاری‌شده تأیید شده و به طور خودکار به کانتینر زمان اجرا صادر می‌شود - در برابر یک سیاست دسترسی IAM جهانی ارزیابی می‌کند:

  • سطح ۱: APIهای پایه گوگل کلود (Coarse-Grained از طریق principalSet:// در قانون ۱): مجوز خروج در سطح پروژه که به همه زمان‌های اجرای عامل در پروژه‌های Spoke اجازه می‌دهد تا برای کشف، تولید توکن و استنتاج به APIهای استاندارد گوگل ( aiplatform ، iamcredentials ، telemetry ، agentregistry ) برسند.
  • سطح ۲: ابزارهای تجاری و سرویس‌های A2A (دقیق‌تر از طریق principal:// در قوانین ۲ و ۳): دسترسی سختگیرانه با حداقل امتیاز محدود به نمونه‌های منفرد موتور استدلال، که با شرایط زبان بیان مشترک (CEL) اعمال می‌شود و سرویس‌های رجیستری عامل ثبت‌شده خاص ( destination.agent_registry.agent.name ) را هدف قرار می‌دهد.

آنچه می‌سازید

  • دروازه عامل متمرکز ( centralized-agw ) در PROJECT_GOVERNANCE
  • افزونه سرویس احراز هویت IAP نسخه ۲ و سیاست احراز هویت در حالت سختگیرانه ENFORCE ( failOpen: false )
  • سیاست دسترسی یکپارچه بنیادی IAM ( uap-rules.json ) و الزام‌آوری سیاست پروژه
  • مجوزهای IAM برای عامل خدمات بین پروژه‌ای ( ar_agw_cross_project_sa )
  • مخزن ذخیره‌سازی ابری مرکزی مشترک (GCS) گوگل
  • نمایندگان فروش برگر و پیتزای ایزوله در PROJECT_SELLERS
  • نماینده خرید با قابلیت کشف خودکار پویای REST در PROJECT_CONCIERGE
  • ثبت خدمات در رجیستری مرکزی نمایندگان با URL های mTLS بین پروژه ای
  • به‌روزرسانی‌های پویای سیاست خروج IAP نسخه ۲ با تأیید زنده و حسابرسی‌های ثبت وقایع ابری

شکل ۳

شکل ۳. توالی پیاده‌سازی گام به گام

آنچه یاد می‌گیرید

  • نحوه پیکربندی مجوزهای IAM برای عامل سرویس بین پروژه‌ای برای دروازه‌های متمرکز
  • نحوه مسیریابی خروجی Agent Runtime از طریق یک Agent Gateway مرکزی در محیط‌های چند پروژه‌ای
  • نحوه واگذاری مجوز Agent Gateway به Identity-Aware Proxy (IAP v2) با استفاده از Service Extensions ( iapPolicyVersion: "V2" )
  • نحوه‌ی ایجاد و اتصال سیاست‌های دسترسی یکپارچه‌ی IAM (UAP) با قوانین زبان بیان مشترک (CEL) که بر مقصدهای ثبت‌شده‌ی رجیستری عامل ( destination.agent_registry.* ) حاکم هستند
  • نحوه حذف شناسه‌ها و URLهای کدشده‌ی عامل با استفاده از کشف خودکار زمان اجرا در برابر رجیستری عامل
  • نحوه آزمایش مسدودسازی اعتماد صفر در محیط واقعی ( HTTP 403 Forbidden ) و تأیید به‌روزرسانی‌های سیاست زنده در Cloud Logging

آنچه شما نیاز دارید

  • ۳ پروژه گوگل کلود با قابلیت پرداخت:
    • PROJECT_GOVERNANCE : سیاست‌های دسترسی مدیریت مرکزی، دروازه، رجیستری و IAM
    • PROJECT_CONCIERGE : نماینده هماهنگ کننده دربان خرید
    • PROJECT_SELLERS : نمایندگان فروش متخصص برگر و پیتزا
  • یک حساب کاربری یا سرویس IAM با roles/owner یا مجوزهای مدیریتی در هر ۳ پروژه
  • یک سازمان ابری گوگل (برای نگاشت دامنه اعتماد SPIFFE)
  • پوسته گوگل کلود یا یک دستگاه محلی با رابط خط فرمان gcloud ، python (۳.۱۱+) و uv نصب شده

این بخش مقدمه را به پایان می‌رساند... و در ادامه به بخش تنظیمات و محیط می‌پردازیم.

۲. راه‌اندازی

اگرچه این معماری شامل ۳ پروژه مجزای گوگل کلود می‌شود، اما می‌توانید ۱۰۰٪ دستورات استقرار ترمینال، دانلودهای مخزن و عملیات مرحله‌بندی را از یک ترمینال Cloud Shell واحد که روی PROJECT_GOVERNANCE تنظیم شده است، اجرا کنید. هر اسکریپت استقرار و دستور gcloud به صراحت پروژه مقصد مناسب را از طریق پرچم‌های CLI ( --project ) هدف قرار می‌دهد.

با دسترسی به خط فرمان پروژه Google Cloud خود شروع کنید:

زمینه پروژه خود را تنظیم کنید

# 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
# 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 نسخه ۲

به طور پیش‌فرض، Google Cloud گزارش‌های حسابرسی دسترسی به داده‌ها را غیرفعال می‌کند تا از هزینه‌های ذخیره‌سازی ناخواسته جلوگیری کند. از آنجا که IAP نسخه ۲ تصمیمات مجوز ( 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 نسخه ۳ را به منابع ( 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های گوگل (Register Core Google APIs) می‌پردازیم.

۳. ثبت نماینده

سرویس اندپوینت APIهای اصلی گوگل را ثبت کنید

Agent Gateway مستلزم آن است که URLهای API گوگل در Central Agent Registry ثبت شوند تا Agentهای پیکربندی‌شده با agent_gateway_config بتوانند ترافیک خروجی را به‌طور ایمن به سرویس‌های اصلی Google Cloud backend (مانند aiplatform ، IAM Credentials و Telemetry) هدایت کنند.

ایجاد core-gapi-services در رجیستری Agent

# 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 ، هویت‌های ماشینی که به کانتینرهای عامل اجرایی صادر می‌شوند، از URNهای SPIFFE تایید شده رمزنگاری شده که توسط Identity-Aware Proxy (IAP v2) ارزیابی می‌شوند، استفاده می‌کنند. هنگام پیکربندی سیاست‌های دسترسی یکپارچه IAM، می‌توانید یک principal واحد خاص یا یک principalSet مبتنی بر ویژگی را هدف قرار دهید:

ابعاد

principal:// (هویت تک ماشینی)

principalSet:// (گروه مبتنی بر ویژگی)

سینتکس IAM

principal://...

principalSet://...

دانه‌بندی

ریزدانه (سطح نمونه): یک نمونه کانتینر واحد و خاص Reasoning Engine را شناسایی می‌کند.

درشت-دانه (سطح پروژه): تمام موتورهای استدلالی را که یک ویژگی مشترک پروژه را به اشتراک می‌گذارند، شناسایی می‌کند.

الگوی URN

principal://agents.global.org-${ORG_ID}.system.id.goog/resources/aiplatform/projects/${PROJECT_NUMBER}/locations/${REGION}/reasoningEngines/${ENGINE_ID}

principalSet://agents.global.org-${ORG_ID}.system.id.goog/attribute.platformContainer/aiplatform/projects/${PROJECT_NUMBER}

مورد استفاده در پلتفرم عامل

سطح ۲ (ابزارهای تجاری و A2A): اعطای مجوز به عوامل هماهنگ‌کننده خاص برای فراخوانی ابزارهای دامنه هدف (مثلاً، متصدی خرید $\rightarrow$ فروشنده برگر).

سطح ۱ (زیرساخت بنیادی): اعطای دسترسی خروجی به تمام عوامل یک پروژه به APIهای Google Cloud ( core-gapi-services ).

تأثیر چرخه عمر

اگر یک عامل حذف و دوباره ایجاد شود، شناسه موتور جدید آن نیاز به به‌روزرسانی الزام‌آوری سیاست IAM دارد.

به طور خودکار برای عوامل تازه مستقر شده در آن پروژه بدون به‌روزرسانی‌های اضافی IAM اعمال می‌شود.

مدیریت اعلانی با سیاست‌های دسترسی یکپارچه (UAP / IAP نسخه ۲)

در IAP نسخه ۱ قدیمی، سیاست‌های خروجی مستقیماً با استفاده از gcloud beta iap web add-iam-policy-binding به منابع جداگانه Agent Registry متصل می‌شدند. در IAP نسخه ۲ و Unified Access Policies ، اتصالات به ازای هر منبع به نفع یک IAM Access Policy واحد و متمرکز ( cfg/uap-rules.json ) حذف شده‌اند.

مجوز خروج بنیادی برای core-gapi-services به عنوان قانون ۱ در سیاست دسترسی یکپارچه در بخش ۵ پیکربندی خواهد شد و اطمینان حاصل می‌شود که همه کانتینرهای عامل، مسیرهای خروج بنیادی را قبل از استقرار تعیین کرده‌اند.

برای جزئیات فنی عمیق‌تر در مورد شناسه‌های اصلی و مکانیک هویت بار کاری، به موارد زیر مراجعه کنید:

این پایان ثبت نام نقطه پایانی API های اصلی است... و در ادامه به بخش Deploy Centralized Agent Gateway می‌رویم.

۴. دروازه عامل

استقرار دروازه عامل متمرکز

دروازه عامل متمرکز ( 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'

این پایان استقرار دروازه است... در ادامه به بخش پیکربندی مجوزها می‌پردازیم .

۵. مجوز

پیکربندی مجوز دروازه عامل و UAP بنیادی

دروازه عامل (Agent Gateway) با استفاده از سیاست‌های مجوزدهی (authorization Policies ) ( networksecurity.authzPolicies ) که با سیاست‌های دسترسی یکپارچه (Unified Access Policies) (UAP) و پروکسی آگاه از هویت (IAP v2) یکپارچه شده‌اند، ترافیک ابزار و عامل خروجی را ایمن و مدیریت می‌کند .

بررسی اجمالی معماری مجوزدهی

شکل ۴

شکل ۴. نمای کلی معماری مجوزدهی

معماری مجوز از سه لایه به هم پیوسته تشکیل شده است:

  1. افزونه سرویس IAP ( authzExtension ) : منبع منطقه‌ای پیکربندی شده با service: iap.googleapis.com ، metadata: iapPolicyVersion: "V2" و failOpen: false برای اجرای دقیق zero-trust پیرامونی.
  2. سیاست احراز هویت دروازه ( authzPolicy ) : منبع منطقه‌ای که دروازه عامل شما را با policyProfile: REQUEST_AUTHZ و action: CUSTOM هدف قرار می‌دهد، بررسی‌های احراز هویت را به افزونه احراز هویت IAP مسیریابی می‌کند.
  3. سیاست دسترسی یکپارچه و اتصال IAM ( accessPolicy & policyBinding ) : منبع جهانی IAM نسخه ۳ که توسط IAP ارزیابی می‌شود. این منبع، مجوز جهانی iap.googleapis.com/resources.egressViaIAP را در برابر هویت‌های SPIFFE تماس‌گیرنده و شرایط کاتالوگ CEL تأیید می‌کند.

مرحله ۱: ایجاد و وارد کردن افزونه احراز هویت IAP نسخه ۲

مانیفست افزونه سرویس را با 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 Authz ارسال کنند:

# 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}

مرحله ۳: تدوین سیاست دسترسی یکپارچه اولیه (قانون ۱: APIهای اصلی گوگل)

cfg/uap-rules.json را با قانون ۱ که به سه 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

مرحله ۴: ایجاد و اتصال سیاست دسترسی 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

تأیید کنید که Policy Binding فعال است:

# 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 بین پروژه‌ای قرار دارد.

۶. مدیریت یکپارچه اطلاعات (IAM) بین پروژه‌ای

پیکربندی مجوزهای IAM بین پروژه‌ای

در این توپولوژی چند پروژه‌ای، زمان‌های اجرای عامل (Agent Runtimes) در پروژه‌های Spoke ( PROJECT_CONCIERGE و PROJECT_SELLERS ) قرار دارند، در حالی که دروازه عامل مرکزی (Central Agent Gateway) و رجیستری عامل (Agent Registry) در PROJECT_GOVERNANCE قرار دارند.

از آنجا که پروژه‌های گوگل کلود، محیط‌های امنیتی ایزوله‌ای هستند، دسترسی بین پروژه‌ای باید به صراحت در دو لایه عملیاتی اعطا شود:

  1. صفحه کنترل (زمان استقرار): هنگام استقرار یک کانتینر عامل پیکربندی شده با --agent-gateway-config ، عامل زمان اجرای پروژه Spoke مربوط به سرویس Agent ( service- @gcp-sa-aiplatform.iam.gserviceaccount.com ) باید کانتینر را به دروازه مرکزی متصل کند. ما یک نقش سفارشی حداقلی ( ar_agw_cross_project_sa ) ایجاد می‌کنیم که networkservices.agentGateways.use ، get و operations.get را در PROJECT_GOVERNANCE اعطا می‌کند.
  2. صفحه داده (اجرای زمان اجرا):
    • کشف کاتالوگ: هویت‌های Spoke برای حل و فصل پویای نقاط پایانی عامل هدف، 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"

اختصاص نقش سفارشی به Agent Runtime Service Agentها

# 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 بین پروژه‌ای است... و در ادامه به بخش استقرار فروشندگان و نمایندگان دربان می‌پردازیم .

۷. زمان اجرای عامل

استقرار نمایندگان فروشنده و متصدی

کدبیس برنامه چندعاملی و اسکریپت‌های استقرار مورد استفاده برای این Codelab در یک مخزن گیت‌هاب گوگل کلود از راه دور نگهداری می‌شوند. مراحل زیر مخزن را به صورت محلی کلون می‌کند، فایل‌های لازم را در ساختار دایرکتوری کاری فعلی کپی می‌کند، فایل‌های موقت را پاکسازی می‌کند و وابستگی‌ها را با 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)

از آنجا که قانون ۱ قبلاً در سیاست دسترسی یکپارچه ما وضع شده است، درخواست‌های اولیه‌سازی کانتینر به 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 و اتصال به پروژه مدیریت عامل Gateway را نشان دهد.

{
  "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"
    }
  }
}

این پایان استقرار نمایندگان است... در ادامه به بخش ثبت نمایندگان در بخش ثبت نمایندگان مرکزی می‌پردازیم.

۸. ثبت بین پروژه‌ای

ثبت نمایندگان در دفتر ثبت مرکزی نمایندگان

هر سه عامل را با استفاده از نقاط پایانی mTLS منطقه‌ای بین پروژه‌ای و شماره‌های عددی پروژه، در رجیستری عامل مرکزی در PROJECT_GOVERNANCE ثبت کنید.

ثبت خدمات به عنوان نمایندگان غیر 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» می‌رویم .

۹. سیاست‌های UAP

پیکربندی سیاست‌های خروجی A2A در Unified Access Policy

تحت معماری پیش‌فرض رد درخواست Agent Gateway در حالت سختگیرانه‌ی ENFORCE :

  1. قانون ۱ (APIهای پایه گوگل کلود): به کانتینرهای عامل در هر ۳ پروژه اجازه می‌دهد تا به core-gapi-services دسترسی پیدا کنند.
  2. قانون ۲ (نماینده فروشنده برگر: مجاز): به نمونه نماینده دربان خرید اجازه می‌دهد تا به طور خاص نماینده فروشنده برگر را فراخوانی کند.
  3. نماینده فروشنده پیتزا (به طور پیش‌فرض رد شده): عمداً از قوانین خط‌مشی حذف شده است. در حالت 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}"

مانیفست را با قانون ۱ و ۲ به‌روزرسانی کنید

فایل جدید cfg/uap-rules-update-2.json را ایجاد کنید تا قانون ۱ (APIهای اصلی) و حالا قانون ۲ (نماینده فروشنده برگر) را شامل شود:

# 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

این پایان تنظیمات سیاست است... در ادامه به بخش «آزمایش و تأیید سیاست‌های مدیریتی» می‌پردازیم.

۱۰. سیاست‌ها را تأیید کنید

تست و تأیید سیاست‌های مدیریتی از طریق ثبت وقایع ابری

در این بخش، شما تعاملات بین پروژه‌ای عامل به عامل (A2A) را در Agent Runtime AI Playground آزمایش خواهید کرد، انسداد HTTP 403 Forbidden را در حالت ENFORCE دقیق در محیط واقعی مشاهده خواهید کرد، سیاست دسترسی یکپارچه را به صورت زنده تغییر خواهید داد و تأیید فوری سفارش را اعتبارسنجی خواهید کرد.

مرحله 1: زمین بازی هوش مصنوعی Open Agent Runtime در PROJECT_CONCIERGE

  1. کنسول ابری گوگل را باز کنید.
  2. در نوار انتخاب پروژه بالا، به PROJECT_CONCIERGE بروید.
  3. در منوی پیمایش، به مسیر Agent Platform > Agents > Deployments بروید.
  4. روی purchasing-concierge-adk کلیک کنید.
  5. برای باز کردن رابط چت تعاملی در سمت راست صفحه، Playground را انتخاب کنید.

مرحله ۲: سفارش برگر آزمایشی (مطابقت با قانون ۲ -> ۲۰۰ OK)

در پنجره چت Playground، درخواست سفارش زیر را ارسال کنید:

I would like 10 Classic Cheeseburgers. Place this order now.

و اگر نیاز به پاسخ تأیید بود، پاسخ زیر را ارسال کنید:

Confirmed, please place the order.

روش دیگر، تست برنامه‌نویسی از Cloud Shell / terminal است:

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'])
"

پشت صحنه چه اتفاقی می‌افتد:

  1. کشف پویا: در طول شروع جلسه، متصدی خرید، رجیستری مرکزی عامل را در PROJECT_GOVERNANCE (از طریق core-gapi-services از طریق Agent Gateway مجاز توسط قانون 1) جستجو کرد تا نقطه پایانی mTLS منطقه‌ای را برای burger-seller-agent کشف کند.
  2. حل قصد و فراخوانی A2A: Gemini در داخل بخش خرید، قصد سفارش غذا را تجزیه و تحلیل می‌کند و از طریق یک RPC خروجی به https://${REGION}-aiplatform.mtls.googleapis.com/.../reasoningEngines/${BURGER_ENGINE_ID} نماینده فروش برگر را فراخوانی می‌کند.
  3. رهگیری دروازه و انتشار SPIFFE: ترافیک خروجی توسط agent_gateway_config دریافت شده و به دروازه عامل مرکزی در PROJECT_GOVERNANCE هدایت می‌شود که حامل هویت رمزنگاری‌شده SPIFFE متصدی ( principal://... ) است.
  4. ارزیابی سیاست IAP نسخه ۲: دروازه عامل مرکزی، افزونه مجوز IAP ( authzExtension ) را فراخوانی می‌کند. IAP نسخه ۲، قانون ۲ را در سیاست دسترسی یکپارچه IAM ارزیابی می‌کند. از آنجا که فراخواننده با ${CONCIERGE_SPIFFE_PRINCIPAL} مطابقت دارد و هدف با burger-seller-agent مطابقت دارد، IAP ALLOW ( granted: true ) را برمی‌گرداند.
  5. اجرای بین پروژه‌ای: Agent Gateway درخواست مجاز را به صورت بین پروژه‌ای به PROJECT_SELLERS پروکسی می‌کند، جایی که موتور استدلال فروشنده برگر سفارش را پردازش کرده و تأیید را برمی‌گرداند.

پاسخ مورد انتظار:

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

مرحله ۳: بررسی لاگ‌های حسابرسی Agent Gateway و IAP v2 (HTTP 200 / مجاز)

گزارش‌های درخواست مربوط به درگاه درخواست نماینده‌ی پرس‌وجو در 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
  )"

این گزارش‌ها باید ترافیک خروجی ناشی از هر دو پروژه Spoke ( PROJECT_CONCIERGE و PROJECT_SELLERS ) را به همراه فیلدهای خروجی برای فراخوانی‌های استدلال Gemini ( generateContent )، تله‌متری Cloud Trace ( /v1/traces ) و جستجوی اعتبارنامه‌های IAM ثبت کنند - که به طور شفاف توسط قانون 1 ( core-gapi-services ) رهگیری و تأیید می‌شوند.

برای تأیید نسخه خط‌مشی POLICY_VERSION_V2 لاگ‌های IAP v2 Cloud Audit Data Access را جستجو کنید:

# 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

مرحله ۴: تست سفارش پیتزا (پیش‌فرض رد -> HTTP 403 ممنوع اعمال شده)

در همان پنجره چت Playground، فرم سفارش پیتزای زیر را ارسال کنید:

I would like 10 BBQ Chicken Pizzas. Place this order now.

و اگر نیاز به پاسخ تأیید بود، پاسخ زیر را ارسال کنید:

Confirmed, please place the order.

روش دیگر، تست برنامه‌نویسی از Cloud Shell / terminal است:

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.

پشت صحنه چه اتفاقی می‌افتد:

  1. کشف پویا: متصدی خرید، مشکل نقطه پایانی pizza-seller-agent را از رجیستری مرکزی نمایندگان در هنگام راه‌اندازی حل کرد.
  2. حل قصد و فراخوانی A2A: Gemini درون Purchasing Concierge تلاش می‌کند تا درخواست سفارش پیتزا را به نقطه پایانی Pizza Seller در PROJECT_SELLERS ارسال کند.
  3. رهگیری دروازه: RPC خروجی توسط agent_gateway_config ضبط شده و به دروازه عامل مرکزی هدایت می‌شود.
  4. ارزیابی سیاست IAP نسخه ۲ (پیش‌فرض رد): دروازه عامل مرکزی، IAP نسخه ۲ را فراخوانی می‌کند. از آنجا که هیچ قانونی در سیاست دسترسی یکپارچه با pizza-seller-agent مطابقت ندارد، IAP مقدار DENY ( granted: false ) را برمی‌گرداند.
  5. مسدودسازی دقیق پیرامونی: از آنجا که افزونه‌ی احراز هویت در حالت ENFORCE ( failOpen: false ) قرار دارد، دروازه‌ی عامل مرکزی بلافاصله اتصال خروجی را قطع کرده و HTTP 403 Forbidden را برمی‌گرداند. ترافیک هرگز از دروازه خارج نمی‌شود و هرگز به PROJECT_SELLERS نمی‌رسد.

مرحله ۵: بررسی لاگ‌های Agent Gateway برای درخواست‌های مسدود شده (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 نسخه ۲ را برای تصمیم رد شده جستجو کنید:

# 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 دسترسی خروجی (Egress Access) بدهید

فایل جدید cfg/uap-rules-update-3.json را ایجاد کنید تا قانون ۱ (APIهای اصلی)، قانون ۲ (نماینده فروشنده برگر) و حالا قانون ۳ (نماینده فروشنده پیتزا) را شامل شود.

# 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

مرحله ۷: دوباره از نماینده پیتزا پرس و جو کنید (فوری، ۲۰۰ تایید موفقیت‌آمیز)

در پنجره چت Playground، درخواست سفارش پیتزا را دوباره ارسال کنید:

I would like 10 BBQ Chicken Pizzas. Place this order now.

و اگر نیاز به پاسخ تأیید بود، پاسخ زیر را ارسال کنید:

Confirmed, please place the order.

روش دیگر، تست برنامه‌نویسی از Cloud Shell / terminal است:

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**

پشت صحنه چه اتفاقی می‌افتد:

  1. به‌روزرسانی پویای سیاست دسترسی یکپارچه IAM: به‌روزرسانی سیاست دسترسی یکپارچه IAM بلافاصله در موتور ارزیابی IAP و بدون هیچگونه خرابی و بدون نیاز به استقرار مجدد هیچ کانتینری اعمال می‌شود.
  2. فراخوانی A2A: متصدی درخواست را از طریق دروازه عامل مرکزی ارسال می‌کند.
  3. ارزیابی سیاست IAP نسخه ۲ (تأیید): IAP نسخه ۲ با قانون ۳ مطابقت دارد، هویت فراخواننده و عبارت CEL هدف را تأیید می‌کند و ALLOW ( granted: true ) را برمی‌گرداند.
  4. اجرای بین پروژه‌ای: دروازه عامل مرکزی، ترافیک مجاز را به PROJECT_SELLERS ، جایی که پیتزافروش سفارش را پردازش می‌کند، پروکسی می‌کند.

مرحله ۸: بررسی لاگ‌های Agent Gateway برای درخواست‌های پیتزای پذیرفته‌شده

# 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

این پایان آزمایش و تأیید است... در ادامه به بخش پاکسازی می‌پردازیم.

۱۱. پاکسازی

برای جلوگیری از تحمیل هزینه به حساب Google Cloud خود برای منابع مورد استفاده در این Codelab، مراحل جداسازی را به ترتیب وابستگی معکوس انجام دهید:

۱. پاکسازی استقرارهای موتور استدلال

اسکریپت 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()
'

۲. سرویس‌های رجیستری عامل را حذف کنید

# 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

۳. حذف اتصال سیاست دسترسی یکپارچه 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

۴. حذف دروازه عامل و سیاست‌های امنیتی

# 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

۵. حذف IAM Bindingهای بین پروژه‌ای و نقش سفارشی

# 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

۶. محدودیت‌های ثبت داده‌های حسابرسی و سیاست‌های سازمانی را برگردانید

# 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

۷. محدودیت‌های سیاست‌های سازمانی را برگردانید

# revert iam v3 access policy binding org policy on project to org level setting
gcloud org-policies delete iam.managed.disableAccessPolicyBinding --project=${PROJECT_GOVERNANCE}

۸. حذف سطل مرحله‌بندی مشترک 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

این بخش پاکسازی را به پایان می‌رساند... و بعد از نتیجه‌گیری !

۱۲. نتیجه‌گیری

تبریک! شما یک معماری چند پروژه‌ای عامل به عامل (A2A) را در Google Cloud با استفاده از Vertex AI Agent Runtime، Central Agent Gateway، Agent Registry و IAM Unified Access Policies (UAP) مستقر و مدیریت کرده‌اید.

خلاصه مفاهیم کلیدی

  • محیط خروجی متمرکز: کانتینرهای زمان اجرای اسپوک ( PROJECT_CONCIERGE ، PROJECT_SELLERS ) از طریق یک دروازه عامل مرکزی در PROJECT_GOVERNANCE با استفاده از agentGatewayConfig مسیریابی می‌شوند.
  • Declarative Governance (UAP): Replaced fragmented per-resource bindings with a single, auditable IAM Access Policy evaluated at the gateway by IAP v2.
  • Cryptographic Identity: Enforced least-privilege egress using container SPIFFE identities ( principal://... ) rather than long-lived keys.
  • Dynamic Service Discovery: Resolved peer agent endpoints at runtime via Central Agent Registry, eliminating hardcoded URLs and project IDs.
  • Runtime Policy Agility: Transitioned pizza-seller-agent from Default Deny ( 403 Forbidden ) to Allowed ( 200 OK ) in real time via policy update, with zero container restarts.

cosmopup

Cosmopup says: "Agents are great—they do all the cross-project work while I focus on my primary objective: napping!"

Next Steps & Documentation