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

۱. مقدمه

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

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

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

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

  1. دروازه عامل (networkservices.googleapis.com): پراکسی مدیریت‌شده، منطقه‌ای، و اجرای خط‌مشی. این میان‌افزار که در حالت خروجی AGENT_TO_ANYWHERE کار می‌کند، ترافیک خروجی عامل را رهگیری می‌کند، ارزیابی‌های مجوز را به افزونه‌های امنیتی واگذار می‌کند، و درخواست‌ها را در سراسر محیط‌های پروژه مسیریابی می‌کند.
  2. Agent Registry (agentregistry.googleapis.com): کاتالوگ سرویس سازمانی واحد. این راهنما یک فهرست متمرکز و تأییدشده از همه ابزارهای دردسترس، سرورهای MCP، و عامل‌های همتا در سراسر سازمان ارائه می‌دهد که امکان کشف خودکار زمان اجرای پویا را با نقطه‌های پایانی بدون کدگذاری سخت فراهم می‌کند.
  3. Agent Identity & IAP v2 Governance (iap.googleapis.com & iam.googleapis.com): چارچوب دسترسی و هویت رمزنگاری‌شده. عوامل اجرایی URNهای ماشین SPIFFE گواهی‌شده و منحصربه‌فرد (principal://...) دریافت می‌کنند. خروجی برون‌مرزی دربرابر خط‌مشی‌های دسترسی یکپارچه IAM (UAP / IAP v2) متمرکز ارزیابی می‌شود و اجازه جهانی iap.googleapis.com/resources.egressViaIAP را بااستفاده از شرایط کاتالوگ غنی «زبان عبارت مشترک» (CEL) (destination.agent_registry.*) تأیید می‌کند.
  4. Agent Runtime (Reasoning Engines): یک پلاتفرم اجرای بدون سرور کاملاً مدیریت‌شده برای برنامه‌های عامل‌محور مبتنی بر Python، با اتصال‌های پیکربندی بومی (agent_gateway_config) به درگاه‌های مرکزی.

سناریوی کسب‌وکار Codelab: خرید غذا و نوشیدنی چندپروژه‌ای

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

  • پروژه حاکمیت مرکزی (PROJECT_GOVERNANCE): تحت مالکیت Central IT و SecOps، میزبان Central Agent Gateway،‏ Central Agent Registry، و IAM Unified Access Policies.
  • پروژه Consumer Orchestrator (PROJECT_CONCIERGE): متعلق به تیم تدارکات، میزبان Purchasing Concierge Agent که به‌طور پویا فروشندگان را کشف می‌کند و سفارش‌های مشتری را هدایت می‌کند.
  • پروژه فروشنده دامنه (PROJECT_SELLERS): تحت مالکیت فروشندگان خارجی یا دپارتمانی، میزبان عامل فروشنده برگر و عامل فروشنده پیتزا.

figure1

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

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

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

حاکمیت متمرکز بین‌پروژه‌ای نوشتن خط‌مشی را از اجرای عامل جدا می‌کند:

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

figure2

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

مدل محدوده هویت دو سطحی در خط‌مشی‌های دسترسی یکپارچه

وقتی کارگزاران ازطریق «دروازه کارگزار مرکزی» ارتباط برقرار می‌کنند، «میانای هویت‌آگاه» (IAP v2) دسترسی را براساس هویت کارگزار تماس‌گیرنده (هویتی مبتنی بر SPIFFE که ازنظر رمزنگاری تأیید شده و به‌طور خودکار برای ظرف زمان اجرا صادر می‌شود) درمقابل «خط‌مشی دسترسی IAM» جهانی ارزیابی می‌کند:

  • سطح ۱: میاناهای برنامه‌سازی کاربردی Google Cloud پایه (درشت‌دانه ازطریق principalSet:// در قانون ۱): مجوز خروج در سطح پروژه که به همه زمان‌های اجرای عامل در پروژه‌های اقماری اجازه می‌دهد به میاناهای برنامه‌سازی کاربردی Google استاندارد (aiplatform، iamcredentials، telemetry، agentregistry) برای کاوش، تولید کد، و استنتاج دسترسی داشته باشند.
  • سطح ۲: ابزارهای کسب‌وکار و سرویس‌های A2A (دقیق ازطریق principal:// در قوانین ۲ و ۳): دسترسی سخت‌گیرانه با کمترین امتیاز محدود به نمونه‌های Reasoning Engine مجزا، که با شرایط Common Expression Language (CEL)‎ که سرویس‌های Agent Registry ثبت‌شده خاصی (destination.agent_registry.agent.name) را هدف قرار می‌دهند اعمال می‌شود.

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

  • درگاه عامل متمرکز (centralized-agw) در PROJECT_GOVERNANCE
  • افزونه سرویس مجوز IAP v2 و خط‌مشی Authz در حالت سخت‌گیرانه ENFORCE (failOpen: false)
  • خط‌مشی دسترسی یکپارچه IAM بنیادی (uap-rules.json) و اتصال خط‌مشی پروژه
  • اجازه‌های IAM عامل سرویس بین‌پروژه‌ای (ar_agw_cross_project_sa)
  • مخزن آماده‌سازی مشترک مرکزی Google Cloud Storage (GCS)
  • عامل‌های فروشنده برگر و پیتزا در PROJECT_SELLERS
  • نماینده دربان خرید با کشف خودکار REST پویا در PROJECT_CONCIERGE
  • ثبت سرویس‌ها در «دفتر ثبت مرکزی نماینده» با نشانی‌های وب mTLS بین‌پروژه‌ای
  • به‌روزرسانی‌های خط‌مشی خروجی Dynamic IAP v2 با درستی‌سنجی زنده و ممیزی‌های Cloud Logging

figure3

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

آنچه می‌آموزید

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

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

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

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

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

اگرچه این معماری ۳ پروژه Google Cloud متمایز را دربرمی‌گیرد، می‌توانید ۱۰۰٪ فرمان‌های استقرار پایانه، بارگیری‌های مخزن، و عملیات آماده‌سازی را از یک پایانه 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

فعال کردن «گزارش‌های دسترسی به داده‌های حسابرسی Cloud» برای 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)"

فعال کردن میاناهای برنامه‌سازی کاربردی 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

اعتبارسنجی فعال‌سازی «میانای برنامه‌سازی کاربردی» در همه پروژه‌ها

اطمینان از اینکه هر سه پروژه (PROJECT_GOVERNANCE، PROJECT_CONCIERGE، و PROJECT_SELLERS) دقیقاً میاناهای برنامه‌سازی کاربردی یکسانی را فعال کرده‌اند، ثبات عملیاتی ایجاد می‌کند و از خرابی‌های ضرب توکن زمان اجرا، خطاهای فهرست‌بندی طرح‌واره، یا قطع شدن دورسنجی جلوگیری می‌کند.

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

# 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

نمونه برونداد اعتبارسنجی:

باید همه میاناهای برنامه‌سازی کاربردی را فعال ببینید.

✅ All 30 required APIs are ENABLED and synchronized across all three projects.

پیکربندی خط‌مشی‌های سازمان

خط‌مشی‌های پیش‌فرض سازمان Google Cloud محدودیت‌هایی را اعمال می‌کنند که اتصال‌های خط‌مشی دسترسی IAM v3 به منابع را محدود می‌کند (constraints/iam.managed.disableAccessPolicyBinding).

با تنظیم صریح enforce: false روی «مجاز»، هرگونه محدودیت خط‌مشی سازمان موروثی را در سطح پروژه لغو کنید.

# 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

بخش راه‌اندازی در اینجا به‌پایان می‌رسد... در ادامه به بخش ثبت میاناهای برنامه‌سازی کاربردی اصلی Google می‌رویم.

۳. Agent Registry

ثبت سرویس نقطه پایان میاناهای برنامه‌سازی کاربردی اصلی Google

«دروازه عامل» نیاز دارد که نشانی‌های وب Google API در «دفتر ثبت مرکزی عامل» ثبت شوند تا عامل‌های پیکربندی‌شده با agent_gateway_config بتوانند ترافیک خروجی را به‌طور ایمن به سرویس‌های اصلی Google Cloud (مانند aiplatform، «اعتبارنامه‌های IAM»، و «دورسنجی») هدایت کنند.

ایجاد core-gapi-services در Agent Registry

# 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://cloudresourcemanager.googleapis.com:443 \
  --interfaces=protocolBinding=JSONRPC,url=https://cloudresourcemanager.mtls.googleapis.com \
  --interfaces=protocolBinding=JSONRPC,url=https://cloudresourcemanager.mtls.googleapis.com:443 \
  --interfaces=protocolBinding=JSONRPC,url=https://iamcredentials.googleapis.com \
  --interfaces=protocolBinding=JSONRPC,url=https://iamcredentials.googleapis.com:443 \
  --interfaces=protocolBinding=JSONRPC,url=https://iamcredentials.mtls.googleapis.com \
  --interfaces=protocolBinding=JSONRPC,url=https://iamcredentials.mtls.googleapis.com:443 \
  --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

Capture Core APIs Endpoint Resource ID

# 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 مبتنی بر مشخصه را هدف قرار دهید:

ابعاد

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}

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

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

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

تأثیر چرخه حیات

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

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

Declarative Governance with Unified Access Policies (UAP / IAP v2)

در IAP v1 قدیمی، خط‌مشی‌های خروج مستقیماً بااستفاده از gcloud beta iap web add-iam-policy-binding به منابع Agent Registry تکی پیوست می‌شدند. تحت IAP v2 و خط‌مشی‌های دسترسی یکپارچه، اتصال‌های هر منبع به‌نفع یک خط‌مشی دسترسی IAM متمرکز (cfg/uap-rules.json) حذف می‌شوند.

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

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

ثبت نقطه پایانی میاناهای برنامه‌سازی کاربردی اصلی در اینجا به‌پایان می‌رسد... در مرحله بعد به بخش استقرار درگاه عامل متمرکز می‌رویم.

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

پیاده‌سازی کردن «دروازه عامل متمرکز»

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

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

۵. صدور مجوز

پیکربندی کردن «مجوز درگاه نماینده» و «خط‌مشی دسترسی کاربر بنیادی»

«دروازه عامل» بااستفاده از خط‌مشی‌های مجوز (networksecurity.authzPolicies) که با خط‌مشی‌های دسترسی یکپارچه (UAP) در Identity-Aware Proxy (IAP نسخه ۲) ادغام شده است، ترافیک عامل و ابزار برون‌سو را ایمن و کنترل می‌کند.

نمای کلی معماری صدور مجوز

figure4

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

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

  1. افزونه سرویس IAP (authzExtension): منبع منطقه‌ای پیکربندی‌شده با service: iap.googleapis.com، metadata: iapPolicyVersion: "V2"، و failOpen: false برای اجرای سخت‌گیرانه محیط اعتماد صفر.
  2. خط‌مشی مجوز درگاه (authzPolicy): منبع منطقه‌ای که «درگاه عامل» شما را با policyProfile: REQUEST_AUTHZ و action: CUSTOM هدف‌یابی می‌کند و بررسی‌های مجوز مسیریابی را به «افزونه مجوز IAP» ارسال می‌کند.
  3. IAM Unified Access Policy & Binding (accessPolicy & policyBinding): Global IAM v3 resource evaluated by IAP. این خط‌مشی اجازه جهانی iap.googleapis.com/resources.egressViaIAP را دربرابر هویت‌های SPIFFE تماس‌گیرنده و شرایط کاتالوگ CEL درستی‌سنجی می‌کند.

مرحله ۱: ایجاد و وارد کردن افزونه IAP v2 Authz

مانیفست «افزونه سرویس» را با 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

مرحله ۲: ایجاد و وارد کردن خط‌مشی مجوز درگاه

پیکربندی «خط‌مشی مجوز» ایجاد کنید که به «دروازه عامل» متصل شود و درستی‌سنجی درخواست را به «افزونه 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}

