Quản trị tập trung Agent Gateway bằng Agent Registry trên nhiều dự án cho Agent Runtime

1. Giới thiệu

Khi các tổ chức doanh nghiệp áp dụng AI tạo sinh, kiến trúc đang nhanh chóng phát triển từ các chatbot nguyên khối, độc lập thành hệ thống đa tác nhân phân tán (Tác nhân với tác nhân/A2A). Trong các cấu trúc liên kết hiện đại này, các tác nhân điều phối cấp cao sẽ điều phối các quy trình làm việc phức tạp của doanh nghiệp bằng cách uỷ quyền nhiệm vụ cho các tác nhân thực hiện miền chuyên biệt, máy chủ công cụ Giao thức ngữ cảnh mô hình (MCP) và cơ sở dữ liệu doanh nghiệp phụ trợ trên các dự án trên đám mây độc lập của Google Cloud.

Tuy nhiên, việc vận hành hệ thống nhiều tác nhân trên quy mô lớn cũng đặt ra những thách thức nghiêm trọng về bảo mật, quản trị và vận hành:

  • Tác nhân ngầm và sự gia tăng công cụ: Khi các nhóm phát triển triển khai tác nhân trong các dự án riêng biệt mà không có danh mục tập trung, tổ chức sẽ mất khả năng theo dõi các công cụ và tác nhân phụ hiện có.
  • Lưu lượng truy cập ra ngoài không được giám sát giữa các dự án: Việc cho phép các tác nhân truy cập trực tiếp vào các tuyến mạng không được kiểm tra sẽ tạo ra rủi ro rò rỉ dữ liệu và vượt qua các ranh giới bảo mật.
  • Tích hợp cố định giá trị trong mã dễ hỏng: Việc cố định giá trị trong mã URL của tác nhân hạ nguồn và mã nhận dạng của Reasoning Engine sẽ tạo ra các phần phụ thuộc dễ hỏng trong quá trình nâng cấp hoặc triển khai lại.
  • Thiếu danh tính có đặc quyền tối thiểu: Tài khoản dịch vụ dùng chung không cung cấp được tính năng chống thoái thác bằng mật mã ở cấp thực thể tác nhân riêng lẻ.

