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

Cosmopup กล่าวว่า "Agent มีประโยชน์มาก เพราะช่วยทำงานข้ามโปรเจ็กต์ทั้งหมดได้ในขณะที่ฉันมุ่งเน้นไปที่วัตถุประสงค์หลัก นั่นคือการงีบหลับ"
ขั้นตอนถัดไปและเอกสารประกอบ
- ภาพรวมแพลตฟอร์ม Agent ของ Gemini Enterprise
- กำหนดค่าและติดตั้งใช้งาน Agent Gateway
- ข้อมูลเจาะลึกเกี่ยวกับข้อมูลประจำตัวของ Agent และการรับรอง SPIFFE
- นโยบายการเข้าถึงแบบรวมของ IAM และแอตทริบิวต์ CEL
- ภาพรวมแคตตาล็อกบริการ Agent Registry
- Model Armor Guardrails และการคุ้มครองข้อมูลที่ละเอียดอ่อน
- อินเทอร์เฟซ Private Service Connect (PSC-I) ที่มี Agent Gateway