مرحله ۳: نوشتن «خط‌مشی دسترسی یکپارچه اولیه» (قانون ۱: Google APIs اصلی)

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

تأیید کنید که «اتصال خط‌مشی» فعال است:

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

‫Foundational Google Cloud API egress اکنون در هر سه پروژه در حالت سخت‌گیرانه ENFORCE به‌طور ایمن مجاز شده است.

راه‌اندازی مجوز درگاه در اینجا به‌پایان می‌رسد... در ادامه به بخش پیکربندی اجازه‌های IAM بین‌پروژه‌ای می‌رویم.

‫۶. IAM بین پروژه‌ای

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

در این توپولوژی چندپروژه‌ای، «زمان‌های اجرای عامل» در پروژه‌های اقماری (PROJECT_CONCIERGE و PROJECT_SELLERS) قرار دارند، درحالی‌که «دروازه عامل مرکزی» و «ثبت عامل» در PROJECT_GOVERNANCE قرار دارند.

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

  1. صفحه کنترل (زمان استقرار): هنگام استقرار محفظه عاملی که با --agent-gateway-config پیکربندی شده است، نماینده سرویس زمان اجرای عامل (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 نیاز دارند تا نقاط پایانی عامل هدف را به‌طور پویا حل‌وفصل کنند.
    • فراخوانی هدف: عامل «دربان» به 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 بین‌پروژه‌ای را به پایان می‌رساند... در ادامه به بخش استقرار نمایندگان فروشنده و دربان می‌رویم.

‫۷. Agent Runtime

استقرار «نماینده فروشنده» و «نماینده دربان»

پایگاه کد برنامه چندعاملی و اسکریپت‌های استقرار استفاده‌شده برای این Codelab در مخزن Google Cloud GitHub ازراه‌دور نگهداری می‌شوند. مراحل زیر مخزن را به‌صورت محلی شبیه‌سازی می‌کند، فایل‌های ضروری را در ساختار دایرکتوری کاری فعلی کپی می‌کند، فایل‌های موقت را پاک‌سازی می‌کند، و وابستگی‌ها را با uv نصب می‌کند.

واکشی آرتیفکت‌های ازراه‌دور

# clone remote repository to temp local dir
git clone https://github.com/GoogleCloudPlatform/cloud-networking-solutions.git ./temp_agw_multiproject
# copy multi-agent application files to current working directory
cp -r temp_agw_multiproject/codelabs/agw-multiproject ./cross-project-multiagent
# remove temporary directory
rm -rf temp_agw_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)