Để giải quyết những thách thức này, Nền tảng tác nhân Gemini Enterprise cung cấp một mặt phẳng kiểm soát kết nối và quản trị hợp nhất, bao gồm 4 trụ cột chính:

  1. Cổng tác nhân (networkservices.googleapis.com): Một proxy thực thi chính sách và mạng khu vực được quản lý. Hoạt động ở chế độ đầu ra AGENT_TO_ANYWHERE, thành phần này chặn lưu lượng truy cập của tác nhân đi ra, uỷ quyền đánh giá cho các tiện ích bảo mật và định tuyến các yêu cầu trên phạm vi dự án.
  2. Sổ đăng ký tác nhân (agentregistry.googleapis.com): Danh mục dịch vụ doanh nghiệp duy nhất. Thư mục này cung cấp một thư mục tập trung, đã được kiểm tra về tất cả các công cụ, máy chủ MCP và tác nhân ngang hàng hiện có trong toàn tổ chức, cho phép tự động phát hiện trong thời gian chạy mà không cần điểm cuối được mã hoá cứng.
  3. Quản trị Danh tính tác nhân và IAP phiên bản 2 (iap.googleapis.com và iam.googleapis.com): Một khung danh tính và quyền truy cập bằng mật mã. Các tác nhân thực thi nhận được URN máy SPIFFE duy nhất, được chứng thực (principal://...). Lưu lượng truy cập ra ngoài được đánh giá dựa trên Chính sách truy cập hợp nhất (UAP/IAP phiên bản 2) của IAM tập trung, xác minh quyền chung iap.googleapis.com/resources.egressViaIAP bằng cách sử dụng các điều kiện danh mục Ngôn ngữ biểu thức chung (CEL) phong phú (destination.agent_registry.*).
  4. Môi trường thời gian chạy của tác nhân (Công cụ suy luận): Một nền tảng thực thi không máy chủ, được quản lý toàn diện cho các ứng dụng tác nhân dựa trên Python, có các liên kết cấu hình gốc (agent_gateway_config) với cổng trung tâm.

Kịch bản kinh doanh trong lớp học lập trình: Mua thực phẩm và đồ uống cho nhiều dự án

Trong lớp học lập trình này, bạn sẽ xây dựng và quản lý một hệ sinh thái mua hàng thực tế gồm nhiều dự án, trải dài trên ba dự án riêng biệt của Google Cloud:

  • Dự án quản trị trung tâm (PROJECT_GOVERNANCE): Do nhóm CNTT trung tâm và SecOps sở hữu, lưu trữ Cổng tác nhân trung tâm, Sổ đăng ký tác nhân trung tâm và Chính sách truy cập hợp nhất của IAM.
  • Dự án Consumer Orchestrator (PROJECT_CONCIERGE): Do nhóm thu mua sở hữu, lưu trữ Tác nhân hỗ trợ mua hàng, có chức năng tự động tìm nhà cung cấp và định tuyến đơn đặt hàng của khách hàng.
  • Dự án của nhà cung cấp miền (PROJECT_SELLERS): Do nhà cung cấp bên ngoài hoặc nhà cung cấp của bộ phận sở hữu, lưu trữ Tác nhân người bán bánh mì kẹp thịt và Tác nhân người bán bánh pizza.

figure1

Hình 1. Cấu trúc quản trị tập trung cho nhiều dự án

Tại sao nên quản trị tập trung trên nhiều dự án?

Trong các tổ chức doanh nghiệp lớn, nhóm phụ trách sản phẩm và nhóm khoa học dữ liệu xây dựng các tác nhân AI trên hàng chục dự án trên đám mây độc lập trên Google Cloud. Việc cho phép mỗi nhóm trực tiếp kiểm soát việc đăng ký công cụ, tuyến mạng đi và các biện pháp bảo vệ an ninh sẽ dẫn đến tình trạng công cụ chưa được kiểm tra tràn lan, chính sách DLP không nhất quán, lưu lượng truy cập đi VPC không được giám sát và nhật ký kiểm tra bị phân mảnh.

Quản trị tập trung trên nhiều dự án tách biệt việc soạn thảo chính sách khỏi việc thực thi tác nhân:

  • Bộ phận CNTT và SecOps trung tâm soạn thảo các chính sách bảo mật, kiểm tra công cụ và giám sát dữ liệu đầu ra trong một Dự án quản trị tập trung duy nhất.
  • Nhóm sản phẩm và ứng dụng chỉ tập trung vào logic kinh doanh trong Dự án thời gian chạy của tác nhân độc lập, liên kết trực tiếp với cổng trung tâm mà không cần tốn chi phí vận hành để quản lý VPC cục bộ, kết nối hoặc công cụ chính sách phân mảnh.

figure2

Hình 2. Cấu trúc và ranh giới quản trị ba cấp giữa các dự án

Mô hình phạm vi danh tính hai cấp trong Chính sách truy cập hợp nhất

Khi các tác nhân giao tiếp thông qua Cổng tác nhân trung tâm, Identity-Aware Proxy (IAP phiên bản 2) sẽ đánh giá quyền truy cập dựa trên Danh tính tác nhân của phương thức gọi (một danh tính dựa trên SPIFFE, được chứng thực bằng mật mã và được cấp tự động cho vùng chứa thời gian chạy) theo Chính sách truy cập IAM chung:

  • Cấp 1: API Google Cloud cơ sở (Thô qua principalSet:// trong Quy tắc 1): Uỷ quyền lưu lượng truy cập ra ngoài trên toàn dự án, cho phép tất cả thời gian chạy của tác nhân trên các dự án nhánh truy cập vào các API Google tiêu chuẩn (aiplatform, iamcredentials, telemetry, agentregistry) để khám phá, tạo mã thông báo và suy luận.
  • Cấp 2: Công cụ kinh doanh và dịch vụ A2A (Chi tiết thông qua principal:// trong Quy tắc 2 và 3): Quyền truy cập nghiêm ngặt theo đặc quyền tối thiểu liên kết với từng phiên bản Reasoning Engine, được thực thi bằng các điều kiện Ngôn ngữ biểu thức chung (CEL) nhắm đến các dịch vụ Agent Registry đã đăng ký cụ thể (destination.agent_registry.agent.name).

Sản phẩm bạn sẽ tạo ra

  • Cổng tác nhân tập trung (centralized-agw) trong PROJECT_GOVERNANCE
  • Tiện ích dịch vụ uỷ quyền IAP phiên bản 2 và Chính sách uỷ quyền ở chế độ THỰC THI nghiêm ngặt (failOpen: false)
  • Chính sách truy cập hợp nhất IAM cơ bản (uap-rules.json) và Liên kết chính sách dự án
  • Quyền IAM của tác nhân dịch vụ trên nhiều dự án (ar_agw_cross_project_sa)
  • Bộ chứa thử nghiệm trung tâm dùng chung trên Google Cloud Storage (GCS)
  • Tác nhân bán bánh mì kẹp thịt và bánh pizza riêng biệt tại PROJECT_SELLERS
  • Tác nhân hỗ trợ mua hàng có tính năng tự động khám phá REST linh động trong PROJECT_CONCIERGE
  • Đăng ký dịch vụ trong Central Agent Registry bằng URL mTLS giữa các dự án
  • Cập nhật chính sách lưu lượng truy cập đi động của IAP phiên bản 2 bằng quy trình xác minh trực tiếp và kiểm tra Cloud Logging

figure3

Hình 3. Trình tự triển khai từng bước

Kiến thức bạn sẽ học được

  • Cách định cấu hình quyền IAM của tác nhân dịch vụ trên nhiều dự án cho cổng tập trung
  • Cách định tuyến lưu lượng truy cập ra ngoài của Môi trường thời gian chạy của tác nhân thông qua một Cổng tác nhân trung tâm trên các môi trường nhiều dự án
  • Cách uỷ quyền cho Cổng tác nhân cho Identity-Aware Proxy (IAP phiên bản 2) bằng Tiện ích dịch vụ (iapPolicyVersion: "V2")
  • Cách tạo và liên kết Chính sách truy cập hợp nhất (UAP) của IAM với các quy tắc Ngôn ngữ biểu thức chung (CEL) chi phối các đích đến đã đăng ký trong Sổ đăng ký tác nhân (destination.agent_registry.*)
  • Cách loại bỏ mã nhận dạng và URL của tác nhân được cố định giá trị trong mã bằng cách sử dụng tính năng tự động khám phá trong thời gian chạy đối với Sổ đăng ký tác nhân
  • Cách kiểm tra hoạt động chặn không tin tưởng theo ranh giới thực tế (HTTP 403 Forbidden) và xác minh thông tin cập nhật chính sách trực tiếp trong Cloud Logging

Bạn cần có

  • 3 dự án trên Google Cloud đã bật tính năng thanh toán:
    • PROJECT_GOVERNANCE: Quản trị tập trung, cổng, sổ đăng ký và chính sách truy cập IAM
    • PROJECT_CONCIERGE: Tác nhân điều phối dịch vụ hỗ trợ mua hàng
    • PROJECT_SELLERS: Người bán chuyên về bánh mì kẹp và pizza
  • Một người dùng hoặc tài khoản dịch vụ IAM có quyền roles/owner hoặc quyền quản trị trên cả 3 dự án
  • Một tổ chức trên Google Cloud (để liên kết miền tin cậy SPIFFE)
  • Google Cloud Shell hoặc máy cục bộ đã cài đặt gcloud CLI, python (3.11 trở lên) và uv

Đến đây là kết thúc phần giới thiệu... tiếp theo là phần Thiết lập và môi trường.

2. Thiết lập

Mặc dù cấu trúc này trải rộng trên 3 dự án trên đám mây của Google Cloud riêng biệt, nhưng bạn có thể thực thi 100% lệnh triển khai thiết bị đầu cuối, tải kho lưu trữ xuống và các thao tác thử nghiệm từ một thiết bị đầu cuối Cloud Shell duy nhất được đặt thành PROJECT_GOVERNANCE. Mỗi tập lệnh triển khai và lệnh gcloud đều nhắm đến dự án đích phù hợp một cách rõ ràng thông qua cờ CLI (--project).

Bắt đầu bằng cách truy cập vào dòng lệnh của dự án Google Cloud:

  • Cloud Shell tại shell.cloud.google.com hoặc
  • Một thiết bị đầu cuối cục bộ đã cài đặt gcloud CLI

Thiết lập bối cảnh cho dự án

# 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

Đặt biến môi trường shell

Nhập giá trị nhận dạng cụ thể cho dự án của bạn.

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

Các biến shell này sẽ được lấy tự động.

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

Tạo thư mục cục bộ cho các tệp cấu hình

# create config folder
mkdir -p cfg

Chỉ định vai trò Quản trị viên chính sách truy cập cho Chính sách truy cập hợp nhất

# 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

Bật Nhật ký kiểm tra quyền truy cập dữ liệu trên đám mây cho IAP phiên bản 2

Theo mặc định, Google Cloud tắt Nhật ký kiểm tra quyền truy cập dữ liệu để tránh phát sinh chi phí lưu trữ ngoài ý muốn. Vì IAP phiên bản 2 đưa ra các quyết định uỷ quyền (granted=true và granted=false) dưới dạng nhật ký kiểm tra quyền truy cập dữ liệu, hãy bật tính năng ghi nhật ký ADMIN_READ, DATA_READ và DATA_WRITE cho iap.googleapis.com trong 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)"

Bật các API Google Cloud bắt buộc

# 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

Xác thực việc bật API trên tất cả dự án

Việc đảm bảo cả ba dự án (PROJECT_GOVERNANCE, PROJECT_CONCIERGE và PROJECT_SELLERS) đều bật cùng một API sẽ giúp đảm bảo tính nhất quán trong hoạt động và ngăn chặn lỗi tạo mã thông báo trong thời gian chạy, lỗi lập danh mục giản đồ hoặc lỗi đo từ xa.

Chạy tập lệnh xác thực sau trong Cloud Shell để xác minh tính tương đương của API trên cả ba dự á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

Kết quả xác thực mẫu:

Bạn sẽ thấy tất cả API đều được bật.

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

Định cấu hình chính sách của tổ chức

Chính sách mặc định của tổ chức trên Google Cloud thực thi các quy tắc ràng buộc nhằm hạn chế việc liên kết chính sách truy cập IAM phiên bản 3 với tài nguyên (constraints/iam.managed.disableAccessPolicyBinding).

Ghi đè mọi quy định hạn chế của chính sách tổ chức được kế thừa ở cấp dự án bằng cách đặt rõ ràng enforce: false thành cho phép.

# 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

Đến đây là kết thúc phần thiết lập... tiếp theo là phần Đăng ký API Google chính.

3. Sổ đăng ký tác nhân

Đăng ký dịch vụ điểm cuối API cốt lõi của Google

Cổng tác nhân yêu cầu URL API của Google phải được đăng ký trong Sổ đăng ký tác nhân trung tâm để các tác nhân được định cấu hình bằng agent_gateway_config có thể định tuyến lưu lượng truy cập đi một cách an toàn đến các dịch vụ phụ trợ chính của Google Cloud (chẳng hạn như aiplatform, Thông tin xác thực IAM và Đo từ xa).

Tạo core-gapi-services trong Sổ đăng ký tác nhân

# 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

Ghi lại mã tài nguyên điểm cuối của API cốt lõ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}"

Tìm hiểu về principalSet so với principal trong Danh tính của tác nhân

Trong Google Cloud IAM và Nền tảng tác nhân Gemini Enterprise, danh tính máy được cấp cho các vùng chứa tác nhân thực thi sẽ sử dụng URN SPIFFE được chứng thực bằng mật mã do Identity-Aware Proxy (IAP phiên bản 2) đánh giá. Khi định cấu hình Chính sách truy cập hợp nhất của IAM, bạn có thể nhắm đến một principal cụ thể hoặc một principalSet dựa trên thuộc tính:

Phương diện

principal:// (Danh tính máy duy nhất)

principalSet:// (Nhóm dựa trên thuộc tính)

Cú pháp IAM

principal://...

principalSet://...

Độ chi tiết

Chi tiết (Cấp thực thể): Xác định một thực thể vùng chứa Reasoning Engine cụ thể.

Thô (Cấp dự án): Xác định tất cả công cụ suy luận có chung một thuộc tính dự án.

Mẫu URN

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

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

Trường hợp sử dụng trong Nền tảng tác nhân

Cấp 2 (Công cụ kinh doanh và A2A): Cho phép các tác nhân điều phối cụ thể gọi các công cụ miền mục tiêu (ví dụ: Nhân viên hỗ trợ mua hàng $\rightarrow$ Người bán bánh mì kẹp thịt).

Cấp 1 (Cơ sở hạ tầng cơ bản): Cấp cho tất cả tác nhân trong một dự án quyền truy cập vào các API Google Cloud (core-gapi-services).

Tác động đến vòng đời

Nếu một tác nhân bị xoá và tạo lại, thì mã nhận dạng công cụ mới của tác nhân đó sẽ yêu cầu một liên kết chính sách IAM mới.

Tự động áp dụng cho các nhân viên hỗ trợ mới được triển khai trong dự án đó mà không cần cập nhật thêm IAM.

Quản trị khai báo bằng Chính sách truy cập hợp nhất (UAP/IAP phiên bản 2)

Trong IAP v1 cũ, các chính sách đầu ra được đính kèm trực tiếp vào từng tài nguyên của Sổ đăng ký tác nhân bằng gcloud beta iap web add-iam-policy-binding. Trong IAP phiên bản 2 và Chính sách truy cập hợp nhất, các mối liên kết theo tài nguyên sẽ bị loại bỏ để thay bằng một Chính sách truy cập IAM tập trung (cfg/uap-rules.json).

Quyền truy cập ra ngoài cơ bản cho core-gapi-services sẽ được định cấu hình là Quy tắc 1 trong Chính sách truy cập hợp nhất ở Mục 5, đảm bảo rằng tất cả vùng chứa tác nhân đều có các tuyến truy cập ra ngoài cơ bản được thiết lập trước khi triển khai.

Để biết thêm thông tin kỹ thuật chi tiết về giá trị nhận dạng chính và cơ chế Workload Identity, hãy xem:

Đến đây là kết thúc phần đăng ký điểm cuối API cốt lõi... tiếp theo là phần Triển khai Cổng tác nhân tập trung.

4. Agent Gateway

Triển khai Agent Gateway tập trung

Triển khai Cổng tác nhân tập trung (centralized-agw) ở chế độ lưu lượng truy cập ra ngoài AGENT_TO_ANYWHERE bên trong dự án $PROJECT_GOVERNANCE.

Xác định tệp kê khai cấu hình cổng

Tạo cfg/${AGW_NAME}.yaml để quản lý lưu lượng truy cập ra ngoài:

# 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

Nhập cấu hình cổng tác nhân

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

Xác minh thông tin chi tiết về cổng tác nhân

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

Kết quả mẫu:

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'

Đến đây là kết thúc phần triển khai cổng... tiếp theo là phần Định cấu hình uỷ quyền.

5. Ủy quyền

Định cấu hình quyền uỷ quyền của cổng tác nhân và UAP cơ bản

Cổng tác nhân bảo mật và quản lý lưu lượng truy cập của công cụ và tác nhân đi ra ngoài bằng Chính sách uỷ quyền (networksecurity.authzPolicies) được tích hợp với Chính sách truy cập hợp nhất (UAP) của Identity-Aware Proxy (IAP phiên bản 2).

Tổng quan về cấu trúc uỷ quyền

figure4

Hình 4. Tổng quan về cấu trúc uỷ quyền

Cấu trúc uỷ quyền bao gồm 3 lớp liên kết với nhau:

  1. Tiện ích dịch vụ IAP (authzExtension): Tài nguyên theo khu vực được định cấu hình bằng service: iap.googleapis.com, metadata: iapPolicyVersion: "V2" và failOpen: false để thực thi nghiêm ngặt mô hình không tin tưởng bất cứ nguồn nào ở ranh giới.
  2. Chính sách uỷ quyền của cổng (authzPolicy): Tài nguyên theo khu vực nhắm đến Cổng tác nhân của bạn bằng policyProfile: REQUEST_AUTHZ và action: CUSTOM, định tuyến các bước kiểm tra uỷ quyền đến Tiện ích uỷ quyền IAP.
  3. Chính sách và mối liên kết truy cập hợp nhất của IAM (accessPolicy và policyBinding): Tài nguyên IAM v3 chung được IAP đánh giá. Hàm này xác minh quyền chung iap.googleapis.com/resources.egressViaIAP dựa trên danh tính SPIFFE của phương thức gọi và điều kiện danh mục CEL.

Bước 1: Tạo và nhập tiện ích uỷ quyền IAP phiên bản 2

Tạo tệp kê khai Tiện ích dịch vụ bằng iapPolicyVersion: "V2" và failOpen: false ở chế độ ENFORCE nghiêm ngặt:

# 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

Nhập Tiện ích Authz:

# import IAP v2 authz extension
gcloud service-extensions authz-extensions import ${AGW_NAME}-svc-ext-authz-iap \
  --source=cfg/${AGW_NAME}-svc-ext-authz-iap.yaml \
  --location=${REGION} \
  --project=${PROJECT_GOVERNANCE}

Xác minh rằng Tiện ích Authz đang hoạt động:

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

Kết quả mẫu:

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

Bước 2: Tạo và nhập Chính sách uỷ quyền cổng

Tạo một cấu hình Chính sách uỷ quyền đính kèm vào Cổng tác nhân và uỷ quyền xác minh yêu cầu cho Tiện ích uỷ quyền IAP:

# 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

Nhập Chính sách uỷ quyề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}

