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

1. Giriş

Kuruluşlar üretken yapay zekayı benimsedikçe mimariler de bağımsız, monolitik chatbot'lardan dağıtılmış çoklu temsilci sistemlerine (temsilciden temsilciye/A2A) hızla geçiyor. Bu modern topolojilerde, üst düzey düzenleyici ajanlar; bağımsız Google Cloud projelerindeki özel alan çalışan ajanlarına, Model Context Protocol (MCP) araç sunucularına ve arka uç kurumsal veritabanlarına görevler atayarak karmaşık iş akışlarını koordine eder.

Ancak çok aracılı sistemleri büyük ölçekte çalıştırmak, güvenlik, yönetim ve operasyon açısından önemli zorluklar doğurur:

  • Gölge Temsilci ve Araç Sayısında Aşırı Artış: Geliştirme ekipleri, merkezi bir katalog olmadan izole projelerde temsilci dağıttığında kuruluşlar hangi araçların ve alt temsilcilerin mevcut olduğunu göremez.
  • İzlenmeyen projeler arası çıkış: Temsilcilere doğrudan, denetlenmeyen ağ rotaları verilmesi, veri hırsızlığı riskleri oluşturur ve güvenlik sınırlarını atlar.
  • Kırılgan Sabit Kodlu Entegrasyonlar: Alt aracı URL'lerini ve Reasoning Engine kimliklerini sabit kodlamak, yükseltmeler veya yeniden dağıtımlar sırasında bozulan kırılgan bağımlılıklar oluşturur.
  • En az ayrıcalık kimliğinin olmaması: Paylaşılan hizmet hesapları, bireysel temsilci örneği düzeyinde kriptografik inkar edilemezlik sağlayamaz.

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

  1. Agent Gateway (networkservices.googleapis.com): Yönetilen, bölgesel bir ağ ve politika yaptırım proxy'si. AGENT_TO_ANYWHERE çıkış modunda çalışan bu bileşen, giden temsilci trafiğini yakalar, yetkilendirme değerlendirmelerini güvenlik uzantılarına devreder ve istekleri proje çevreleri arasında yönlendirir.
  2. Agent Registry (agentregistry.googleapis.com): Tek kurumsal hizmet kataloğu. Kuruluş genelinde mevcut tüm araçların, MCP sunucularının ve eş aracıların merkezi ve incelenmiş bir dizinini sunar. Böylece, sabit kodlu uç noktalar olmadan dinamik çalışma zamanı otomatik keşfini etkinleştirir.
  3. Temsilci Kimliği ve IAP v2 Yönetimi (iap.googleapis.com ve iam.googleapis.com): Kriptografik kimlik ve erişim çerçevesi. Yürütülen aracılar, benzersiz ve onaylanmış SPIFFE makine URN'leri (principal://...) alır. Giden çıkış, zengin Common Expression Language (CEL) katalog koşullarını (destination.agent_registry.*) kullanarak evrensel izni (iap.googleapis.com/resources.egressViaIAP) doğrulayan merkezi IAM Birleştirilmiş Erişim Politikaları'na (UAP/IAP v2) göre değerlendirilir.
  4. Agent Runtime (Reasoning Engines): Python tabanlı temsilci uygulamaları için merkezi ağ geçitlerine yerel yapılandırma bağlamaları (agent_gateway_config) içeren, 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 bir çok projeli satın alma ekosistemi oluşturacak ve yöneteceksiniz:

  • Merkezi Yönetim Projesi (PROJECT_GOVERNANCE): Merkezi BT ve SecOps'a aittir. Merkezi Temsilci Ağ Geçidi, Merkezi Temsilci Kayıt Defteri ve IAM Birleştirilmiş Erişim Politikaları'nı barındırır.
  • Tüketici Düzenleyici Projesi (PROJECT_CONCIERGE): Satın alma ekibine aittir ve tedarikçileri dinamik olarak keşfedip müşteri siparişlerini yönlendiren Satın Alma Concierge Temsilcisi'ni barındırır.
  • Alan Tedarikçi Projesi (PROJECT_SELLERS): Harici veya departman tedarikçilerine ait olan bu proje, Burger Satıcı Temsilcisi ve Pizza Satıcı Temsilcisi'ni barındırır.