چون قانون ۱ زودتر در «خط‌مشی دسترسی یکپارچه» ما ایجاد شده است، درخواست‌های مقداردهی اولیه محفظه به میاناهای برنامه‌سازی کاربردی 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}'

خروجی باید هویت زمان اجرای نماینده «دربان» و پروژه و اتصال به «دروازه نماینده» پروژه «حاکمیت» را نشان دهد.

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

این بخش مربوط به استقرار عامل‌ها است... بخش بعدی ثبت عامل‌ها در دفتر ثبت مرکزی عامل‌ها است.

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

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

هر سه عامل را در «دفتر ثبت مرکزی عامل» در 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.googleapis.com/v1/projects/${PROJECT_NUMBER_SELLERS}/locations/${REGION}/reasoningEngines/${BURGER_ENGINE_ID}:query \
  --interfaces=protocolBinding=JSONRPC,url=https://${REGION}-aiplatform.googleapis.com/v1beta1/projects/${PROJECT_NUMBER_SELLERS}/locations/${REGION}/reasoningEngines/${BURGER_ENGINE_ID}:query \
  --interfaces=protocolBinding=JSONRPC,url=https://${REGION}-aiplatform.googleapis.com:443/v1/projects/${PROJECT_NUMBER_SELLERS}/locations/${REGION}/reasoningEngines/${BURGER_ENGINE_ID}:query \
  --interfaces=protocolBinding=JSONRPC,url=https://${REGION}-aiplatform.googleapis.com:443/v1beta1/projects/${PROJECT_NUMBER_SELLERS}/locations/${REGION}/reasoningEngines/${BURGER_ENGINE_ID}:query \
  --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 \
  --interfaces=protocolBinding=JSONRPC,url=https://${REGION}-aiplatform.mtls.googleapis.com:443/v1/projects/${PROJECT_NUMBER_SELLERS}/locations/${REGION}/reasoningEngines/${BURGER_ENGINE_ID}:query \
  --interfaces=protocolBinding=JSONRPC,url=https://${REGION}-aiplatform.mtls.googleapis.com:443/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.googleapis.com/v1/projects/${PROJECT_NUMBER_SELLERS}/locations/${REGION}/reasoningEngines/${PIZZA_ENGINE_ID}:query \
  --interfaces=protocolBinding=JSONRPC,url=https://${REGION}-aiplatform.googleapis.com/v1beta1/projects/${PROJECT_NUMBER_SELLERS}/locations/${REGION}/reasoningEngines/${PIZZA_ENGINE_ID}:query \
  --interfaces=protocolBinding=JSONRPC,url=https://${REGION}-aiplatform.googleapis.com:443/v1/projects/${PROJECT_NUMBER_SELLERS}/locations/${REGION}/reasoningEngines/${PIZZA_ENGINE_ID}:query \
  --interfaces=protocolBinding=JSONRPC,url=https://${REGION}-aiplatform.googleapis.com:443/v1beta1/projects/${PROJECT_NUMBER_SELLERS}/locations/${REGION}/reasoningEngines/${PIZZA_ENGINE_ID}:query \
  --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 \
  --interfaces=protocolBinding=JSONRPC,url=https://${REGION}-aiplatform.mtls.googleapis.com:443/v1/projects/${PROJECT_NUMBER_SELLERS}/locations/${REGION}/reasoningEngines/${PIZZA_ENGINE_ID}:query \
  --interfaces=protocolBinding=JSONRPC,url=https://${REGION}-aiplatform.mtls.googleapis.com:443/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.googleapis.com/v1/projects/${PROJECT_NUMBER_CONCIERGE}/locations/${REGION}/reasoningEngines/${CONCIERGE_ENGINE_ID}:query \
  --interfaces=protocolBinding=JSONRPC,url=https://${REGION}-aiplatform.googleapis.com/v1beta1/projects/${PROJECT_NUMBER_CONCIERGE}/locations/${REGION}/reasoningEngines/${CONCIERGE_ENGINE_ID}:query \
  --interfaces=protocolBinding=JSONRPC,url=https://${REGION}-aiplatform.googleapis.com:443/v1/projects/${PROJECT_NUMBER_CONCIERGE}/locations/${REGION}/reasoningEngines/${CONCIERGE_ENGINE_ID}:query \
  --interfaces=protocolBinding=JSONRPC,url=https://${REGION}-aiplatform.googleapis.com:443/v1beta1/projects/${PROJECT_NUMBER_CONCIERGE}/locations/${REGION}/reasoningEngines/${CONCIERGE_ENGINE_ID}:query \
  --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 \
  --interfaces=protocolBinding=JSONRPC,url=https://${REGION}-aiplatform.mtls.googleapis.com:443/v1/projects/${PROJECT_NUMBER_CONCIERGE}/locations/${REGION}/reasoningEngines/${CONCIERGE_ENGINE_ID}:query \
  --interfaces=protocolBinding=JSONRPC,url=https://${REGION}-aiplatform.mtls.googleapis.com:443/v1beta1/projects/${PROJECT_NUMBER_CONCIERGE}/locations/${REGION}/reasoningEngines/${CONCIERGE_ENGINE_ID}:query