Xác minh Chính sách uỷ quyền đang hoạt động:

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

Bước 3: Tạo Chính sách truy cập hợp nhất ban đầu (Quy tắc 1: API cốt lõi của Google)

Tạo cfg/uap-rules.json với Quy tắc 1 cho phép ba principalSet của dự án tiếp cận 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

Bước 4: Tạo và liên kết chính sách truy cập IAM

Tạo Chính sách truy cập IAM chung:

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

Liên kết Chính sách truy cập với 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

Xác minh rằng Liên kết chính sách đang hoạt động:

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

Kết quả mẫu:

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}

Giờ đây, dữ liệu đầu ra của Cloud APIs cơ bản của Google Cloud được uỷ quyền một cách an toàn trên cả ba dự án ở chế độ ENFORCE nghiêm ngặt.

Đến đây là kết thúc phần thiết lập uỷ quyền cổng... tiếp theo là phần Định cấu hình quyền IAM trên nhiều dự án.

6. IAM trên nhiều dự án

Định cấu hình quyền IAM trên nhiều dự án

Trong cấu trúc liên kết nhiều dự án này, Môi trường thời gian chạy của tác nhân nằm trong các dự án nhánh (PROJECT_CONCIERGE và PROJECT_SELLERS), còn Cổng tác nhân trung tâm và Sổ đăng ký tác nhân nằm trong PROJECT_GOVERNANCE.