figure1

Şekil 1. Çok projeli merkezi yönetim mimarisi

Neden projeler arası merkezi yönetim?

Büyük kurumsal şirketlerde ürün ekipleri ve veri bilimi grupları, onlarca bağımsız Google Cloud projesinde yapay zeka ajanları oluşturur. Her ekibe araç kaydı, çıkış ağı rotaları ve güvenlik önlemleri ü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çalı denetleme günlüklerine yol açar.

Projeler arası merkezi yönetim, politika yazma işlemini temsilci yürütme işleminden ayırır:

  • Merkezi BT ve SecOps, tek bir Merkezi Yönetim Projesi'nde güvenlik politikaları oluşturur, araçları inceler ve çıkışları izler.
  • Ürün ve uygulama ekipleri, bağımsız aracı çalışma zamanı projelerinde yalnızca iş mantığına odaklanır. Yerel VPC'leri, ara bağlantıları veya parçalı politika motorlarını yönetmenin operasyonel 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 İki Katmanlı Kimlik Kapsamı Modeli

Temsilciler, Merkezi Temsilci Ağ Geçidi üzerinden iletişim kurduğunda Identity-Aware Proxy (IAP v2), erişimi arayanın Temsilci Kimliği'ne göre değerlendirir. Bu kimlik, çalışma zamanı container'ına otomatik olarak verilen, şifreleme ile onaylanmış, SPIFFE tabanlı bir kimliktir ve global bir IAM erişim politikasına göre değerlendirilir:

  • 1. Katman: Temel Google Cloud API'leri (1. Kural'da principalSet:// aracılığıyla kaba taneli): Spoke projelerindeki tüm temsilci çalışma zamanlarının keşif, jeton oluşturma ve çıkarım için standart Google API'lerine (aiplatform, iamcredentials, telemetry, agentregistry) erişmesine olanak tanıyan proje genelinde çıkış yetkilendirmesi.
  • 2. Katman: İş Araçları ve A2A Hizmetleri (2. ve 3. Kurallarda principal:// ile Ayrıntılı): Belirli kayıtlı Temsilci Kayıt Defteri hizmetlerini (destination.agent_registry.agent.name) hedefleyen Common Expression Language (CEL) koşullarıyla uygulanan, bireysel Reasoning Engine örneklerine bağlı katı en az ayrıcalık erişimi.

Oluşturacağınız içerik

  • PROJECT_GOVERNANCE bölgesinde merkezi Agent Gateway (centralized-agw)
  • Katı zorunlu modda IAP v2 Yetkilendirme Hizmeti Uzantısı ve Authz Politikası (failOpen: false)
  • Temel IAM Birleştirilmiş Erişim Politikası (uap-rules.json) ve proje politika bağlaması
  • Projeler arası hizmet aracısı IAM izinleri (ar_agw_cross_project_sa)
  • Paylaşılan merkezi Google Cloud Storage (GCS) hazırlama paketi
  • PROJECT_SELLERS bölgesindeki izole hamburger ve pizza satıcısı temsilcileri
  • PROJECT_CONCIERGE dilinde dinamik REST otomatik keşif özelliğine sahip Satın Alma Concierge Aracısı
  • Projeler arası mTLS URL'leri ile Merkezi Temsilci Kayıt Defteri'ndeki 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) devretme
  • Kayıtlı Temsilci Kayıt Defteri hedeflerini (destination.agent_registry.*) yöneten Common Expression Language (CEL) kurallarıyla IAM Birleştirilmiş Erişim Politikaları'nı (UAP) yazma ve bağlama
  • Temsilci Kayıt Defteri'ne karşı çalışma zamanı otomatik keşfini kullanarak sabit kodlu temsilci kimliklerini ve URL'leri ortadan kaldırma
  • Gerçek çevre sıfır güven engellemesini (HTTP 403 Forbidden) test etme 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 defteri ve IAM erişim politikaları
    • PROJECT_CONCIERGE: Satın alma temsilcisi düzenleyici temsilci
    • PROJECT_SELLERS: Burger ve pizza uzmanı satıcı temsilcileri
  • 3 projenin tamamında 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 CLI, python (3.11+) ve uv yüklü yerel bir makine