Capture Underlying Agent Registry IDs

# 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 در «خط‌مشی دسترسی یکپارچه»

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

  1. قانون ۱ (میاناهای برنامه‌سازی کاربردی Google Cloud پایه): به محفظه‌های عامل در هر ۳ پروژه اجازه می‌دهد به 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}"

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

برای به‌روزرسانی ایمن خط‌مشی دسترسی بدون ازبین بردن قوانین موجود، مانیفست تلفیقی کامل حاوی قانون ۱ (میاناهای برنامه‌سازی کاربردی اصلی Google) و قانون ۲ (نماینده فروشنده برگر) را تعریف کنید:

# create consolidated policy manifest with Rule 1 and Rule 2
cat > cfg/uap-rules-consolidated.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}')"
      }
    }
  },
  {
    "description": "Rule 2: Allow Purchasing Concierge to invoke Burger Seller Agent via Central Gateway",
    "effect": "ALLOW",
    "principals": [
      "${CONCIERGE_SPIFFE_PRINCIPAL}",
      "principal://agents.global.org-${ORG_ID}.system.id.goog/attribute.agentIdentity/projects/${PROJECT_NUMBER_CONCIERGE}/locations/${REGION}/reasoningEngines/${CONCIERGE_ENGINE_ID}",
      "principalSet://agents.global.org-${ORG_ID}.system.id.goog/attribute.agentIdentity/projects/${PROJECT_NUMBER_CONCIERGE}/locations/${REGION}/reasoningEngines/${CONCIERGE_ENGINE_ID}"
    ],
    "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

اعمال خط‌مشی دسترسی به‌روزشده

مانیفست قوانین ادغام‌شده را به‌صورت اعلانی بااستفاده از --details-rules اعمال کنید:

# update IAM access policy with consolidated manifest (Rule 1 + Rule 2)
gcloud iam access-policies update ${UAP_POLICY_NAME} \
  --details-rules=cfg/uap-rules-consolidated.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

راه‌اندازی خط‌مشی به پایان رسید... در مرحله بعد به بخش آزمایش و درستی‌سنجی خط‌مشی‌های حاکمیت می‌رویم.

‫۱۰. به‌تأیید رساندن خط‌مشی‌ها

آزمایش و درستی‌سنجی خط‌مشی‌های حاکمیت ازطریق Cloud Logging

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

مرحله ۱: باز کردن «زمین بازی هوش مصنوعی زمان اجرای نماینده» در PROJECT_CONCIERGE

  1. کنسول Google Cloud را باز کنید.
  2. در نوار انتخابگر پروژه در بالا، به PROJECT_CONCIERGE بروید.
  3. در منو پیمایش، به پلاتفرم نماینده > نمایندگان > استقرارها بروید.
  4. روی purchasing-concierge-adk کلیک کنید.
  5. زمین بازی را انتخاب کنید تا میانای گپ تعاملی در سمت راست صفحه‌نمایش باز شود.

مرحله ۲: سفارش همبرگر آزمایشی (مطابقت قانون ۲ -> ۲۰۰ 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'])
"

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

  1. کاوش پویا: درطول راه‌اندازی جلسه، «دربان خرید» از «دفتر ثبت مرکزی نماینده» در PROJECT_GOVERNANCE (ازطریق core-gapi-services ازطریق «دروازه نماینده» که توسط «قانون ۱» مجاز شده است) پرس‌وجو کرد تا نقطه پایانی mTLS منطقه‌ای را برای burger-seller-agent کاوش کند.
  2. حل‌وفصل قصد و فراخوانی عامل به عامل: Gemini در «دربان خرید» قصد سفارش غذا را تجزیه می‌کند و «عامل برگر فروشی» را ازطریق یک RPC برون‌مرزی به https://${REGION}-aiplatform.mtls.googleapis.com/.../reasoningEngines/${BURGER_ENGINE_ID} فراخوانی می‌کند.
  3. رهگیری درگاه و انتشار SPIFFE: ترافیک خروجی توسط agent_gateway_config ضبط می‌شود و به «درگاه عامل مرکزی» در PROJECT_GOVERNANCE هدایت می‌شود، که حامل هویت SPIFFE رمزنگاری‌شده Concierge (principal://...) است.
  4. ارزیابی خط‌مشی IAP نسخه ۲: «دروازه عامل مرکزی» افزونه مجوز IAP‏ (authzExtension) را فراخوانی می‌کند. IAP نسخه ۲ «قانون ۲» را در «خط‌مشی دسترسی یکپارچه IAM» ارزیابی می‌کند. چون تماس‌گیرنده با ${CONCIERGE_SPIFFE_PRINCIPAL} و هدف با burger-seller-agent مطابقت دارد، IAP‏ ALLOW (granted: true) را برمی‌گرداند.
  5. اجرای بین‌پروژه‌ای: «دروازه عامل» درخواست مجاز را به‌صورت بین‌پروژه‌ای به 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 / ALLOWED)

گزارش‌های درخواست Query 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 ضبط کنند—که به‌طور شفاف توسط قانون ۱ (core-gapi-services) رهگیری و مجاز می‌شوند.

برای درستی‌سنجی نسخه خط‌مشی POLICY_VERSION_V2، گزارش‌های «دسترسی به داده‌های ممیزی ابری» 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/${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 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.

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

  1. Dynamic Discovery: «دربان خرید» نقطه پایانی pizza-seller-agent را از Central Agent Registry درطول راه‌اندازی حل‌وفصل کرد.
  2. حل قصد و فراخوانی A2A: Gemini در «دربان خرید» تلاش می‌کند درخواست سفارش پیتزا را به نقطه پایانی «فروشنده پیتزا» در PROJECT_SELLERS ارسال کند.
  3. رهگیری دروازه: RPC خروجی توسط agent_gateway_config ضبط می‌شود و به «دروازه عامل مرکزی» هدایت می‌شود.
  4. ارزیابی خط‌مشی IAP v2 (رد پیش‌فرض): «دروازه عامل مرکزی» IAP v2 را فراخوانی می‌کند. چون هیچ قانونی در «خط‌مشی دسترسی یکپارچه» وجود ندارد که با pizza-seller-agent مطابقت داشته باشد، IAP‏ DENY (granted: false) را برمی‌گرداند.
  5. مسدود کردن محیطی سخت‌گیرانه: چون «افزونه Authz» در حالت اجرا (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

مرحله ۶: اعطای پویای دسترسی خروج به Pizza Agent

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

# 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

مرحله ۷: دوباره از نماینده پیتزا پرسمان کنید (موفقیت فوری ۲۰۰ 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**

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

  1. بازآوری پویای خط‌مشی: به‌روزرسانی «خط‌مشی دسترسی یکپارچه IAM» بلافاصله در موتور ارزیابی IAP بدون هیچ‌گونه زمان ازکارافتادگی و بدون بازاستقرار هیچ‌یک از محفظه‌ها اعمال می‌شود.
  2. فراخوانی A2A: «دربان» درخواست را ازطریق «دروازه نماینده مرکزی» ارسال می‌کند.
  3. ارزیابی خط‌مشی IAP v2 (تأیید): IAP v2 با «قانون ۳» مطابقت دارد، هویت فراخواننده و عبارت 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://aiplatform.mtls.googleapis.com/v1beta1/projects/${PROJECT_SELLERS}/locations/global/publishers/google/models/gemini-3.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 بین پروژه‌ای

# 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، و «خط‌مشی‌های دسترسی یکپارچه» (UAP) مربوط‌به IAM مستقر و مدیریت کرده‌اید.

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

  • Centralized Egress Perimeter: Routed spoke runtime containers (PROJECT_CONCIERGE, PROJECT_SELLERS) through a central Agent Gateway in PROJECT_GOVERNANCE using agentGatewayConfig.
  • حاکمیت اعلانی (UAP): اتصال‌های تکه‌تکه به‌ازای هر منبع با یک «خط‌مشی دسترسی IAM» قابل‌حسابرسی جایگزین شده است که در درگاه توسط IAP نسخه ۲ ارزیابی می‌شود.
  • هویت رمزنگاری‌شده: خروج با کمترین امتیاز بااستفاده از هویت‌های SPIFFE محفظه (principal://...) به‌جای کلیدهای بلندمدت اعمال می‌شود.
  • Dynamic Service Discovery: نقاط پایانی عامل همتا را در زمان اجرا ازطریق Central Agent Registry حل کرد و نشانی‌های وب و شناسه‌های پروژه کدگذاری‌شده را حذف کرد.
  • چابکی خط‌مشی زمان اجرا: pizza-seller-agent از «رد پیش‌فرض» (403 Forbidden) به «مجاز» (200 OK) به‌طور هم‌زمان ازطریق به‌روزرسانی خط‌مشی، بدون راه‌اندازی مجدد محفظه، منتقل شد.

cosmopup

Cosmopup می‌گوید: «عامل‌ها عالی هستند—آن‌ها همه کارهای بین‌پروژه‌ای را انجام می‌دهند درحالی‌که من روی هدف اصلی‌ام تمرکز می‌کنم: چرت زدن!»

مراحل بعدی و مستندات