Vì các dự án trên Google Cloud là các ranh giới bảo mật riêng biệt, nên quyền truy cập giữa các dự án phải được cấp rõ ràng trên hai lớp hoạt động:

  1. Mặt phẳng điều khiển (Thời gian triển khai): Khi triển khai vùng chứa tác nhân được định cấu hình bằng --agent-gateway-config, Tác nhân dịch vụ thời gian chạy của tác nhân (service-@gcp-sa-aiplatform.iam.gserviceaccount.com) của dự án nhánh phải đính kèm vùng chứa vào cổng trung tâm. Chúng tôi tạo một vai trò tuỳ chỉnh tối thiểu (ar_agw_cross_project_sa) cấp quyền networkservices.agentGateways.use, get và operations.get trong PROJECT_GOVERNANCE.
  2. Mặt phẳng dữ liệu (Thực thi thời gian chạy):
    • Khám phá danh mục: Danh tính của Spoke cần có roles/agentregistry.viewer trong PROJECT_GOVERNANCE để phân giải linh động các điểm cuối của tác nhân mục tiêu.
    • Lệnh gọi mục tiêu: Tác nhân Concierge cần có roles/aiplatform.user trong PROJECT_SELLERS để thực thi các truy vấn đối với công cụ suy luận của người bán.