Giriş bölümü tamamlandı. Şimdi Kurulum ve Ortam bölümüne geçelim.

2. Kurulum

Bu mimari 3 farklı Google Cloud projesini kapsasa da terminal dağıtım komutlarının, depo indirme işlemlerinin ve hazırlık işlemlerinin tamamı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 hedeflemelidir.

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

Projenizin bağlamını belirleme

# 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 özgü 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 Veri Erişimi Günlükleri'ni etkinleştirme

Google Cloud, istenmeyen depolama maliyetlerini önlemek için Veri Erişimi denetleme günlüklerini varsayılan olarak devre dışı bırakır. IAP v2, yetkilendirme kararlarını (granted=true ve granted=false) Veri Erişimi denetleme günlükleri olarak yayınladığından PROJECT_GOVERNANCE içinde 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

Üç projede de (PROJECT_GOVERNANCE, PROJECT_CONCIERGE ve PROJECT_SELLERS) tam olarak aynı API'lerin etkinleştirilmesi, operasyonel tutarlılık sağlar ve çalışma zamanı jeton oluşturma hatalarını, şema kataloglama hatalarını veya telemetri kesintilerini önler.

Üç projenin tamamında API eşdeğerliğ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 (constraints/iam.managed.disableAccessPolicyBinding) kısıtlayan kısıtlamalar uygular.

enforce: false değerini açıkça "allow" (izin ver) olarak ayarlayarak proje düzeyinde devralınan tüm 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ü tamamlandı. Şimdi Temel Google API'lerini kaydetme bölümüne geçelim.

3. Agent Registry

Temel Google API'leri uç nokta hizmetini kaydetme

Agent Gateway, agent_gateway_config ile yapılandırılan temsilcilerin çıkış trafiğini temel Google Cloud arka uç hizmetlerine (ör. aiplatform, IAM kimlik bilgileri ve telemetri) güvenli bir şekilde yönlendirebilmesi için Google API URL'lerinin Merkezi Temsilci Kayıt Defteri'ne kaydedilmesini gerektirir.

Temsilci Kayıt Defteri'nde core-gapi-services oluşturun

# 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 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ği'nde principalSet ve principal arasındaki farkı anlama

Google Cloud IAM ve Gemini Enterprise Agent Platform'da, çalışan temsilci container'larına verilen makine kimlikleri, Identity-Aware Proxy (IAP v2) tarafından değerlendirilen kriptografik olarak onaylanmış SPIFFE URN'lerini kullanır. IAM Birleştirilmiş Erişim Politikaları'nı yapılandırırken belirli bir principal'i veya özelliğe dayalı bir principalSet'i 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 akıl yürütme motorlarını tanımlar.

URN kalıbı

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'da kullanım alanı

2.katman (İşletme Araçları ve A2A): Belirli düzenleyici temsilcilerin hedef alan araçlarını çağırmasına izin verme (ör. Satın Alma Danışmanı $\rightarrow$ Burger Satıcısı).

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

Yaşam Döngüsü Etkisi

Bir temsilci silinip yeniden oluşturulursa yeni motor kimliği için güncellenmiş bir IAM politika bağlaması gerekir.

