Agent Runtime için projeler arası Agent Registry ile Agent Gateway'de merkezi yönetim

1. Giriş

Kurumsal kuruluşlar üretken yapay zekayı benimsedikçe mimariler, bağımsız ve tek parçalı chatbot'lardan hızla dağıtılmış çoklu aracı sistemlere (Agent-to-Agent / A2A) dönüşüyor. Bu modern topolojilerde üst düzey düzenleyici ajanlar, görevleri bağımsız Google Cloud projelerindeki uzman alan çalışanı ajanlarına, Model Bağlam Protokolü (MCP) araç sunucularına ve arka uç kurumsal veritabanlarına devrederek karmaşık iş akışlarını koordine eder.

Ancak çoklu aracı sistemlerin büyük ölçekte çalıştırılması, kritik güvenlik, yönetim ve operasyonel zorluklar ortaya çıkarır:

  • Gizli aracı ve araçların kontrolsüz büyümesi: Geliştirme ekipleri, merkezi bir katalog olmadan izole edilmiş projelerde aracı dağıttığında kuruluşlar hangi araçların ve alt aracıların bulunduğunu göremez.
  • İzlenmeyen Projeler Arası Çıkış: Aracıların doğrudan ve denetlenmemiş ağ rotalarına izin verilmesi, veri sızıntısı riskleri oluşturur ve güvenlik çevrelerini atlar.
  • Kırılgan, Sabit Kodlanmış Entegrasyonlar: Aşağı akış aracı URL'lerinin ve Akıl Yürütme Motoru kimliklerinin sabit kodlanması, yükseltmeler veya yeniden dağıtımlar sırasında bozulan kırılgan bağımlılıklar oluşturur.
  • En Az Ayrıcalıklı Kimlik Eksikliği: Paylaşılan hizmet hesapları, bireysel aracı örneği düzeyinde kriptografik olarak inkar edilemezlik sağlayamaz.

Gemini Enterprise Agent Platform, bu zorlukları çözmek için dört temel sütundan oluşan birleşik bir yönetim ve bağlantı kontrol noktası sunar:

  1. Aracı Ağ Geçidi (networkservices.googleapis.com): Yönetilen, bölgesel bir ağ ve politika zorlama proxy'si. AGENT_TO_ANYWHERE Çıkış modunda çalışarak giden aracı trafiğini engeller, yetkilendirme değerlendirmelerini güvenlik uzantılarına devreder ve istekleri proje sınırları arasında yönlendirir.
  2. Agent Registry (agentregistry.googleapis.com): Tek kurumsal hizmet kataloğu. Kuruluş genelinde kullanılabilen tüm araçların, MCP sunucularının ve eş aracılarının merkezi ve onaylanmış bir dizinini sunarak sıfır sabit kodlanmış uç nokta ile dinamik çalışma zamanı otomatik keşfine olanak tanır.
  3. Agent Identity & IAP v2 Governance (iap.googleapis.com & iam.googleapis.com): Şifreleme tabanlı bir kimlik ve erişim çerçevesi. Yürütme aracıları, benzersiz ve onaylanmış SPIFFE makine URN'leri (principal://...) alır. Giden çıkış, zengin Common Expression Language (CEL) katalog koşulları (destination.agent_registry.*) kullanılarak evrensel izni (iap.googleapis.com/resources.egressViaIAP) doğrulayan merkezi IAM Birleşik Erişim Politikaları (UAP / IAP v2) ile değerlendirilir.
  4. Agent Runtime (Akıl Yürütme Motorları): Merkezi ağ geçitlerine yerel yapılandırma bağlamaları (agent_gateway_config) içeren, Python tabanlı ajan uygulamaları için tümüyle yönetilen, sunucusuz bir yürütme platformu.

Codelab İş Senaryosu: Çok Projeli Yiyecek ve İçecek Satın Alma

Bu codelab'de, üç farklı Google Cloud projesini kapsayan gerçek dünyadaki çok projeli bir satın alma ekosistemi oluşturup yöneteceksiniz:

  • Merkezi Yönetim Projesi (PROJECT_GOVERNANCE): Merkezi BT ve SecOps'a aittir. Merkezi Aracı Ağ Geçidi, Merkezi Aracı Kayıt Defteri ve IAM Birleşik Erişim Politikaları'nı barındırır.
  • Consumer Orchestrator Project (PROJECT_CONCIERGE): Tedarik ekibine aittir. Satıcıları dinamik olarak keşfeden ve müşteri siparişlerini yönlendiren Purchasing Concierge Agent'ı barındırır.
  • Alan Tedarikçi Projesi (PROJECT_SELLERS): Burger Satıcı Temsilcisi ve Pizza Satıcı Temsilcisi'ni barındıran, harici veya departman tedarikçilerine ait.

figure1

Şek. 1. Çok projeli merkezi yönetişim mimarisi

Neden Projeler Arası Merkezi Yönetim?

Büyük kurumsal kuruluşlarda, ürün ekipleri ve veri bilimi grupları onlarca bağımsız Google Cloud projesinde yapay zeka temsilcileri oluşturur. Her ekibe araç kaydı, çıkış ağı rotaları ve güvenlik koruma duvarları üzerinde doğrudan kontrol verilmesi, incelenmemiş araçların yaygınlaşmasına, tutarsız Veri Kaybını Önleme politikalarına, izlenmeyen VPC çıkışına ve parçalanmış denetleme günlüklerine yol açar.

Projeler arası merkezi yönetişim, politika oluşturmayı aracı yürütmeden ayırır:

  • Merkezi BT ve SecOps, güvenlik politikaları oluşturur, araçları inceler ve tek bir merkezi yönetim projesi kapsamında çıkış trafiğini izler.
  • Ürün ve uygulama ekipleri, bağımsız Agent Runtime projelerinde tamamen iş mantığına odaklanır. Yerel VPC'leri, ara bağlantıları veya parçalanmış politika motorlarını yönetmenin operasyonel ek yükü olmadan doğrudan merkezi ağ geçidine bağlanır.

figure2