Tạo vai trò IAM tuỳ chỉnh trong 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"

Chỉ định vai trò tuỳ chỉnh cho tác nhân dịch vụ thời gian chạy của tác nhân

# 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

Đến đây là kết thúc phần thiết lập IAM trên nhiều dự án... tiếp theo là phần Triển khai tác nhân Người bán và Người hỗ trợ.

7. Thời gian chạy của tác nhân

Triển khai tác nhân bán hàng và tác nhân hỗ trợ

Toàn bộ mã nguồn của ứng dụng đa tác nhân và tập lệnh triển khai dùng cho Lớp học lập trình này được duy trì trong một kho lưu trữ từ xa của Google Cloud trên GitHub. Các bước sau đây sẽ sao chép kho lưu trữ trên máy, sao chép các tệp cần thiết vào cấu trúc thư mục đang hoạt động, dọn dẹp các tệp tạm thời và cài đặt các phần phụ thuộc bằng uv.

Tìm nạp cấu phần phần mềm từ xa

# 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

Tạo bộ chứa thử nghiệm trung tâm dùng chung

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

Cách hoạt động của tính năng Liên kết cổng tác nhân trên nhiều dự án

Trong bước này, bạn sẽ triển khai Tác nhân người bán vào dự án nhánh (PROJECT_SELLERS) đồng thời định cấu hình các tác nhân này để định tuyến lưu lượng truy cập ra ngoài thông qua Cổng tác nhân trung tâm trong 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)

Vì Quy tắc 1 được thiết lập trước trong Chính sách truy cập hợp nhất, nên các yêu cầu khởi chạy vùng chứa đến API Google Cloud được cho phép thông qua cổng mà không bị gián đoạn.

Triển khai Tác nhân bán bánh mì kẹp thịt và pizza cho 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}

Xác thực định tuyến cổng của người bán

# 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

Triển khai Tác nhân hỗ trợ mua hàng cho 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}

Xác thực định tuyến cổng mua hàng