Ek IAM güncellemeleri olmadan, ilgili projede yeni dağıtılan temsilcilere otomatik olarak uygulanır.

Birleşik Erişim Politikaları (UAP/IAP v2) ile Bildirimli Yönetim

Eski IAP v1'de çıkış politikaları, gcloud beta iap web add-iam-policy-binding kullanılarak doğrudan her bir Agent Registry kaynağına ekleniyordu. IAP v2 ve Birleştirilmiş Erişim Politikaları kapsamında, kaynak başına bağlamalar yerine tek bir merkezi IAM Erişim Politikası (cfg/uap-rules.json) kullanı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ılacak. Böylece tüm temsilci container'ları için dağıtımdan önce temel çıkış rotaları oluşturulacak.

Asıl tanımlayıcılar ve Workload Identity mekanizmaları hakkında daha ayrıntılı teknik bilgi için aşağıdaki kaynakları inceleyin:

Böylece temel API'lerin uç nokta kaydı tamamlanmış oldu. Şimdi Merkezi Agent Gateway'i dağıtma bölümüne geçelim.

4. Agent Gateway

Merkezi Agent Gateway'i dağıtma

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

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

Giden trafik 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ı İç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}

Temsilci 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çelim.

5. Yetkilendirme

Agent Gateway yetkilendirmesini ve temel UAP'yi yapılandırma

Agent Gateway, Identity-Aware Proxy (IAP v2) Birleşik Erişim Politikaları (UAP) ile entegre edilmiş Yetkilendirme Politikaları (networksecurity.authzPolicies) kullanarak giden araç ve temsilci trafiğini güvence altına alır 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): Katı çevre sıfır güven yaptırımı 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, yetkilendirme kontrollerini IAP Authz Uzantısı'na yönlendiren bölgesel kaynak.
  3. IAM Birleştirilmiş Erişim Politikası ve Bağlama (accessPolicy ve policyBinding): IAP tarafından değerlendirilen global IAM v3 kaynağı. Arayan SPIFFE kimlikleri ve CEL kataloğu koşullarına göre evrensel izin iap.googleapis.com/resources.egressViaIAP'i doğrular.

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

iapPolicyVersion: "V2" ve failOpen: false ile katı ENFORCE modunda Service Extension manifestini 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 uzantısına 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 (1. kural: Temel Google API'leri)

1. kuralın üç projenin (principalSet) core-gapi-services'ye erişmesine izin verdiği cfg/uap-rules.json oluşturun:

# 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 her üç projede de katı ENFORCE modunda güvenli bir şekilde yetkilendirildi.

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, Agent Runtime'lar bağlı projelerde (PROJECT_CONCIERGE ve PROJECT_SELLERS) bulunurken Central Agent Gateway ve Agent Registry PROJECT_GOVERNANCE projesinde bulunur.

Google Cloud projeleri izole 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 temsilci container'ı dağıtılırken bağlı bileşen projesinin temsilci çalışma zamanı hizmet aracısı (service-@gcp-sa-aiplatform.iam.gserviceaccount.com), container'ı 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şturuyoruz.
  2. Veri düzlemi (çalışma zamanı yürütme):
    • Katalog Keşfi: Spoke kimliklerinin, hedef aracı uç noktalarını dinamik olarak çözümlemek için PROJECT_GOVERNANCE içinde roles/agentregistry.viewer rolüne ihtiyacı vardır.
    • Hedef Çağrı: Concierge temsilcisinin, satıcı akıl yürütme motorlarına yönelik sorguları yürütmek için PROJECT_SELLERS içinde roles/aiplatform.user'ye ihtiyacı var.

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 hizmet aracısı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çelim.

7. Agent Runtime

Satıcı ve Concierge Temsilcileri Dağıtma

Bu codelab'de kullanılan çoklu ajan uygulama kod tabanı ve dağıtım komut dosyaları, uzak bir Google Cloud GitHub deposunda barındırılır. 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ı getir

# 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

Paylaşılan Merkezi Hazırlık 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ı Agent Gateway Bağlantısının İşleyiş Şekli

Bu adımda, Seller Agent'ları uç projeye (PROJECT_SELLERS) dağıtırken çıkış trafiğini PROJECT_GOVERNANCE içindeki merkezi Agent Gateway üzerinden yönlendirecek şekilde yapılandıracaksı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ştirilmiş Erişim Politikamızda daha önce oluşturulduğu için Google Cloud API'lerine yönelik container başlatma isteklerine ağ geçidi üzerinden kesintisiz olarak izin verilir.

Burger ve Pizza Satıcısı Temsilcilerini PROJECT_SELLERS'e dağıtma

# 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 Temsilcisi'ni PROJECT_CONCIERGE konumuna 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}'

Çıkışta Concierge temsilcisinin çalışma zamanı kimliği ve projesi ile Governance projesinin Agent Gateway'ine bağlama işlemi 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"
    }
  }
}