Şekil 2. Üç katmanlı projeler arası yönetişim mimarisi ve sınırları

Birleştirilmiş erişim politikalarında iki katmanlı kimlik kapsamı modeli

Temsilciler Central Agent Gateway üzerinden iletişim kurduğunda, Identity-Aware Proxy (IAP v2), arayanın temsilci kimliğine (çalışma zamanı kapsayıcısına otomatik olarak verilen, SPIFFE tabanlı, kriptografik olarak onaylanmış bir kimlik) göre erişimi genel bir IAM erişim politikasına karşı değerlendirir:

  • 1. Katman: Temel Google Cloud API'leri (1. Kural'daki principalSet:// ile kaba taneli): Kelebek projelerindeki tüm aracı çalışma zamanlarının keşif, jeton oluşturma ve çıkarım için standart Google API'lerine (aiplatform, iamcredentials, telemetry, agentregistry) ulaşmasına izin veren proje genelinde çıkış yetkilendirmesi.
  • 2. Katman: İş Araçları ve A2A Hizmetleri (2. ve 3. Kurallarda principal:// ile İnce Ayrıntılı): Kayıtlı belirli Agent Registry hizmetlerini (destination.agent_registry.agent.name) hedefleyen Common Expression Language (CEL) koşullarıyla zorunlu kılınan, bireysel Reasoning Engine örneklerine bağlı sıkı en az ayrıcalık erişimi.

Ne oluşturacaksınız?

  • PROJECT_GOVERNANCE bölgesinde merkezi Agent Gateway (centralized-agw)
  • Katı ENFORCE modunda IAP v2 Yetkilendirme Hizmeti Uzantısı ve Authz Politikası (failOpen: false)
  • Temel IAM Birleşik Erişim Politikası (uap-rules.json) ve proje politikası bağlama
  • Projeler arası hizmet aracısı IAM izinleri (ar_agw_cross_project_sa)
  • Paylaşılan merkezi Google Cloud Storage (GCS) hazırlık paketi
  • PROJECT_SELLERS Bölgesinde Bağımsız Burger ve Pizza Satıcısı Temsilcileri
  • PROJECT_CONCIERGE içinde dinamik REST otomatik keşfi ile Satın Alma Concierge Aracısı
  • Projeler arası mTLS URL'leriyle Central Agent Registry'deki hizmet kayıtları
  • Canlı doğrulama ve Cloud Logging denetimleriyle dinamik IAP v2 çıkış politikası güncellemeleri

figure3

Şekil 3. Adım adım uygulama sırası

Öğrenecekleriniz

  • Merkezi ağ geçitleri için projeler arası hizmet aracısı IAM izinlerini yapılandırma
  • Çok projeli ortamlarda Agent Runtime çıkışını merkezi bir Agent Gateway üzerinden yönlendirme
  • Hizmet uzantılarını (iapPolicyVersion: "V2") kullanarak Agent Gateway yetkilendirmesini Identity-Aware Proxy'ye (IAP v2) nasıl devrederim?
  • IAM Birleştirilmiş Erişim Politikaları'nı (UAP) Common Expression Language (CEL) kurallarıyla yetkilendirme ve bağlama (kayıtlı Aracı Kayıt Otoritesi hedeflerini yönetme) (destination.agent_registry.*)
  • Çalışma zamanında otomatik keşif özelliğini kullanarak, Agent Registry'ye karşı sabit kodlu aracı kimliklerini ve URL'leri ortadan kaldırma
  • Gerçek çevre sıfır güven engellemeyi test etme (HTTP 403 Forbidden) ve Cloud Logging'de canlı politika güncellemelerini doğrulama

İhtiyacınız olanlar

  • Faturalandırmanın etkin olduğu 3 Google Cloud projesi:
    • PROJECT_GOVERNANCE: Merkezi yönetim, ağ geçidi, kayıt otoritesi ve IAM erişim politikaları
    • PROJECT_CONCIERGE: Satın alma danışmanı düzenleyici aracısı
    • PROJECT_SELLERS: Burger ve pizza konusunda uzman satıcı temsilcileri
  • 3 projenin tümünde roles/owner veya yönetim izinlerine sahip bir IAM kullanıcısı ya da hizmet hesabı
  • Google Cloud kuruluşu (SPIFFE güven alanı eşlemesi için)
  • Google Cloud Shell veya gcloud KSA, python (3.11+) ve uv yüklü bir yerel makine

Giriş bölümünü tamamladık. Şimdi Kurulum ve Ortam bölümüne geçiyoruz.

2. Kurulum

Bu mimari 3 farklı Google Cloud projesini kapsasa da terminal dağıtım komutlarının, depo indirmelerinin ve hazırlama işlemlerinin% 100'ünü PROJECT_GOVERNANCE olarak ayarlanmış tek bir Cloud Shell terminalinden yürütebilirsiniz. Her dağıtım komut dosyası ve gcloud komutu, KSA işaretleri (--project) aracılığıyla uygun hedef projeyi açıkça hedefler.

Google Cloud projenizin komut satırına erişerek başlayın:

Proje bağlamınızı ayarlama

# 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

Kabuk ortamı değişkenlerini ayarlama

Projeye özel tanımlayıcılarınızı girin.

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

Bu kabuk değişkenleri otomatik olarak türetilir.

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

Yapılandırma dosyaları için yerel dizin oluşturma

# create config folder
mkdir -p cfg

Birleştirilmiş erişim politikaları için erişim politikası yöneticisi rolü atama

# grant Access Policy Admin and Project IAM Admin to current user in Governance Project
for ROLE in "roles/iam.accessPolicyAdmin" "roles/resourcemanager.projectIamAdmin"; do
  gcloud projects add-iam-policy-binding ${PROJECT_GOVERNANCE} \
    --member="user:$(gcloud config get-value account)" \
    --role="${ROLE}" \
    --condition=None
done

IAP v2 için Cloud Audit Data Access Logs'u etkinleştirme

Google Cloud, varsayılan olarak Veri Erişimi denetleme günlüklerini devre dışı bırakarak istenmeyen depolama maliyetlerini önler. IAP v2, yetkilendirme kararlarını (granted=true ve granted=false) veri erişimi denetleme günlükleri olarak yaydığı için PROJECT_GOVERNANCE bölümünde iap.googleapis.com için ADMIN_READ, DATA_READ ve DATA_WRITE günlük kaydını etkinleştirin:

# 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)"

Gerekli Google Cloud API'lerini etkinleştirme

# 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

Tüm projelerde API etkinleştirme işlemini doğrulama

Üç projenin (PROJECT_GOVERNANCE, PROJECT_CONCIERGE ve PROJECT_SELLERS) de aynı API'lerin etkinleştirildiğinden emin olmak, operasyonel tutarlılık sağlar ve çalışma zamanı jetonu oluşturma hatalarını, şema kataloglama hatalarını veya telemetri kesintilerini önler.

Üç projenin tümünde API eşliğini doğrulamak için Cloud Shell'de aşağıdaki doğrulama komut dosyasını çalıştırın:

# 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

Örnek Doğrulama Çıkışı:

Tüm API'lerin etkinleştirildiğini görmeniz gerekir.

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

Kuruluş politikalarını yapılandırma

Varsayılan Google Cloud kuruluş politikaları, IAM v3 erişim politikası bağlamalarını kaynaklarla sınırlayan kısıtlamalar uygular (constraints/iam.managed.disableAccessPolicyBinding).

enforce: false ayarını açıkça izin verilecek şekilde belirleyerek proje düzeyinde devralınan kuruluş politikası kısıtlamalarını geçersiz kılın.

# 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

Kurulum bölümü sona erdi. Şimdi Core Google API'lerini kaydetme bölümüne geçiyoruz.

3. Agent Registry

Temel Google API'leri Uç Nokta Hizmeti'ni Kaydetme

Agent Gateway, agent_gateway_config ile yapılandırılan aracıların çıkış trafiğini temel Google Cloud arka uç hizmetlerine (ör. aiplatform, IAM Credentials ve Telemetry) güvenli bir şekilde yönlendirebilmesi için Google API URL'lerinin Central Agent Registry'ye kaydedilmesini gerektirir.

Aracı Kayıt Defteri'nde core-gapi-services oluşturma

# 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

Capture Core API'leri Uç Nokta Kaynak Kimliği

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

Temsilci kimliğinde principalSet ile principal arasındaki fark

Google Cloud IAM ve Gemini Enterprise Agent Platform'da, yürütme aracısı kapsayıcılarına verilen makine kimlikleri, Identity-Aware Proxy (IAP v2) tarafından değerlendirilen kriptografik olarak onaylanmış SPIFFE URN'leri kullanır. IAM Unified Access Policies'i yapılandırırken belirli bir principal veya özelliğe dayalı bir principalSet hedefleyebilirsiniz:

Boyut

principal:// (Tek Makine Kimliği)

principalSet:// (Özelliğe Dayalı Grup)

IAM Söz Dizimi

principal://...

principalSet://...

Ayrıntı düzeyi

Ayrıntılı (örnek düzeyinde): Tek ve belirli bir Reasoning Engine container örneğini tanımlar.

Kaba taneli (proje düzeyinde): Ortak bir proje özelliğini paylaşan tüm muhakeme motorlarını tanımlar.

URN Desen

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 Platform'daki Kullanım Alanı

2.Katman (İş Araçları ve A2A): Belirli düzenleyici aracıların hedef alan araçlarını (ör. satın alma danışmanı $\rightarrow$ burger satıcısı) çağırmasına izin verme.

1. Katman (Temel Altyapı): Bir projedeki tüm aracılara Google Cloud API'lerine çıkış erişimi verme (core-gapi-services).

Yaşam Döngüsü Etkisi

Silinip yeniden oluşturulan bir aracının yeni motor kimliği için güncellenmiş bir IAM politikası bağlaması gerekir.

Ek IAM güncellemeleri olmadan, söz konusu projede yeni dağıtılan aracılara otomatik olarak uygulanır.

Birleştirilmiş Erişim Politikaları (UAP / IAP v2) ile Bildirime Dayalı Yönetim

Eski IAP v1'de çıkış politikaları, gcloud beta iap web add-iam-policy-binding kullanılarak doğrudan tek tek aracı kayıt defteri kaynaklarına ekleniyordu. IAP v2 ve Birleştirilmiş Erişim Politikaları kapsamında, kaynak başına bağlamalar tek ve merkezi bir IAM erişim politikası (cfg/uap-rules.json) lehine kaldırılır.

core-gapi-services için temel çıkış yetkilendirmesi, Bölüm 5'teki Birleşik Erişim Politikası'nda Kural 1 olarak yapılandırılır. Böylece, tüm aracı kapsayıcıların dağıtımdan önce temel çıkış rotaları oluşturulur.

Asıl tanımlayıcılar ve Workload Identity mekanizmalarıyla ilgili daha ayrıntılı teknik bilgiler için aşağıdaki kaynaklara bakın:

Temel API'ler uç nokta kaydı tamamlandı. Şimdi Merkezi Aracı Ağ Geçidini Dağıtma bölümüne geçiyoruz.

4. Agent Gateway

Merkezi Agent Gateway'i dağıtma

$PROJECT_GOVERNANCE projesinde AGENT_TO_ANYWHERE çıkış modunda merkezi Agent Gateway'i (centralized-agw) dağıtın.

Ağ Geçidi Yapılandırma Manifestini Tanımlama

Çıkış trafiği yönetimi için cfg/${AGW_NAME}.yaml oluşturun:

# 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

Aracı ağ geçidi yapılandırmasını içe aktarma

# import and create agent gateway
gcloud network-services agent-gateways import ${AGW_NAME} \
  --source="cfg/${AGW_NAME}.yaml" \
  --location=${REGION} \
  --project=${PROJECT_GOVERNANCE}

Ajan ağ geçidi ayrıntılarını doğrulama

# show agent gateway status
gcloud network-services agent-gateways describe ${AGW_NAME} \
  --location=${REGION} \
  --project=${PROJECT_GOVERNANCE}

Örnek çıkış:

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'

Ağ geçidi dağıtımı tamamlandı. Şimdi Yetkilendirmeyi Yapılandırma bölümüne geçiyoruz.

5. Yetkilendirme

Aracı Ağ Geçidi Yetkilendirmesini ve Temel UAP'yi Yapılandırma

Aracı Ağ Geçidi, Identity-Aware Proxy (IAP v2) Birleşik Erişim Politikaları (UAP) ile entegre edilmiş Yetkilendirme Politikaları (networksecurity.authzPolicies) kullanarak giden araç ve aracı trafiğini güvenli hale getirir ve yönetir.

Yetkilendirme Mimarisine Genel Bakış

figure4

Şekil 4. Yetkilendirme Mimarisine Genel Bakış

Yetkilendirme mimarisi, birbirine bağlı üç katmandan oluşur:

  1. IAP Hizmet Uzantısı (authzExtension): Sıkı çevre sıfır güven uygulama için service: iap.googleapis.com, metadata: iapPolicyVersion: "V2" ve failOpen: false ile yapılandırılmış bölgesel kaynak.
  2. Ağ Geçidi Yetkilendirme Politikası (authzPolicy): policyProfile: REQUEST_AUTHZ ve action: CUSTOM ile Agent Gateway'inizi hedefleyen bölgesel kaynak, yetkilendirme kontrollerini IAP Authz Uzantısı'na yönlendirir.
  3. IAM Birleştirilmiş Erişim Politikası ve Bağlama (accessPolicy & policyBinding): IAP tarafından değerlendirilen global IAM v3 kaynağı. Arayan SPIFFE kimliklerine ve CEL kataloğu koşullarına karşı evrensel izni iap.googleapis.com/resources.egressViaIAP doğrular.

1. adım: IAP v2 yetkilendirme uzantısını oluşturun ve içe aktarın

Katı ENFORCE modunda iapPolicyVersion: "V2" ve failOpen: false ile hizmet uzantısı manifesti oluşturun:

# 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 uzantısını içe aktarın:

# 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 uzantısının etkin olduğunu doğrulayın:

# describe authz extension
gcloud service-extensions authz-extensions describe ${AGW_NAME}-svc-ext-authz-iap \
  --location=${REGION} \
  --project=${PROJECT_GOVERNANCE}

Örnek çıkış:

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. adım: Ağ geçidi yetkilendirme politikası oluşturun ve içe aktarın

Agent Gateway'e eklenen ve istek doğrulamasını IAP Authz Extension'a devreden bir yetkilendirme politikası yapılandırması oluşturun:

# 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

Yetkilendirme politikasını içe aktarın:

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

Etkin yetkilendirme politikasını doğrulayın:

# describe authz policy
gcloud beta network-security authz-policies describe ${AGW_NAME}-authz-policy-profile-iap \
  --location=${REGION} \
  --project=${PROJECT_GOVERNANCE}

3. adım: İlk Birleştirilmiş Erişim Politikasını Oluşturun (Kural 1: Temel Google API'leri)

cfg/uap-rules.json oluşturun. 1. kural, üç proje principalSetsinin core-gapi-services'ye ulaşmasına izin verir:

# create initial unified access policy rules manifest
cat > cfg/uap-rules.json << EOF
[
  {
    "description": "Rule 1: Allow agent runtimes across all 3 projects to reach Core Google APIs",
    "effect": "ALLOW",
    "principals": [
      "principalSet://agents.global.org-${ORG_ID}.system.id.goog/attribute.platformContainer/aiplatform/projects/${PROJECT_NUMBER_GOVERNANCE}",
      "principalSet://agents.global.org-${ORG_ID}.system.id.goog/attribute.platformContainer/aiplatform/projects/${PROJECT_NUMBER_CONCIERGE}",
      "principalSet://agents.global.org-${ORG_ID}.system.id.goog/attribute.platformContainer/aiplatform/projects/${PROJECT_NUMBER_SELLERS}"
    ],
    "operation": {
      "permissions": [
        "iap.googleapis.com/resources.egressViaIAP"
      ]
    },
    "conditions": {
      "iap.googleapis.com": {
        "expression": \
        "destination.is_registered == true && \
         destination.agent_registry.resource_type == 'ENDPOINT' && ( \
         destination.agent_registry.endpoint.name == 'projects/${PROJECT_GOVERNANCE}/locations/${REGION}/endpoints/core-gapi-services' || \
         destination.agent_registry.endpoint.name == 'projects/${PROJECT_GOVERNANCE}/locations/${REGION}/endpoints/${ENDPOINT_ID}' || \
         destination.agent_registry.endpoint.name == 'projects/${PROJECT_NUMBER_GOVERNANCE}/locations/${REGION}/endpoints/${ENDPOINT_ID}')"
      }
    }
  }
]
EOF

4. adım: IAM erişim politikasını oluşturun ve bağlayın

Genel IAM erişim politikasını oluşturun:

# create global IAM access policy
gcloud iam access-policies create ${UAP_POLICY_NAME} \
  --details-rules=cfg/uap-rules.json \
  --project=${PROJECT_GOVERNANCE} \
  --location=global

Erişim politikasını PROJECT_GOVERNANCE ile bağlayın:

# 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

Politika bağlamanın etkin olduğunu doğrulayın:

# verify policy binding
gcloud iam policy-bindings describe ${UAP_BINDING_NAME} \
  --project=${PROJECT_GOVERNANCE} \
  --location=global

Örnek çıkış:

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}

Temel Google Cloud API çıkışı artık katı ENFORCE modunda üç projenin tamamında güvenli bir şekilde yetkilendiriliyor.

Ağ geçidi yetkilendirme kurulumu tamamlandı. Şimdi Projeler Arası IAM İzinlerini Yapılandırma bölümüne geçelim.

6. Projeler arası IAM

Projeler Arası IAM İzinlerini Yapılandırma

Bu çok projeli topolojide, aracı çalışma zamanları uç projelerde (PROJECT_CONCIERGE ve PROJECT_SELLERS) bulunurken merkezi aracı ağ geçidi ve aracı kayıt defteri PROJECT_GOVERNANCE içinde yer alır.

Google Cloud projeleri yalıtılmış güvenlik çevreleri olduğundan projeler arası erişimin iki operasyonel katmanda açıkça verilmesi gerekir:

  1. Kontrol düzlemi (Dağıtım zamanı): --agent-gateway-config ile yapılandırılmış bir aracı kapsayıcısı dağıtılırken bağlı proje Aracı Çalışma Zamanı Hizmeti Aracısı (service-@gcp-sa-aiplatform.iam.gserviceaccount.com), kapsayıcıyı merkezi ağ geçidine eklemelidir. PROJECT_GOVERNANCE içinde networkservices.agentGateways.use, get ve operations.get izinlerini veren minimum düzeyde bir özel rol (ar_agw_cross_project_sa) oluştururuz.
  2. Veri düzlemi (çalışma zamanı yürütme):
    • Katalog Bulma: Hedef aracı uç noktalarını dinamik olarak çözmek için Spoke kimliklerinin PROJECT_GOVERNANCE içinde roles/agentregistry.viewer olması gerekir.
    • Hedef Çağırma: Concierge aracısının, satıcı muhakeme motorlarına karşı sorgu yürütmek için roles/aiplatform.user PROJECT_SELLERS içinde olması gerekir.

PROJECT_GOVERNANCE içinde özel IAM rolü oluşturma

# 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 hizmeti aracılarına özel rol atama

# 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

Projeler arası IAM kurulumu tamamlandı. Şimdi Satıcı ve Concierge Temsilcilerini Dağıtma bölümüne geçiyoruz.

7. Aracı Çalışma Zamanı

Satış ve müşteri temsilcisi aracılarını dağıtma

Bu codelab'de kullanılan çoklu aracı uygulaması kod tabanı ve dağıtım komut dosyaları, uzak bir Google Cloud GitHub deposunda tutulur. Aşağıdaki adımlarda depo yerel olarak klonlanır, gerekli dosyalar mevcut çalışma dizini yapısına kopyalanır, geçici dosyalar temizlenir ve bağımlılıklar uv ile yüklenir.

Uzak yapıları getirme

# 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

Paylaşılan merkezi hazırlama paketi oluşturma

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

Projeler Arası Aracı Ağ Geçidi Bağlama İşleminin Çalışma Şekli

Bu adımda, çıkış trafiğini PROJECT_GOVERNANCE içindeki merkezi aracı ağ geçidinden yönlendirecek şekilde yapılandırırken satıcı aracılarını bağlı proje (PROJECT_SELLERS) içine dağıtacaksınız:

# !-- for example purposes -- NOT a command to execute --!
# snippet from deploy_burger.py
burger_config = {
    "staging_bucket": staging_bucket_uri,
    "gcs_dir_name": "burger_agent",
    "display_name": "burger-seller-agent-adk",
    "identity_type": "AGENT_IDENTITY",
    "agent_gateway_config": {
        "agent_to_anywhere_config": {
            "agent_gateway": f"projects/{args.governance_project}/locations/{args.region}/agentGateways/{args.gateway}"
        }
    },
}
deployed_burger = client.agent_engines.create(agent=burger_playground, config=burger_config)

1. Kural, Birleşik Erişim Politikamızda daha önce belirlendiğinden Google Cloud API'lerine yönelik kapsayıcı başlatma isteklerine ağ geçidi üzerinden kesintisiz olarak izin verilir.

PROJECT_SELLERS bölgesinde Burger ve Pizza Satıcısı Aracıları dağıtın

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

Satıcı ağ geçidi yönlendirmesini doğrulama

# 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

Satın alma Concierge aracısını PROJECT_CONCIERGE'ya dağıtma

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

Satın alma ağ geçidi yönlendirmesini doğrulama

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

Çıktıda, Concierge aracısının çalışma zamanı kimliği ve projesi ile Governance projesi Agent Gateway'e bağlama gösterilmelidir.

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

Ajan dağıtımları tamamlandı. Şimdi Merkezi Ajan Kayıt Defteri'ne Ajan Kaydetme bölümüne geçiyoruz.

8. Projeler arası kayıt defteri

Merkezi Ajan Kayıt Defteri'ne Ajan Kaydetme

Proje genelinde bölgesel mTLS uç noktalarını ve sayısal proje numaralarını kullanarak PROJECT_GOVERNANCE içindeki Merkezi Aracı Kayıt Defteri'ne üç aracıyı da kaydedin.

Hizmetleri Agent Registry'de A2A dışı aracı olarak kaydetme

# 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

Temel alınan aracı kayıt kimliklerini yakalama

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

Kayıt defteri yapılandırması tamamlandı. Şimdi A2A çıkış politikalarını yapılandırma bölümüne geçiyoruz.

9. UAP politikaları

Birleşik Erişim Politikası'nda A2A çıkış politikalarını yapılandırma

Yüksek düzey ZORUNLU KILMA modunda, Agent Gateway'in Varsayılan Olarak Reddetme mimarisi altında:

  1. 1. Kural (Temel Google Cloud API'leri): 3 projenin tümündeki aracı kapsayıcılarının core-gapi-services'ye ulaşmasına izin verir.
  2. 2. Kural (Köfte Satıcısı Temsilcisi: İZİN VER): Satın Alma Danışmanı Temsilcisi örneğinin özellikle Köfte Satıcısı Temsilcisi'ni çağırmasına izin verir.
  3. Pizza Satıcısı Ajanı (Varsayılan olarak REDDEDİLDİ): Politikada kasıtlı olarak yer almamıştır. ENFORCE modunda (failOpen: false), Concierge'in Pizza Satıcısı'nı çağırma girişimi, HTTP 403 Forbidden ile ağ geçidi çevresinde hemen sonlandırılır.

Formulate Concierge Agent Identity

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

Manifesti 1. ve 2. Kural ile Güncelleme

Kural 1 (Temel API'ler) ve artık Kural 2'yi (Burger Satıcısı Aracısı) içerecek şekilde yeni cfg/uap-rules-update-2.json oluşturun:

# 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

Güncellenen erişim politikasını uygulama

# 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 erişim politikası ayrıntılarını doğrulama

# inspect updated access policy
gcloud iam access-policies describe ${UAP_POLICY_NAME} \
  --project=${PROJECT_GOVERNANCE} \
  --location=global

Örnek çıkış:

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

Politika kurulumu tamamlandı. Şimdi Yönetim Politikalarını Test Etme ve Doğrulama bölümüne geçiyoruz.

10. Politikaları doğrulama

Cloud Logging ile Yönetim Politikalarını Test Etme ve Doğrulama

Bu bölümde, Agent Runtime AI Playground'da projeler arası Agent-to-Agent (A2A) etkileşimlerini test edecek, katı ENFORCE modunda gerçek çevre HTTP 403 Forbidden engellemeyi gözlemleyecek, birleşik erişim politikasını canlı olarak değiştirecek ve anında sipariş onayını doğrulayacaksınız.

1. adım: PROJECT_CONCIERGE içinde Agent Runtime AI Playground'u açın

  1. Google Cloud Console'u açın.
  2. Üstteki proje seçici çubuğunda PROJECT_CONCIERGE simgesine geçin.
  3. Gezinme menüsünde Agent Platform > Agents > Deployments'a (Agent Platform > Aracıları > Dağıtımlar) gidin.
  4. purchasing-concierge-adk simgesini tıklayın.
  5. Ekranın sağ tarafında etkileşimli sohbet arayüzünü açmak için Playground'u seçin.

2. adım: Burger siparişini test edin (2. kural eşleşmesi -> 200 OK)

Playground sohbet penceresinde aşağıdaki sipariş istemini gönderin:

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

Onay yanıtı gerekiyorsa aşağıdaki yanıtı gönderin:

Confirmed, please place the order.

Alternatif olarak, Cloud Shell / terminalden programatik olarak test edin:

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

Onay yanıtı gerekiyorsa şu komutu kullanın:

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

Kamera arkasında neler olur?

  1. Dinamik Keşif: Oturum başlatma sırasında, Satın Alma Asistanı, burger-seller-agent için bölgesel mTLS uç noktasını keşfetmek üzere PROJECT_GOVERNANCE'deki (1. Kural tarafından yetkilendirilmiş Aracı Ağ Geçidi aracılığıyla core-gapi-services üzerinden) Merkezi Aracı Kayıt Defteri'ne sorgu gönderdi.
  2. Amacı Çözme ve A2A Çağırma: Satın alma danışmanının içindeki Gemini, yemek siparişi amacını ayrıştırır ve https://${REGION}-aiplatform.mtls.googleapis.com/.../reasoningEngines/${BURGER_ENGINE_ID} için giden bir UPÇ aracılığıyla Burger Satıcısı Temsilcisi'ni çağırır.
  3. Ağ Geçidi Yakalama ve SPIFFE Yayma: Çıkış trafiği agent_gateway_config tarafından yakalanır ve PROJECT_GOVERNANCE içindeki Merkezi Aracı Ağ Geçidi'ne yönlendirilir. Bu trafik, Concierge'ın kriptografik SPIFFE kimliğini (principal://...) taşır.
  4. IAP v2 Politika Değerlendirmesi: Merkezi Aracı Ağ Geçidi, IAP yetkilendirme uzantısını (authzExtension) çağırır. IAP v2, IAM Birleştirilmiş Erişim Politikası'ndaki 2. Kural'ı değerlendirir. Arayan ${CONCIERGE_SPIFFE_PRINCIPAL} ile, hedef ise burger-seller-agent ile eşleştiği için IAP, ALLOW (granted: true) değerini döndürür.
  5. Projeler Arası Yürütme: Agent Gateway, yetkili isteği projeler arası olarak PROJECT_SELLERS'ye yönlendirir. Burada Burger Seller Reasoning Engine, siparişi işler ve onay döndürür.

Beklenen yanıt:

Your order for 10 Classic Cheeseburger(s) has been placed!
Here is a summary of your order:
- 10x Classic Cheeseburger @ IDR 85,000/each = IDR 850,000

Total: IDR 850,000
Your Order ID is: e8f9c732-f347-4cc4-acff-cfe09ccbeddd

3. adım: Aracı ağ geçidi ve IAP v2 denetleme günlüklerini inceleyin (HTTP 200 / İzin verildi)

PROJECT_GOVERNANCE içinde Agent Gateway istek günlüklerine sorgu gönderme:

# 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
  )"

Günlükler, hem uç projelerden (PROJECT_CONCIERGE ve PROJECT_SELLERS) kaynaklanan giden trafiği yakalamalıdır. Bu trafik, Gemini akıl yürütme çağrıları (generateContent), Cloud Trace telemetrisi (/v1/traces) ve IAM kimlik bilgisi aramaları için çıkış alanlarını içerir. Bu trafik, 1. Kural (core-gapi-services) tarafından şeffaf bir şekilde yakalanır ve yetkilendirilir.

Politika sürümünü doğrulamak için IAP v2 Cloud Audit Data Access günlüklerini sorgulayın POLICY_VERSION_V2:

# query IAP v2 audit logs with shortened principal and resource fields
gcloud logging read "
  logName=\"projects/${PROJECT_GOVERNANCE}/logs/cloudaudit.googleapis.com%2Fdata_access\"
  AND protoPayload.serviceName=\"iap.googleapis.com\"
" \
  --project="${PROJECT_GOVERNANCE}" \
  --limit=5 \
  --format="table(
    timestamp.date('%H:%M:%S'):label=TIME,
    protoPayload.authenticationInfo.principalSubject.sub('\.global\..*\/reasoningEngines\/', '.[...]/reasoningEngines/'):label=CALLER,
    protoPayload.authorizationInfo[0].granted:label=GRANTED,
    protoPayload.metadata.destination.agent_registry.resource_type.basename():label=TYPE,
    protoPayload.metadata.destination.agent_registry.resource_id.basename():label=RESOURCE_ID,
    protoPayload.authorizationInfo[0].permission.basename():label=PERMISSION
  )"

Örnek çıkış:

TIME      CALLER                                                            GRANTED  TYPE      RESOURCE_ID     PERMISSION
HH:MM:SS  principal://agents.[...]/reasoningEngines/${CONCIERGE_ENGINE_ID}  True     Endpoint  ${ENDPOINT_ID}  resources.egressViaIAP
HH:MM:SS  principal://agents.[...]/reasoningEngines/${BURGER_ENGINE_ID}     True     Endpoint  ${ENDPOINT_ID}  resources.egressViaIAP
HH:MM:SS  principal://agents.[...]/reasoningEngines/${CONCIERGE_ENGINE_ID}  True     Endpoint  ${ENDPOINT_ID}  resources.egressViaIAP
HH:MM:SS  principal://agents.[...]/reasoningEngines/${BURGER_ENGINE_ID}     True     Endpoint  ${ENDPOINT_ID}  resources.egressViaIAP

4. adım: Pizza siparişini test edin (varsayılan olarak reddetme -> HTTP 403 Forbidden ENFORCED)

Aynı Playground sohbet penceresinde aşağıdaki pizza siparişi istemini gönderin:

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

Onay yanıtı gerekiyorsa aşağıdaki yanıtı gönderin:

Confirmed, please place the order.

Alternatif olarak, Cloud Shell / terminalden programatik olarak test edin:

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

Onay yanıtı gerekiyorsa şu komutu kullanın:

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

Beklenen yanıt:

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.

Kamera arkasında neler olur?

  1. Dinamik Keşif: Satın alma danışmanı, başlatma sırasında Merkezi Aracı Kayıt Defteri'nden pizza-seller-agent uç noktasını çözdü.
  2. Amacı Çözme ve A2A Çağırma: Satın alma danışmanındaki Gemini, pizza siparişi isteğini PROJECT_SELLERS içindeki Pizza Satıcısı uç noktasına göndermeye çalışır.
  3. Ağ Geçidi Yakalama: Giden UPÇ, agent_gateway_config tarafından yakalanır ve Merkezi Aracı Ağ Geçidi'ne yönlendirilir.
  4. IAP v2 politika değerlendirmesi (varsayılan olarak reddetme): Merkezi aracı ağ geçidi, IAP v2'yi çağırır. Birleştirilmiş erişim politikasında pizza-seller-agent ile eşleşen kural olmadığı için IAP, DENY (granted: false) değerini döndürür.
  5. Sıkı Çevre Bloğu: Yetkilendirme uzantısı ENFORCE modunda (failOpen: false) olduğundan, Central Agent Gateway giden bağlantıyı hemen sonlandırır ve HTTP 403 Forbidden değerini döndürür. Trafik hiçbir zaman ağ geçidinden çıkmaz ve PROJECT_SELLERS'e ulaşmaz.

5. adım: Engellenen istekler için aracı ağ geçidi günlüklerini inceleyin (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
  )"

Örnek Reddedilen Günlük Çıkışı:

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

Reddedilen karar için IAP v2 veri erişimi denetleme günlüklerini sorgulayın:

# 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
  )"

Örnek Reddedilen Denetleme Günlüğü Çıkışı:

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. adım: Pizza aracısına çıkış erişimini dinamik olarak verin

Kural 1 (Temel API'ler), Kural 2 (Burger Satıcısı Aracısı) ve artık Kural 3'ü (Pizza Satıcısı Aracısı) içerecek şekilde yeni cfg/uap-rules-update-3.json oluşturun.

# 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

Politika güncellemesini canlı olarak uygulama:

# update IAM access policy with Pizza rule
gcloud iam access-policies update ${UAP_POLICY_NAME} \
  --add-details-rules=cfg/uap-rules-update-3.json \
  --project=${PROJECT_GOVERNANCE} \
  --location=global

7. adım: Pizza aracısına tekrar sorgu gönderin (200 OK yanıtı hemen alınır)

Playground sohbet penceresinde pizza siparişi istemini yeniden gönderin:

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

Onay yanıtı gerekiyorsa aşağıdaki yanıtı gönderin:

Confirmed, please place the order.

Alternatif olarak, Cloud Shell / terminalden programatik olarak test edin:

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

Onay yanıtı gerekiyorsa şu komutu kullanın:

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

Beklenen yanıt:

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

Kamera arkasında neler olur?

  1. Dinamik politika yenileme: IAM Birleşik Erişim Politikası'nın güncellenmesi, IAP değerlendirme motorunda hemen geçerli olur. Bu işlem sırasında herhangi bir kesinti yaşanmaz ve kapsayıcılar yeniden dağıtılmaz.
  2. A2A Çağırma: Concierge, isteği Merkezi Temsilci Ağ Geçidi üzerinden gönderir.
  3. IAP v2 politika değerlendirmesi (onay): IAP v2, 3. Kural ile eşleşir, arayan kimliğini ve hedef CEL ifadesini doğrular ve ALLOW (granted: true) değerini döndürür.
  4. Projeler Arası Yürütme: Merkezi Aracı Ağ Geçidi, yetkili trafiği PROJECT_SELLERS'ye yönlendirir. Burada Pizza Satıcısı siparişi işler.

8. adım: Verilen pizza istekleri için aracı ağ geçidi günlüklerini inceleyin

# 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
  )"

Örnek verilen günlük çıktısı:

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

Test ve doğrulama tamamlandı. Şimdi Temizleme bölümüne geçiyoruz.

11. Temizleme

Bu Codelab'de kullanılan kaynaklar için Google Cloud hesabınızın ücretlendirilmesini önlemek amacıyla, yıkım adımlarını kesinlikle ters bağımlılık sırasına göre uygulayın:

1. Clean Up Reasoning Engine Deployments

Gerekçe motorlarını silmek ve uzun süreli işlemlerini beklemek için her iki çalışma zamanı projesinde de cleanup_old_deployments.py komut dosyasını çalıştırın:

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

Alternatif olarak, akıl yürütme motorlarını satır içi olarak listeleyip silebilirsiniz:

uv run --directory ./cross-project-multiagent python -c '
import vertexai
import os
from vertexai.preview import reasoning_engines

region = os.environ.get("REGION", "us-central1")
for proj in [os.environ.get("PROJECT_CONCIERGE"), os.environ.get("PROJECT_SELLERS")]:
    if not proj:
        continue
    print(f"Cleaning reasoning engines in {proj}...")
    vertexai.init(project=proj, location=region)
    for eng in reasoning_engines.ReasoningEngine.list():
        print(f"  Deleting {eng.resource_name} ({eng.display_name})...")
        eng.delete()
'

2. Kayıt otoritesi hizmetlerini silme

# delete agent registry services in Central Governance Project
for SERVICE in burger-seller-agent pizza-seller-agent purchasing-concierge-adk core-gapi-services; do
  gcloud agent-registry services delete ${SERVICE} \
    --project=${PROJECT_GOVERNANCE} \
    --location=${REGION} \
    --quiet || true
done

3. IAM Birleştirilmiş Erişim Politikası Bağlantısını ve Erişim Politikasını Silme

# 1. delete IAM policy binding
gcloud -q iam policy-bindings delete ${UAP_BINDING_NAME} \
  --project=${PROJECT_GOVERNANCE} \
  --location=global || true

# 2. delete IAM access policy
gcloud -q iam access-policies delete ${UAP_POLICY_NAME} \
  --project=${PROJECT_GOVERNANCE} \
  --location=global || true

4. Aracı Ağ Geçidi ve Güvenlik Politikalarını Silme

# 1. delete authorization policy
gcloud beta network-security authz-policies delete ${AGW_NAME}-authz-policy-profile-iap \
  --location=${REGION} \
  --project=${PROJECT_GOVERNANCE} --quiet || true

# 2. delete authorization extension
gcloud service-extensions authz-extensions delete ${AGW_NAME}-svc-ext-authz-iap \
  --location=${REGION} \
  --project=${PROJECT_GOVERNANCE} --quiet || true
# 3. delete agent gateway
gcloud network-services agent-gateways delete ${AGW_NAME} \
  --project=${PROJECT_GOVERNANCE} \
  --location=${REGION} --quiet || true

5. Projeler Arası IAM Bağlamalarını ve Özel Rolü Kaldırma

# 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

Kurulum aşamasında roles/iam.accessPolicyAdmin ve roles/resourcemanager.projectIamAdmin rollerini atadıysanız en az ayrıcalık ilkesini geri yüklemek için bu rolleri etkin kullanıcı hesabınızdan kaldırın:

# 6. remove Access Policy Admin and Project IAM Admin roles from user
for ROLE in "roles/iam.accessPolicyAdmin" "roles/resourcemanager.projectIamAdmin"; do
  gcloud projects remove-iam-policy-binding ${PROJECT_GOVERNANCE} \
    --member="user:$(gcloud config get-value account)" \
    --role="${ROLE}" \
    --condition=None --quiet || true
done

6. Denetleme verileri günlüğünü ve kuruluş politikası kısıtlamalarını geri alma

# 1. Export current Central Governance IAM policy
gcloud projects get-iam-policy ${PROJECT_GOVERNANCE} --format=json > cfg/gov_iam_policy.json
# 2. Filter out iap.googleapis.com from auditConfigs
python3 -c "
import json
with open('cfg/gov_iam_policy.json') as f:
    policy = json.load(f)

if 'auditConfigs' in policy:
    # Remove iap.googleapis.com; if nothing else remains, clear the list
    policy['auditConfigs'] = [
        ac for ac in policy['auditConfigs'] if ac.get('service') != 'iap.googleapis.com'
    ]

with open('cfg/gov_iam_policy.json', 'w') as f:
    json.dump(policy, f, indent=2)
"
# 3. Apply the updated policy to revert audit logging to default
gcloud projects set-iam-policy ${PROJECT_GOVERNANCE} cfg/gov_iam_policy.json

7. Kuruluş politikası kısıtlamalarını geri döndürme

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

8. Paylaşılan GCS Hazırlama Paketi ve Yerel Yapıları Silme

# 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

Temizleme bölümümüzü tamamladık. Şimdi Sonuç bölümüne geçiyoruz.

12. Sonuç

Tebrikler! Vertex AI Agent Runtime, Central Agent Gateway, Agent Registry ve IAM Unified Access Policies (UAP) kullanarak Google Cloud'da çok projeli bir Agent-to-Agent (A2A) mimarisi dağıtıp yönetiyorsunuz.

Temel Kavramların Özeti

  • Merkezi çıkış çevresi: agentGatewayConfig kullanılarak PROJECT_GOVERNANCE içindeki merkezi bir aracı ağ geçidi üzerinden yönlendirilen spoke çalışma zamanı kapsayıcıları (PROJECT_CONCIERGE, PROJECT_SELLERS).
  • Bildirime Dayalı Yönetim (UAP): Kaynak başına parçalanmış bağlamalar, IAP v2 tarafından ağ geçidinde değerlendirilen tek bir denetlenebilir IAM erişim politikasıyla değiştirildi.
  • Kriptografik Kimlik: Uzun süreli anahtarlar yerine kapsayıcı SPIFFE kimlikleri (principal://...) kullanılarak en az ayrıcalıklı çıkış zorunlu kılınır.
  • Dinamik Hizmet Bulma: Sabit kodlu URL'leri ve proje kimliklerini ortadan kaldırarak, çalışma zamanında Merkezi Ajan Kayıt Defteri aracılığıyla eş ajan uç noktalarını çözümler.
  • Çalışma Zamanı Politikası Çevikliği: Politika güncellemesi aracılığıyla, kapsayıcı yeniden başlatılmadan, pizza-seller-agent varsayılan olarak reddetme (403 Forbidden) durumundan izin verme (200 OK) durumuna anında geçiş yapıldı.

cosmopup

Cosmopup diyor ki: "Aracılar harika. Ben asıl hedefime (uyumak) odaklanırken onlar projeler arası tüm işleri hallediyor."

Sonraki Adımlar ve Belgeler