# 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ết quả sẽ cho thấy danh tính và dự án trong thời gian chạy của tác nhân Concierge, cũng như mối liên kết với Cổng tác nhân của dự án Quản trị.

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

Đến đây là kết thúc phần triển khai tác nhân... tiếp theo là phần Đăng ký tác nhân trong Sổ đăng ký tác nhân trung tâm.

8. Sổ đăng ký trên nhiều dự án

Đăng ký tác nhân trong Sổ đăng ký tác nhân trung tâm

Đăng ký cả 3 tác nhân trong Central Agent Registry (Sổ đăng ký tác nhân trung tâm) trong PROJECT_GOVERNANCE bằng cách sử dụng các điểm cuối mTLS theo khu vực giữa các dự án và số dự án dạng số.

Đăng ký dịch vụ dưới dạng tác nhân không phải A2A trong Sổ đăng ký tác nhân

# 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

Ghi lại mã nhận dạng trong sổ đăng ký của tác nhân cơ bản

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

Đến đây là kết thúc phần cấu hình sổ đăng ký... tiếp theo là phần Định cấu hình chính sách lưu lượng truy cập ra ngoài từ ứng dụng đến ứng dụng.

9. Chính sách về UAP

Định cấu hình chính sách lưu lượng truy cập ra ngoài từ ứng dụng đến ứng dụng trong Chính sách truy cập hợp nhất

Theo cấu trúc Từ chối theo mặc định của Agent Gateway ở chế độ BUỘC THỰC HIỆN nghiêm ngặt:

  1. Quy tắc 1 (API Google Cloud cơ sở): Cho phép vùng chứa tác nhân trên cả 3 dự án truy cập vào core-gapi-services.
  2. Quy tắc 2 (Tác nhân bán bánh mì kẹp thịt: CHO PHÉP): Cho phép thực thể Tác nhân hỗ trợ mua hàng gọi cụ thể Tác nhân bán bánh mì kẹp thịt.
  3. Tác nhân bán pizza (BỊ TỪ CHỐI theo mặc định): Cố ý bị loại trừ khỏi các quy tắc chính sách. Ở chế độ ENFORCE (failOpen: false), mọi nỗ lực của Concierge nhằm gọi Pizza Seller sẽ bị chấm dứt ngay lập tức tại ranh giới cổng bằng HTTP 403 Forbidden.

Xây dựng danh tính của nhân viên hỗ trợ

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

Cập nhật tệp kê khai bản cập nhật bằng Quy tắc 1 và 2

Để cập nhật chính sách truy cập một cách an toàn mà không làm ảnh hưởng đến các quy tắc hiện có, hãy xác định tệp kê khai hợp nhất đầy đủ chứa Quy tắc 1 (API chính của Google) và Quy tắc 2 (Tác nhân Burger Seller):

# 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

Áp dụng chính sách truy cập mới nhất

Áp dụng tệp kê khai quy tắc hợp nhất theo cách khai báo bằng --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

Xác minh thông tin chi tiết về chính sách truy cập IAM

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

Kết quả mẫu:

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

Đến đây là kết thúc phần thiết lập chính sách... tiếp theo là phần Kiểm thử và xác minh chính sách quản trị.

10. Xác minh chính sách

Kiểm thử và xác minh chính sách quản trị thông qua Cloud Logging

Trong phần này, bạn sẽ thử nghiệm các hoạt động tương tác giữa các tác nhân (A2A) trên nhiều dự án trong Sân chơi AI của Môi trường thời gian chạy tác nhân, quan sát hoạt động chặn HTTP 403 Forbidden thực tế của vành đai ở chế độ nghiêm ngặt ENFORCE, sửa đổi Chính sách truy cập hợp nhất trực tiếp và xác thực phê duyệt đơn đặt hàng ngay lập tức.

Bước 1: Mở Sân chơi AI của Agent Runtime trong PROJECT_CONCIERGE

  1. Mở Google Cloud Console.
  2. Trong thanh chọn dự án ở trên cùng, hãy chuyển sang PROJECT_CONCIERGE.
  3. Trong trình đơn điều hướng, hãy chuyển đến Nền tảng tác nhân > Tác nhân > Triển khai.
  4. Nhấp vào purchasing-concierge-adk.
  5. Chọn Playground để mở giao diện trò chuyện tương tác ở bên phải màn hình.

Bước 2: Kiểm tra đơn đặt hàng bánh mì kẹp thịt (Quy tắc 2 khớp -> 200 OK)

Trong cửa sổ trò chuyện của Playground, hãy gửi câu lệnh đặt hàng sau:

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

Nếu cần phản hồi xác nhận, hãy gửi thư trả lời sau:

Confirmed, please place the order.

Ngoài ra, hãy kiểm thử theo phương thức lập trình từ Cloud Shell/thiết bị đầu cuối:

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