Temsilci dağıtımları tamamlandı. Şimdi Temsilcileri Merkezi Temsilci Kayıt Defteri'ne kaydetme bölümüne geçelim.

8. Projeler arası kayıt defteri

Temsilcileri Merkezi Temsilci Kayıt Defteri'ne kaydetme

Projeler arası bölgesel mTLS uç noktalarını ve sayısal proje numaralarını kullanarak üç temsilciyi de PROJECT_GOVERNANCE bölgesindeki Merkezi Temsilci Kayıt Defteri'ne kaydedin.

Hizmetleri Agent Registry'de A2A aracısı olmayan temsilciler 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.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

Temel Temsilci 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çelim.

9. UAP politikaları

Birleştirilmiş erişim politikasında A2A çıkış politikalarını yapılandırma

Agent Gateway'in katı ENFORCE modundaki Default Deny mimarisi kapsamında:

  1. 1. kural (Temel Google Cloud API'leri): 3 projenin tamamındaki aracı kapsayıcılarının core-gapi-services adresine erişmesine izin verir.
  2. 2. kural (Burger Seller Agent: ALLOW): Purchasing Concierge Agent örneğinin özellikle Burger Seller Agent'ı çağırmasına izin verir.
  3. Pizza Satıcısı Temsilcisi (Varsayılan olarak REDDEDİLDİ): Politika kurallarının dışında bırakılmıştır. ENFORCE modunda (failOpen: false), Concierge'in Pizza Seller'ı çağırma girişimleri, ağ geçidi çevresinde HTTP 403 Forbidden ile hemen sonlandırılır.

Concierge temsilci kimliğini oluşturma

# formulate the exact SPIFFE machine identity for the Concierge Agent
export CONCIERGE_SPIFFE_PRINCIPAL="principal://agents.global.org-${ORG_ID}.system.id.goog/resources/aiplatform/projects/${PROJECT_NUMBER_CONCIERGE}/locations/${REGION}/reasoningEngines/${CONCIERGE_ENGINE_ID}"
echo "Concierge SPIFFE Principal: ${CONCIERGE_SPIFFE_PRINCIPAL}"

1 ve 2 numaralı kurallarla güncelleme manifesti

Erişim politikasını mevcut kuralları bozmadan güvenli bir şekilde güncellemek için 1. kural (temel Google API'leri) ve 2. kuralı (Burger Seller Agent) içeren tam birleştirilmiş manifesti tanımlayın:

# 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

Güncellenen erişim politikasını uygulama

--details-rules kullanarak birleştirilmiş kural manifestini bildirimli olarak uygulayın:

# 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 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çelim.

10. Politikaları doğrulama

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

Bu bölümde, Agent Runtime AI Atölyesi'nde projeler arası Agent-to-Agent (A2A) etkileşimlerini test edecek, katı ENFORCE modunda gerçek çevre HTTP 403 Forbidden engellemesini 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 uygulamasında Agent Runtime AI Atölyesi'ni açın.

  1. Google Cloud Console'u açın.
  2. Üstteki proje seçici çubuğunda PROJECT_CONCIERGE projesine geçin.
  3. Gezinme menüsünde Agent Platform > Agents > Deployments'a (Agent Platform > Temsilciler > Dağıtımlar) gidin.
  4. purchasing-concierge-adk simgesini tıklayın.
  5. Ekranın sağ tarafındaki 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 edebilirsiniz:

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

Arka planda gerçekleşen işlemler:

  1. Dinamik Keşif: Oturum başlatma sırasında Satın Alma Concierge'i, burger-seller-agent için bölgesel mTLS uç noktasını keşfetmek amacıyla PROJECT_GOVERNANCE bölgesindeki Merkezi Temsilci Kayıt Defteri'ni (1. kural tarafından yetkilendirilen Temsilci Ağ Geçidi aracılığıyla core-gapi-services üzerinden) sorguladı.
  2. Niyet Çözümleme ve A2A Çağrısı: Purchasing Concierge'deki Gemini, yemek siparişi niyetini ayrıştırır ve https://${REGION}-aiplatform.mtls.googleapis.com/.../reasoningEngines/${BURGER_ENGINE_ID} adresine giden bir RPC aracılığıyla Burger Seller Agent'ı çağırır.
  3. Ağ Geçidi Engelleme ve SPIFFE Yayılımı: Çıkış trafiği agent_gateway_config tarafından yakalanır ve Concierge'in şifreleme SPIFFE kimliğini (principal://...) taşıyarak PROJECT_GOVERNANCE içindeki Merkezi Agent Gateway'e yönlendirilir.
  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) döndürür.
  5. Projeler arası yürütme: Agent Gateway, yetkili isteği projeler arası olarak PROJECT_SELLERS projesine 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: Agent Gateway ve IAP v2 denetleme günlüklerini inceleyin (HTTP 200 / ALLOWED)

PROJECT_GOVERNANCE içinde Agent Gateway istek günlüklerini sorgulama:

# 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, her iki uç projeden (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ı içerir. Bu alanlar, 1. kural (core-gapi-services) tarafından şeffaf bir şekilde yakalanır ve yetkilendirilir.

Politika sürümünü (POLICY_VERSION_V2) doğrulamak için IAP v2 Cloud Audit Data Access 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 çı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 etme (Varsayılan olarak reddetme -> HTTP 403 Yasak UYGULANDI)

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 edebilirsiniz:

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.

Arka planda gerçekleşen işlemler:

  1. Dinamik Keşif: Satın Alma Concierge'i, başlangıç sırasında Merkezi Temsilci Kayıt Defteri'nden pizza-seller-agent uç noktasını çözümledi.
  2. Amaç Çözümleme ve A2A Çağrısı: Satın Alma Danışmanı'ndaki Gemini, pizza siparişi isteğini PROJECT_SELLERS'deki Pizza Satıcısı uç noktasına göndermeye çalışır.
  3. Ağ Geçidi Engelleme: Giden RPC, agent_gateway_config tarafından yakalanır ve Merkezi Temsilci Ağ Geçidi'ne yönlendirilir.
  4. IAP v2 politika değerlendirmesi (varsayılan olarak reddetme): Merkezi temsilci ağ geçidi, IAP v2'yi çağırır. Birleştirilmiş Erişim Politikası'nda pizza-seller-agent ile eşleşen hiçbir kural bulunmadığından IAP, DENY (granted: false) döndürür.
  5. Katı Çevre Engellemesi: Authz Uzantısı ZORUNLU modda (failOpen: false) olduğundan Merkezi Aracı Ağ Geçidi, 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'a ulaşmaz.

5. adım: Engellenen istekler (HTTP 403 / REDDEDİLDİ) için Agent Gateway günlüklerini inceleyin

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

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

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 Temsilcisi'ne dinamik olarak çıkış erişimi verme

1. kural (temel API'ler), 2. kural (hamburger satıcısı temsilcisi) ve şimdi 3. kuralı (pizza satıcısı temsilcisi) içerecek yeni bir 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 temsilcisini tekrar sorgulama (Anında 200 OK yanıtı)

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 edebilirsiniz:

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

Arka planda gerçekleşen işlemler:

  1. Dinamik politika yenileme: IAM Birleştirilmiş Erişim Politikası'nın güncellenmesi, IAP değerlendirme motorunda sıfır kesinti süresiyle ve herhangi bir container'ı yeniden dağıtmadan hemen geçerli olur.
  2. A2A çağrısı: 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ın 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 Temsilci Ağ Geçidi, yetkili trafiği PROJECT_SELLERS projesine yönlendirir. Pizza Satıcısı, siparişi bu projede işler.

8. adım: Onaylanan pizza istekleri için Agent Gateway günlüklerini inceleme

# 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 İzin Verilen Günlük Çıkışı:

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

Test ve doğrulama işlemi tamamlandı. Şimdi Temizleme bölümüne geçelim.

11. Temizleme

Bu codelab'de kullanılan kaynaklar için Google Cloud hesabınızdan ücret alınmasını önlemek amacıyla, kaldırma adımlarını bağımlılık sırasının tam tersi şekilde uygulayın:

1. Reasoning Engine Dağıtımlarını Temizleme

Akıl yürütme motorlarını silmek ve uzun süreli işlemlerini beklemek için her iki çalışma zamanı projesinde de dahil edilen 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çinde 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. Temsilci Kayıt Defteri 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ğlaması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. Agent Gateway'i 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. Denetim 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 alma

# 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 paketini 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ü tamamlandı. Şimdi Sonuç bölümüne geçelim.

12. Sonuç

Tebrikler! Vertex AI Agent Runtime, Central Agent Gateway, Agent Registry ve IAM Birleşik Erişim Politikaları'nı (UAP) kullanarak Google Cloud'da çok projeli bir yapay zeka ajanından yapay zeka ajanına (A2A) mimarisi dağıttınız ve yönettiniz.

Temel Kavramların Özeti

  • Merkezi çıkış çevresi: agentGatewayConfig kullanarak PROJECT_GOVERNANCE içindeki merkezi bir Agent Gateway üzerinden yönlendirilen bağlı bileşen çalışma zamanı kapsayıcıları (PROJECT_CONCIERGE, PROJECT_SELLERS).
  • Bildirim temelli yönetim (UAP): Parçalı kaynak bazlı bağlamalar, ağ geçidinde IAP v2 tarafından değerlendirilen tek ve denetlenebilir bir IAM erişim politikasıyla değiştirildi.
  • Kriptografik Kimlik: Uzun ömürlü anahtarlar yerine kapsayıcı SPIFFE kimlikleri (principal://...) kullanılarak zorunlu kılınan en az ayrıcalıklı çıkış.
  • Dinamik hizmet keşfi: Çalışma zamanında, Merkezi Temsilci Kayıt Defteri aracılığıyla eş temsilci uç noktaları çözümlenerek sabit kodlu URL'ler ve proje kimlikleri ortadan kaldırıldı.
  • Çalışma Zamanı Politikası Çevikliği: Politika güncellemesi aracılığıyla, container'ı yeniden başlatmaya gerek kalmadan pizza-seller-agent, Varsayılan Reddetme (403 Forbidden) durumundan İzin Verildi (200 OK) durumuna anlık olarak geçirildi.

cosmopup

Cosmopup diyor ki: "Temsilciler harika. Ben asıl hedefim olan uykuya odaklanırken onlar projeler arası tüm işleri hallediyor."

Sonraki Adımlar ve Belgeler