Nếu cần phản hồi xác nhận, hãy dùng lệnh sau:

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ều gì xảy ra trong hậu trường:

  1. Khám phá linh động: Trong quá trình khởi động phiên, Nhân viên hỗ trợ mua hàng đã truy vấn Sổ đăng ký tác nhân trung tâm trong PROJECT_GOVERNANCE (thông qua core-gapi-services thông qua Cổng tác nhân được uỷ quyền theo Quy tắc 1) để khám phá điểm cuối mTLS theo khu vực cho burger-seller-agent.
  2. Phân giải ý định và gọi A2A: Gemini trong Tác nhân hỗ trợ mua hàng phân tích cú pháp ý định đặt món ăn và gọi Tác nhân bán bánh mì kẹp thịt thông qua một RPC gửi đi đến https://${REGION}-aiplatform.mtls.googleapis.com/.../reasoningEngines/${BURGER_ENGINE_ID}.
  3. Chặn cổng và truyền SPIFFE: Lưu lượng truy cập đi được agent_gateway_config ghi lại và chuyển đến Cổng tác nhân trung tâm trong PROJECT_GOVERNANCE, mang theo danh tính SPIFFE mã hoá của Concierge (principal://...).
  4. Đánh giá chính sách IAP phiên bản 2: Cổng tác nhân trung tâm gọi tiện ích uỷ quyền IAP (authzExtension). IAP phiên bản 2 đánh giá Quy tắc 2 trong Chính sách truy cập hợp nhất của IAM. Vì phương thức gọi khớp với ${CONCIERGE_SPIFFE_PRINCIPAL} và mục tiêu khớp với burger-seller-agent, nên IAP sẽ trả về ALLOW (granted: true).
  5. Thực thi trên nhiều dự án: Cổng tác nhân uỷ quyền yêu cầu được uỷ quyền trên nhiều dự án vào PROJECT_SELLERS, nơi Công cụ suy luận của người bán bánh mì kẹp thịt xử lý đơn đặt hàng và trả về thông tin xác nhận.

Phản hồi dự kiến:

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

Bước 3: Kiểm tra Nhật ký kiểm tra của Agent Gateway và IAP phiên bản 2 (HTTP 200/ALLOWED)

Truy vấn nhật ký yêu cầu của Agent Gateway trong 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
  )"

Nhật ký phải ghi lại lưu lượng truy cập đi bắt nguồn từ cả hai dự án nhánh (PROJECT_CONCIERGE và PROJECT_SELLERS) với các trường lưu lượng truy cập đi cho các lệnh gọi suy luận của Gemini (generateContent), dữ liệu đo từ xa của Cloud Trace (/v1/traces) và các lượt tra cứu thông tin xác thực IAM – được chặn và uỷ quyền một cách minh bạch theo Quy tắc 1 (core-gapi-services).

Truy vấn nhật ký Quyền truy cập dữ liệu kiểm tra trên đám mây của IAP phiên bản 2 để xác minh phiên bản chính sách 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
  )"

Kết quả mẫu:

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

Bước 4: Thử nghiệm đặt bánh pizza (Từ chối theo mặc định -> HTTP 403 Bị cấm ĐÃ THỰC THI)

Trong cùng cửa sổ trò chuyện của Playground, hãy gửi câu lệnh đặt bánh pizza sau:

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

Nếu cần phản hồi xác nhận, hãy gửi thư trả lời sau:

Confirmed, please place the order.

Ngoài ra, hãy kiểm thử theo phương thức lập trình từ Cloud Shell/thiết bị đầu cuối:

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

Nếu cần phản hồi xác nhận, hãy dùng lệnh sau:

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

Phản hồi dự kiến:

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.

Điều gì xảy ra trong hậu trường:

  1. Khám phá linh động: Tác nhân hỗ trợ mua hàng đã phân giải điểm cuối pizza-seller-agent từ Central Agent Registry trong quá trình khởi động.
  2. Phân giải ý định và gọi A2A: Gemini trong Tác nhân hỗ trợ mua hàng cố gắng gửi yêu cầu đặt bánh pizza đến điểm cuối của Người bán bánh pizza trong PROJECT_SELLERS.
  3. Chặn cổng: RPC gửi đi được agent_gateway_config thu thập và chuyển đến Cổng tác nhân trung tâm.
  4. Đánh giá chính sách IAP phiên bản 2 (Từ chối theo mặc định): Central Agent Gateway gọi IAP phiên bản 2. Vì không có quy tắc nào trong Chính sách truy cập hợp nhất khớp với pizza-seller-agent, nên IAP sẽ trả về DENY (granted: false).
  5. Chặn nghiêm ngặt theo ranh giới: Vì Tiện ích Authz đang ở chế độ THỰC THI (failOpen: false), nên Cổng tác nhân trung tâm sẽ ngay lập tức chấm dứt kết nối đi và trả về HTTP 403 Forbidden. Lưu lượng truy cập không bao giờ rời khỏi cổng và không bao giờ đến được PROJECT_SELLERS.

Bước 5: Kiểm tra nhật ký cổng tác nhân để tìm các yêu cầu bị chặn (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
  )"

Kết quả nhật ký mẫu bị từ chối:

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

Truy vấn nhật ký kiểm tra quyền truy cập dữ liệu của IAP phiên bản 2 để tìm quyết định từ chối:

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

Kết quả mẫu của nhật ký kiểm tra bị từ chố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

Bước 6: Cấp quyền truy cập đầu ra cho tác nhân Pizza một cách linh động

Tạo cfg/uap-rules-update-3.json mới để thêm Quy tắc 1 (API chính), Quy tắc 2 (Tác nhân bán bánh mì kẹp) và giờ là Quy tắc 3 (Tác nhân bán pizza)

# 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

Áp dụng nội dung cập nhật chính sách:

# 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

Bước 7: Truy vấn lại Pizza Agent (Thành công ngay lập tức với mã 200 OK)

Trong cửa sổ trò chuyện của Playground, hãy gửi lại câu lệnh đặt bánh pizza:

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

Nếu cần phản hồi xác nhận, hãy gửi thư trả lời sau:

Confirmed, please place the order.

Ngoài ra, hãy kiểm thử theo phương thức lập trình từ Cloud Shell/thiết bị đầu cuối:

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

Nếu cần phản hồi xác nhận, hãy dùng lệnh sau:

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

Phản hồi dự kiến:

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

Điều gì xảy ra trong hậu trường:

  1. Làm mới chính sách linh động: Việc cập nhật Chính sách truy cập hợp nhất của IAM sẽ có hiệu lực ngay lập tức trong công cụ đánh giá IAP mà không cần thời gian ngừng hoạt động và không cần triển khai lại bất kỳ vùng chứa nào.
  2. Gọi A2A: Tác nhân hỗ trợ gửi yêu cầu thông qua Cổng tác nhân trung tâm.
  3. Đánh giá chính sách IAP phiên bản 2 (Phê duyệt): IAP phiên bản 2 khớp với Quy tắc 3, xác minh danh tính của phương thức gọi và biểu thức CEL mục tiêu, đồng thời trả về ALLOW (granted: true).
  4. Thực thi trên nhiều dự án: Cổng tác nhân trung tâm uỷ quyền lưu lượng truy cập được uỷ quyền vào PROJECT_SELLERS, nơi Người bán pizza xử lý đơn đặt hàng.

Bước 8: Kiểm tra nhật ký của cổng tác nhân để tìm các yêu cầu về pizza được cấp

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

Kết quả nhật ký mẫu khi được cấp quyền:

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

Đến đây là kết thúc phần kiểm thử và xác minh... tiếp theo là phần Dọn dẹp.

11. Dọn dẹp

Để tránh bị tính phí vào tài khoản Google Cloud cho các tài nguyên được dùng trong Lớp học lập trình này, hãy thực hiện các bước chia nhỏ theo thứ tự phụ thuộc ngược nghiêm ngặt:

1. Dọn dẹp các bản triển khai Reasoning Engine

Thực thi tập lệnh cleanup_old_deployments.py đi kèm trên cả hai dự án thời gian chạy để xoá các công cụ suy luận và chờ các thao tác chạy trong thời gian dài:

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

Ngoài ra, bạn có thể liệt kê và xoá các công cụ suy luận cùng dòng:

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. Xoá dịch vụ đăng ký nhân viên hỗ trợ

# 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. Xoá mối liên kết chính sách truy cập hợp nhất và chính sách truy cập của 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. Xoá cổng nhân viên hỗ trợ và chính sách bảo mật

# 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. Xoá các liên kết IAM và vai trò tuỳ chỉnh giữa các dự án

# 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

Nếu bạn đã chỉ định roles/iam.accessPolicyAdmin và roles/resourcemanager.projectIamAdmin trong giai đoạn Thiết lập, hãy xoá các vai trò này khỏi tài khoản người dùng đang hoạt động để khôi phục đặc quyền tối thiểu:

# 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. Huỷ bỏ việc ghi nhật ký dữ liệu kiểm tra và các quy tắc ràng buộc của chính sách tổ chức

# 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. Huỷ bỏ các quy tắc ràng buộc của Chính sách tổ chức

# 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. Xoá bộ chứa thử nghiệm GCS dùng chung và cấu phần phần mềm cục bộ

# 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

Đến đây là kết thúc phần dọn dẹp... tiếp theo là phần Kết luận!

12. Kết luận

Xin chúc mừng! Bạn đã triển khai và quản lý một cấu trúc Tác nhân AI với tác nhân AI (A2A) đa dự án trên Google Cloud bằng cách sử dụng Vertex AI Agent Runtime, Central Agent Gateway, Agent Registry và Chính sách truy cập hợp nhất (UAP) của IAM.

Tóm tắt các khái niệm chính

  • Vùng biên lưu lượng truy cập ra tập trung: Định tuyến các vùng chứa thời gian chạy nhánh (PROJECT_CONCIERGE, PROJECT_SELLERS) thông qua một Cổng tác nhân trung tâm trong PROJECT_GOVERNANCE bằng agentGatewayConfig.
  • Quản trị khai báo (UAP): Thay thế các liên kết phân mảnh theo tài nguyên bằng một Chính sách truy cập IAM duy nhất, có thể kiểm tra, được đánh giá tại cổng bằng IAP phiên bản 2.
  • Danh tính mã hoá: Thực thi quyền truy cập ra ngoài với đặc quyền tối thiểu bằng cách sử dụng danh tính SPIFFE của vùng chứa (principal://...) thay vì khoá có thời hạn dài.
  • Khám phá dịch vụ linh động: Điểm cuối của tác nhân ngang hàng được phân giải trong thời gian chạy thông qua Sổ đăng ký tác nhân trung tâm, giúp loại bỏ URL và mã dự án được cố định giá trị trong mã.
  • Tính linh hoạt của chính sách thời gian chạy: Chuyển đổi pizza-seller-agent từ Từ chối theo mặc định (403 Forbidden) sang Được phép (200 OK) theo thời gian thực thông qua bản cập nhật chính sách mà không cần khởi động lại vùng chứa.

cosmopup

Cosmopup cho biết: "Các tác nhân rất tuyệt vời, chúng làm tất cả công việc liên quan đến nhiều dự án trong khi tôi tập trung vào mục tiêu chính của mình: ngủ trưa!"

Các bước tiếp theo và tài liệu