Egress Gemini Enterprise dengan Agent Gateway ke server MCP kustom pribadi menggunakan Agent Registry

1. Pengantar

Codelab ini membahas konektivitas keluar yang bersifat pribadi dan diatur untuk Gemini Enterprise menggunakan Agent Gateway dalam mode agent-to-anywhere (keluar). Anda akan mengonfigurasi aplikasi Gemini Enterprise untuk memanggil server Model Context Protocol (MCP) kustom yang dihosting di Cloud Run secara aman dengan merutekan traffic melalui Agent Gateway menggunakan antarmuka Private Service Connect (PSC) untuk terhubung ke endpoint PSC untuk Google API di jaringan VPC.

Di lingkungan perusahaan, memberikan akses jaringan langsung kepada agen otonom berisiko menyebabkan pemindahan data yang tidak sah dan eksekusi alat yang tidak diperiksa. Agent Gateway menyediakan titik penerapan zero-trust tingkat platform yang terpusat yang secara dinamis memeriksa payload alat MCP HTTP yang dapat di-streaming. Permintaan keluar diautentikasi dengan Agent Identity yang dapat diverifikasi secara kriptografis dan diotorisasi melalui Identity-Aware Proxy (IAP) menggunakan Unified Access Policies (UAP) IAM dengan aturan Common Expression Language (CEL). Hal ini memungkinkan kontrol akses terperinci atas alat dan metode MCP tertentu tanpa mengekspos workload backend ke internet publik.

Yang Anda bangun

  • Agent Gateway beroperasi dalam mode egress (agent-to-anywhere) dengan verifikasi endpoint Agent Registry
  • Layanan Cloud Run yang menghosting server MCP HTTP streamable pribadi (--ingress=internal) yang terdaftar dengan spesifikasi alatnya di Agent Registry
  • Ekstensi otorisasi Identity-Aware Proxy (IAP) untuk Agent Gateway
  • Kebijakan Akses Terpadu (UAP) IAM dengan kondisi CEL untuk otorisasi alat MCP
  • Aplikasi Gemini Enterprise terikat ke Agent Gateway dan terhubung ke penyimpanan data server MCP kustom yang diimpor dari Agent Registry
  • Resource jaringan VPC, zona DNS Cloud, dan endpoint PSC untuk Google API
  • Lampiran jaringan PSC untuk traffic keluar VPC pribadi Agent Gateway
  • Aturan kebijakan Cloud Next Generation Firewall (NGFW) untuk mengamankan traffic VPC

figure1

Gambar 1. Arsitektur codelab

Yang Anda pelajari

  • Cara men-deploy server MCP HTTP pribadi yang dapat di-streaming dari sumber di Cloud Run dan mendaftarkan endpoint serta skema alatnya di Agent Registry
  • Cara mengonfigurasi Agent Gateway dengan entri registry yang sesuai dan merutekan panggilan alat aplikasi Gemini Enterprise melalui gateway
  • Cara membuat traffic keluar VPC pribadi menggunakan lampiran dan antarmuka jaringan PSC
  • Cara mendelegasikan otorisasi Agent Gateway ke Identity-Aware Proxy (IAP)
  • Cara membuat dan mengikat Kebijakan Akses Terpadu (UAP) IAM menggunakan atribut CEL destination.agent_registry.* dan destination.is_registered untuk membatasi eksekusi alat MCP
  • Cara memvalidasi penegakan kebijakan dan keluar jaringan menggunakan Cloud Logging

Yang Anda perlukan

  • Project Google Cloud yang mengaktifkan penagihan
  • Lisensi Gemini Enterprise yang aktif atau uji coba 30 hari
  • Izin IAM untuk menyediakan layanan jaringan, Gemini Enterprise, dan resource Agent Platform
  • Shell yang kompatibel dengan POSIX (bash atau zsh) dengan Google Cloud CLI (gcloud), curl, dan jq yang diinstal

Bagian pengantar ini telah selesai... selanjutnya kita akan membahas bagian Konsep.

2. Konsep

Urutan deployment

Codelab ini men-deploy infrastruktur terlebih dahulu sehingga jalur jaringan pribadi dan kontrol tata kelola dapat beroperasi sebelum mendaftarkan dan menghubungkan alat MCP dengan Gemini Enterprise:

  1. Infrastruktur jaringan: Sediakan subnet VPC, endpoint PSC, lampiran jaringan PSC, aturan kebijakan Cloud NGFW, dan zona Cloud DNS pribadi.
  2. Agent Gateway: Deploy Agent Gateway dalam mode egress dengan integrasi Agent Registry (registries) dan egress VPC pribadi (networkAttachment).
  3. Kebijakan otorisasi: Konfigurasi ekstensi otorisasi IAP, kebijakan Authz Gateway, dan Kebijakan Akses Terpadu (UAP) IAM menggunakan kondisi CEL destination.is_registered dan destination.agent_registry.*.
  4. Men-deploy & mendaftarkan server MCP: Deploy server MCP matematika dari sumber ke Cloud Run (--ingress=internal) dan daftarkan spesifikasi layanan dan alat (add dan subtract) di Agent Registry.
  5. Aplikasi Gemini Enterprise: Buat aplikasi Gemini Enterprise (Engine), konfigurasi setelan identitas dan kemampuan observasi, serta ikat keluar keluar ke Agent Gateway (agentGatewaySetting).
  6. Mengimpor konektor data MCP kustom: Buat dan aktifkan konektor data REGISTRY_MCP (:setUpDataConnector) untuk menautkan penyimpanan data pendukung server MCP terdaftar ke aplikasi Gemini Enterprise.
  7. Validasi: Uji eksekusi alat yang diizinkan dan ditolak dalam chat serta verifikasi penegakan kebijakan di seluruh log Agent Gateway, DNS, Firewall, dan Cloud Run.

Egress Gemini Enterprise

Gemini Enterprise merutekan permintaan alat server MCP kustom ke Agent Gateway jika agentGatewaySetting di Engine dan use_agent_gateway_egress: true di DataConnector dikonfigurasi.

figure2

Gambar 2. Arsitektur keluar Gemini Enterprise

Aplikasi Gemini Enterprise mengatur perutean alat di empat area utama:

  1. Widget (default_search_widget_config):
    • Menyajikan antarmuka klien web. Widget menerima perintah dari pengguna dan memulai sesi chat dengan mesin yang mendasarinya.
  2. Asisten Inti (assistants/default_assistant/agents/default/core_assistant):
    • Agen penalaran percakapan root dalam mesin. Saat mengevaluasi kueri pengguna, Asisten Inti menentukan apakah penghitungan aritmetika diperlukan, memeriksa alat yang tersedia, dan mendelegasikan eksekusi ke sub-agen Agent Gateway yang disintesis.
  3. Penyimpanan Data dan Konektor Data:
    • DataStore: Disediakan di dalam Collection khusus saat :setUpDataConnector berjalan, yang menautkan (dataStoreIds) skema alat Agent Registry yang diimpor (add, subtract), jenis argumen, dan petunjuk agen ke Engine Gemini Enterprise.
    • DataConnector: Mengelola koneksi tindakan REGISTRY_MCP (createBapConnection: true) ke server MCP jarak jauh (instance_uri), menyelesaikan resource server MCP Agent Registry (registry_mcp_server_name), dan mengaktifkan keluar Agent Gateway (use_agent_gateway_egress: true).
  4. Agent Identity, Agent Registry, dan Agent Gateway:
    • Saat mengirimkan panggilan alat keluar, Konektor Data akan merutekan traffic ke gateway yang ditentukan dalam agentGatewaySetting. Asisten Inti membuat token identitas SPIFFE yang menyatakan identitasnya: principal://agents.global.org-.../agents/default/core_assistant.
    • Agent Gateway terintegrasi dengan Agent Registry menggunakan kolom registries untuk menyelesaikan endpoint tujuan dan skema alat terdaftar secara dinamis. Layanan ini mengisi atribut destination.is_registered dan destination.agent_registry.* serta meneruskannya ke IAP v2 untuk dievaluasi terhadap aturan CEL Kebijakan Akses Terpadu (UAP) IAM sebelum mengizinkan transit ke jaringan VPC.

Konektivitas VPC gateway

Agent Gateway memungkinkan konektivitas jaringan VPC pribadi menggunakan dua kolom YAML:

  • networkConfig.egress.networkAttachment: Mengarahkan traffic IP pribadi agar dirutekan melalui lampiran jaringan PSC ke dalam jaringan VPC.
  • dnsPeeringConfig.domains: Melakukan peering resolusi DNS dengan zona DNS Cloud DNS jaringan VPC sehingga nama host target (*.run.app) diselesaikan ke alamat IP endpoint PSC pribadi yang ditentukan di jaringan VPC.

Batasan & persyaratan

  • Khusus StreamableHTTP: Transport Server-Sent Events (SSE) lama tidak didukung. Server MCP harus menggunakan StreamableHTTP.
  • Public CA TLS diperlukan: Endpoint MCP harus menggunakan sertifikat TLS yang ditandatangani oleh Public CA tepercaya publik, meskipun saat diakses secara pribadi melalui PSC.
  • Penggantian kebijakan org: Anda harus secara eksplisit mengganti kebijakan organisasi untuk penyimpanan data MCP Kustom sebelum mendaftarkan penyimpanan data.

Ini mengakhiri bagian konsep... selanjutnya ke bagian Penyiapan.

3. Penyiapan

Peran IAM yang diperlukan

Peran berikut diperlukan untuk menyelesaikan Codelab:

Domain

Peran IAM yang diperlukan

Project & IAM

roles/orgpolicy.policyAdmin
roles/resourcemanager.projectIamAdmin
roles/iam.accessPolicyAdmin
roles/serviceusage.serviceUsageAdmin
roles/iam.serviceAccountUser

Networking & Gateway

roles/networkservices.admin
roles/networksecurity.admin
roles/serviceextensions.admin
roles/compute.networkAdmin
roles/dns.admin

Gemini Enterprise & Registry

roles/discoveryengine.admin
roles/agentregistry.admin (atau roles/apphub.admin)

Beban Kerja & Build

roles/run.admin
roles/cloudbuild.builds.editor
roles/artifactregistry.writer
roles/storage.admin

Kemampuan observasi

roles/logging.viewer
roles/logging.logWriter

Atau gunakan peran dasar yang luas seperti roles/owner yang dikombinasikan dengan roles/orgpolicy.policyAdmin (karena roles/owner saja tidak dapat mengubah kebijakan organisasi).

Mengakses project Anda

Codelab ini menggunakan satu project Google Cloud. Langkah-langkah konfigurasi menggunakan perintah CLI gcloud dan shell Linux.

Mulailah dengan mengakses command line project Google Cloud Anda:

Menetapkan Project ID

gcloud config set project SET_YOUR_PROJECT_ID_HERE

Mengautentikasi sesi

# login to gcloud cli
gcloud auth login
# login for gcloud api
gcloud auth application-default login

Menetapkan variabel lingkungan shell

# set custom var for slug (eg, "foo") and region preference
export SLUG="foo"
export REGION="us-central1"

echo ${SLUG}
echo ${REGION}
# create project vars (automatic)
export PROJ_ID=$(gcloud config list --format="value(core.project)")
export PROJ_NO=$(gcloud projects describe ${PROJ_ID} --format="value(projectNumber)")
export ORG_ID=$(gcloud projects get-ancestors ${PROJ_ID} --format="value(id)" | tail -n 1)
export USER_IDENTITY=$(gcloud config get-value account)

echo ${PROJ_ID}
echo ${PROJ_NO}
echo ${ORG_ID}
echo ${USER_IDENTITY}
# create resource vars for agent platform (automatic)
export AGW_NAME="agw-${SLUG}-${REGION}-ata"
export AGW_URI="projects/${PROJ_ID}/locations/${REGION}/agentGateways/${AGW_NAME}"
export UAP_POLICY_NAME="uap-policy-${SLUG}"
export UAP_BINDING_NAME="uap-binding-${SLUG}"
export MCP_NAME="math-wizard"
export MCP_URL="https://${MCP_NAME}-${PROJ_NO}.${REGION}.run.app/mcp"

echo ${AGW_NAME}
echo ${AGW_URI}
echo ${UAP_POLICY_NAME}
echo ${UAP_BINDING_NAME}
echo ${MCP_NAME}
echo ${MCP_URL}
# create resource vars for gemini enterprise (automatic)
export GE_APP_DISPLAY_NAME="Codelab app"
export GE_APP_ORG_NAME="${SLUG}, Inc."
export GE_LOCATION="global"
export GE_APP_NAME="app-${SLUG}-${GE_LOCATION}"
export GE_APP_INIT="${GE_APP_NAME}_$(date +%s)"

echo ${GE_APP_DISPLAY_NAME}
echo ${GE_APP_ORG_NAME}
echo ${GE_LOCATION}
echo ${GE_APP_NAME}
echo ${GE_APP_INIT}

Menetapkan domain tepercaya identitas agen

Pernyataan if-then-else memeriksa apakah project termasuk dalam organisasi untuk menetapkan domain tepercaya yang benar bagi identitas agen utama.

# set var for trust domain
if [[ -n "${ORG_ID}" ]]; then
  export TRUST_DOMAIN="agents.global.org-${ORG_ID}.system.id.goog"
else
  export TRUST_DOMAIN="agents.global.proj-${PROJ_NO}.system.id.goog"
fi

echo "trust domain: ${TRUST_DOMAIN}"

Menetapkan project penagihan dan kuota

# set cli quota project
gcloud config set billing/quota_project ${PROJ_ID}
# set api quota project
gcloud auth application-default set-quota-project ${PROJ_ID}

Buat direktori lokal untuk file konfigurasi

# create config folder
mkdir -p cfg

Jika menjalankan penginstalan Google Cloud SDK yang dikelola sendiri (yaitu, di luar Cloud Shell), update komponen ke versi terbaru.

# update gcloud cli
gcloud components update

Mengaktifkan layanan API

# enable google apis (part 1)
gcloud services enable \
  agentregistry.googleapis.com \
  agentidentity.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 \
  iap.googleapis.com \
  logging.googleapis.com \
  modelarmor.googleapis.com \
  monitoring.googleapis.com \
  networksecurity.googleapis.com \
  networkservices.googleapis.com \
  notebooks.googleapis.com \
  observability.googleapis.com
# enable google apis (part 2)
gcloud services enable \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com \
  discoveryengine.googleapis.com \
  dns.googleapis.com \
  orgpolicy.googleapis.com \
  run.googleapis.com \
  saasservicemgmt.googleapis.com \
  securitycenter.googleapis.com \
  storage.googleapis.com \
  telemetry.googleapis.com \
  texttospeech.googleapis.com

Organization Policies

Batasan kebijakan organisasi terkelola Google Cloud default membatasi fitur yang digunakan dalam Codelab ini:

Ganti batasan kebijakan organisasi yang diwarisi di tingkat project dengan menetapkan enforce: false secara eksplisit.

Menonaktifkan batasan MCP kustom

# disable data connector constraint (allow custom mcp servers)
gcloud org-policies set-policy /dev/stdin << EOF
name: projects/${PROJ_NO}/policies/discoveryengine.managed.disableCustomMcpServerConnector
spec:
  rules:
  - enforce: false
EOF
# verify org policy constraint on project
gcloud org-policies describe discoveryengine.managed.disableCustomMcpServerConnector \
  --project=${PROJ_ID} --effective

Menonaktifkan batasan kebijakan akses

# disable iam v3 constraint (allow v3 access policies)
gcloud org-policies set-policy /dev/stdin << EOF
name: projects/${PROJ_NO}/policies/iam.managed.disableAccessPolicyBinding
spec:
  rules:
  - enforce: false
EOF
# verify org policy constraint on project
gcloud org-policies describe iam.managed.disableAccessPolicyBinding \
  --project=${PROJ_ID} --effective

Memeriksa dan menonaktifkan batasan konektor data bersyarat

Secara default, discoveryengine.managed.allowedEgressFqdns dan discoveryengine.managed.allowedDataSources hanya memblokir pembuatan konektor jika project Anda berada dalam perimeter Kontrol Layanan VPC (VPC SC) atau jika administrator organisasi telah menambahkan project Anda ke enforcedProjects.

Pertama, periksa kebijakan yang berlaku di project Anda:

# check effective egress fqdn constraint on project
gcloud org-policies describe discoveryengine.managed.allowedEgressFqdns \
  --project=${PROJ_ID} --effective
# check effective data source constraint on project
gcloud org-policies describe discoveryengine.managed.allowedDataSources \
  --project=${PROJ_ID} --effective

~~IF~~ batasan ini diterapkan, untuk memastikan batasan tersebut tidak memblokir penyiapan konektor custom_mcp di organisasi yang dibatasi kebijakan atau SC VPC, tetapkan enforce: false pada kedua kebijakan untuk project Anda:

# disable egress fqdn constraint on project
gcloud org-policies set-policy /dev/stdin << EOF
name: projects/${PROJ_NO}/policies/discoveryengine.managed.allowedEgressFqdns
spec:
  rules:
  - enforce: false
EOF
# disable allowed data sources constraint on project
gcloud org-policies set-policy /dev/stdin << EOF
name: projects/${PROJ_NO}/policies/discoveryengine.managed.allowedDataSources
spec:
  rules:
  - enforce: false
EOF
# verify both constraints are disabled on project
gcloud org-policies describe discoveryengine.managed.allowedEgressFqdns \
  --project=${PROJ_ID} --effective

gcloud org-policies describe discoveryengine.managed.allowedDataSources \
  --project=${PROJ_ID} --effective

Izin IAM

Berikan peran IAM yang diperlukan ke akun pengguna Anda dan akun layanan default Compute Engine yang digunakan oleh Cloud Build:

  • Akun pengguna (${USER_IDENTITY}):
    • Memerlukan izin untuk men-deploy dan memanggil layanan Cloud Run (roles/run.admin, roles/run.invoker, roles/iam.serviceAccountUser), membuat image container (roles/cloudbuild.builds.editor), mengelola Gemini Enterprise (roles/discoveryengine.admin), dan membuat Kebijakan Akses Terpadu (roles/iam.accessPolicyAdmin).
  • Akun layanan default Compute Engine(${PROJ_NO}-compute@developer.gserviceaccount.com):
    • Digunakan oleh Cloud Build untuk menyiapkan kode sumber di Cloud Storage (roles/storage.admin), mengirimkan image ke Artifact Registry (roles/artifactregistry.writer), dan menulis log build (roles/logging.logWriter).

Jalankan perintah berikut untuk menetapkan binding peran:

# grant roles to user account
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="user:${USER_IDENTITY}" \
  --role="roles/run.admin"

gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="user:${USER_IDENTITY}" \
  --role="roles/iam.serviceAccountUser"

gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="user:${USER_IDENTITY}" \
  --role="roles/run.invoker"

gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="user:${USER_IDENTITY}" \
  --role="roles/discoveryengine.admin"

gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="user:${USER_IDENTITY}" \
  --role="roles/iam.accessPolicyAdmin"

gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="user:${USER_IDENTITY}" \
  --role="roles/cloudbuild.builds.editor"
# grant roles to default compute (cloud build) service account
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="serviceAccount:${PROJ_NO}-compute@developer.gserviceaccount.com" \
  --role="roles/storage.admin"

gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="serviceAccount:${PROJ_NO}-compute@developer.gserviceaccount.com" \
  --role="roles/artifactregistry.writer"

gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="serviceAccount:${PROJ_NO}-compute@developer.gserviceaccount.com" \
  --role="roles/logging.logWriter"

Memverifikasi izin IAM

Periksa enam binding peran (6) di akun pengguna.

# show iam policy on project for user account
gcloud projects get-iam-policy ${PROJ_ID} \
  --flatten="bindings[].members" \
  --filter="bindings.members:${USER_IDENTITY}" \
  --format="table(bindings.role:label=ROLE, bindings.members:label=PRINCIPAL_IDENTITY)"

Periksa tiga (3) binding peran di akun layanan komputasi default.

# show iam policy on project for default compute service account
gcloud projects get-iam-policy ${PROJ_ID} \
  --flatten="bindings[].members" \
  --filter="bindings.members:${PROJ_NO}-compute@developer.gserviceaccount.com" \
  --format="table(bindings.role:label=ROLE, bindings.members:label=PRINCIPAL_IDENTITY)"

Memverifikasi binding agen layanan (sebagai tindakan pencegahan)

Di project baru, Google Cloud otomatis menyediakan agen layanan Agent Gateway dan memberinya roles/agentgateway.serviceAgent saat networkservices.googleapis.com diaktifkan untuk pertama kalinya. Jika Anda menggunakan kembali project yang ada yang pembersihan sebelumnya mungkin telah menghapus binding agen layanan default, jalankan perintah berikut sebagai tindakan antisipasi untuk memastikan binding identitas dan peran tetap utuh:

# ensure network services service account has been created
gcloud beta services identity create \
  --service=networkservices.googleapis.com \
  --project="${PROJ_ID}"

# ensure network services service account has service agent roles applied
gcloud projects add-iam-policy-binding "${PROJ_ID}" \
  --member="serviceAccount:service-${PROJ_NO}@gcp-sa-agentgateway.iam.gserviceaccount.com" \
  --role="roles/agentgateway.serviceAgent"

Ini mengakhiri bagian penyiapan... selanjutnya ke bagian Network.

4. Jaringan

Di bagian ini, Anda akan men-deploy jaringan VPC menggunakan mode khusus dengan subnet /28 khusus (192.168.10.0/28) yang mendukung lampiran jaringan PSC untuk keluar dari jaringan Agent Gateway ke jaringan VPC.

Endpoint PSC untuk Google API di-deploy menggunakan satu /32alamat IPv4 internal global (172.16.20.20) untuk mendukung akses internal pribadi ke Google API dan layanan Google. Dalam Codelab ini, Agent Gateway menargetkan Cloud Run menggunakan endpoint PSC dengan me-resolve domain run.app. melalui peering Cloud DNS.

Membuat jaringan

Buat jaringan VPC global.

# create vpc network
gcloud compute networks create vnet-${SLUG} --subnet-mode=custom

Buat subnet untuk lampiran jaringan PSC Agent Gateway:

# create subnet for agent gateway psc na
gcloud compute networks subnets create subnet-${REGION}-agw \
  --network=vnet-${SLUG} \
  --range=192.168.10.0/28 \
  --region=${REGION} \
  --enable-private-ip-google-access

Membuat aturan firewall

Buat kebijakan firewall untuk mengizinkan semua traffic keluar dengan pengelogan diaktifkan. Hal ini akan digunakan untuk memantau traffic keluar dari Agent Gateway ke jaringan VPC. Cloud NGFW mendukung tingkatan Essentials dan Standard untuk keamanan jaringan dan pemantauan traffic.

# create fw policy
gcloud compute network-firewall-policies create fw-policy-${SLUG} --global
# create fw policy rule
gcloud compute network-firewall-policies rules create 1001 \
  --description="allow all out and log" \
  --firewall-policy=fw-policy-${SLUG} \
  --global-firewall-policy \
  --action=allow \
  --direction=EGRESS \
  --layer4-configs=all \
  --dest-ip-ranges=0.0.0.0/0 \
  --enable-logging
# bind fw policy to network
gcloud compute network-firewall-policies associations create \
  --name=fw-policy-bind-${SLUG} \
  --firewall-policy=fw-policy-${SLUG} \
  --network=vnet-${SLUG} \
  --global-firewall-policy

Membuat lampiran jaringan PSC

Buat lampiran jaringan Private Service Connect (PSC) yang dikonfigurasi untuk menerima koneksi secara otomatis dari Agent Gateway. Lampiran jaringan membuat sisi koneksi jaringan VPC konsumen untuk ditautkan secara aman dengan sisi produsen Agent Gateway untuk traffic keluar. Untuk mengetahui informasi tambahan tentang persyaratan subnet dan spesifikasi rentang IP, lihat Mengonfigurasi konektivitas VPC.

# create psc network attachment
gcloud compute network-attachments create psc-na-${REGION}-agw \
  --region=${REGION} \
  --subnets=subnet-${REGION}-agw \
  --connection-preference=ACCEPT_AUTOMATIC

Memverifikasi lampiran jaringan PSC

# show psc network attachment details
gcloud compute network-attachments describe psc-na-${REGION}-agw --region=${REGION}

Ambil URI resource lampiran jaringan PSC dan simpan di variabel lingkungan PSC_NA_URI. URI ini akan dirujuk dalam konfigurasi Agent Gateway (networkConfig.egress.networkAttachment) untuk menyediakan Antarmuka PSC untuk traffic keluar jaringan ke jaringan VPC:

# fetch psc network attachment uri
export PSC_NA_URI=$(gcloud compute network-attachments describe psc-na-${REGION}-agw \
  --region=${REGION} \
  --format="value(selfLink.scope(v1))")
echo ${PSC_NA_URI}

Membuat endpoint PSC

Endpoint Private Service Connect (PSC) untuk Google API digunakan oleh Agent Gateway untuk membuat konektivitas pribadi ke server MCP Cloud Run melalui jalur jaringan internal tanpa mengekspos traffic ke internet publik. Panggilan alat keluar yang keluar dari Agent Gateway ke jaringan VPC akan me-resolve URL layanan Cloud Run target (*.run.app) ke alamat IP endpoint pribadi ini.

Cadangkan alamat IPv4 internal global untuk endpoint PSC. Alamat IP yang dipilih harus berupa alamat /32 yang tidak tumpang-tindih dengan subnet yang ada di jaringan VPC Anda:

# set env var for psc ep ip address
export PSC_EP_IP="172.16.20.20"
echo ${PSC_EP_IP}
# reserve internal global ipv4 address
gcloud compute addresses create ip-psc2gapis \
  --global \
  --purpose=PRIVATE_SERVICE_CONNECT \
  --addresses=${PSC_EP_IP} \
  --network=vnet-${SLUG}

Buat endpoint PSC untuk Google API menggunakan paket all-apis, yang mencakup Cloud Run (run.app).

# create psc endpoint for google apis
gcloud compute forwarding-rules create psc2gapis \
  --global \
  --network=vnet-${SLUG} \
  --address=ip-psc2gapis \
  --target-google-apis-bundle=all-apis

Verifikasi endpoint PSC

# show psc endpoint details
gcloud compute forwarding-rules describe psc2gapis --global

Buat zona dan data DNS

Cloud DNS digunakan untuk memungkinkan Agent Gateway berkomunikasi secara pribadi dengan server MCP yang dihosting di Cloud Run. Saat mengevaluasi permintaan alat keluar yang menargetkan Cloud Run, Agent Gateway menggunakan peering DNS (dnsPeeringConfig.domains) untuk menyelesaikan kueri DNS untuk *.run.app menggunakan zona Cloud DNS pribadi yang terkait dengan jaringan VPC Anda. Data DNS pribadi menampilkan kueri dengan alamat IP endpoint PSC internal (172.16.20.20), sehingga permintaan alat MCP dapat dirutekan melalui jalur jaringan pribadi.

Buat zona terkelola Cloud DNS pribadi untuk domain run.app.:

# create private dns zone
gcloud dns managed-zones create priv-zone-run \
  --description="private zone for run.app" \
  --dns-name="run.app." \
  --visibility=private \
  --networks=vnet-${SLUG}

Buat data DNS karakter pengganti A untuk *.run.app. yang mengarah ke alamat IP endpoint PSC:

# create dns record
gcloud dns record-sets create "*.run.app." \
  --zone=priv-zone-run \
  --type=A \
  --ttl=300 \
  --rrdatas=${PSC_EP_IP}

Buat kebijakan Cloud DNS untuk mengaktifkan logging kueri DNS. Logging DNS mencatat permintaan resolusi domain yang berasal dari Agent Gateway dalam jaringan VPC Anda, sehingga memberikan kemampuan audit dan memungkinkan Anda memverifikasi bahwa permintaan alat *.run.app di-resolve dengan benar ke endpoint PSC internal:

# create dns policy (logging)
gcloud dns policies create dns-policy-${SLUG} \
  --description="dns logging for vnet-${SLUG}" \
  --networks=vnet-${SLUG} \
  --enable-logging

Bagian jaringan ini telah selesai... selanjutnya ke bagian Agent Gateway.

5. Agent Gateway

Agent Gateway menentukan registries untuk instance Agent Registry bersama dengan kolom networkConfig yang mengonfigurasi setelan peering DNS dan network attachment PSC untuk konektivitas VPC pribadi:

  • registries: Mengaitkan gateway dengan hingga dua instance Agent Registry: satu regional (../locations/${REGION}) dan satu global (../locations/global). Tindakan ini mengintegrasikan Agent Gateway dengan Agent Registry untuk menyelesaikan deployment regional (seperti server MCP Cloud Run di ${REGION}) dan resource global (seperti agen Gemini Enterprise dan endpoint global) untuk penerapan kebijakan IAP v2 yang terperinci. Entri regional lebih diprioritaskan daripada entri global saat menyelesaikan URL tujuan.
  • networkAttachment: Menunjuk ke lampiran jaringan PSC (psc-na-${REGION}-agw), yang menghubungkan Agent Gateway ke jaringan VPC Anda untuk keluar pribadi.
  • dnsPeeringConfig.domains: Mengonfigurasi run.app. sehingga kueri DNS yang berasal dari Agent Gateway untuk layanan Cloud Run menggunakan peering DNS untuk me-resolve nama host ke alamat IP endpoint PSC Google API pribadi (172.16.20.20) yang dikonfigurasi di zona pribadi Cloud DNS Anda.

Men-deploy Agent Gateway

Buat dan impor file konfigurasi Agent Gateway.

# create agent gateway config file
cat > cfg/${AGW_NAME}-networkConfig.yaml << EOF
name: ${AGW_NAME}
protocols:
  - MCP
googleManaged:
  governedAccessPath: AGENT_TO_ANYWHERE
registries:
  - "//agentregistry.googleapis.com/projects/${PROJ_ID}/locations/${REGION}"
networkConfig:
  egress:
    networkAttachment: ${PSC_NA_URI}
  dnsPeeringConfig:
    domains:
      - run.app.
    targetProject: ${PROJ_ID}
    targetNetwork: projects/${PROJ_ID}/global/networks/vnet-${SLUG}
EOF
# import agent gateway config file (create gateway)
gcloud network-services agent-gateways import ${AGW_NAME} \
  --source="cfg/${AGW_NAME}-networkConfig.yaml" \
  --location=${REGION}

Memverifikasi deployment Agent Gateway

Konfirmasi Agent Registry dan konfigurasi jaringan:

# show agent gateway registries and network config
gcloud network-services agent-gateways describe ${AGW_NAME} \
  --location=${REGION} \
  --format="yaml(registries,networkConfig)"

Output yang diharapkan:

networkConfig:
  dnsPeeringConfig:
    domains:
    - run.app.
    targetNetwork: projects/${PROJ_ID}/global/networks/vnet-${SLUG}
    targetProject: ${PROJ_ID}
  egress:
    networkAttachment: projects/${PROJ_ID}/regions/${REGION}/networkAttachments/psc-na-${REGION}-agw
registries:
- //agentregistry.googleapis.com/projects/${PROJ_ID}/locations/${REGION}

Pastikan output menampilkan detail konfigurasi yang diperlukan:

  • registries: Mencantumkan URI Agent Registry regional (${REGION}) yang terkait dengan gateway.
  • egress.networkAttachment: Menentukan URI lampiran jaringan PSC untuk keluar VPC.
  • dnsPeeringConfig.domains: Berisi run.app. yang mengarah ke targetNetwork untuk resolusi domain pribadi.

Periksa lampiran jaringan PSC untuk mengonfirmasi koneksi gateway:

# show psc network attachment details
gcloud compute network-attachments describe psc-na-${REGION}-agw \
  --region=${REGION} \
  --format="yaml(connectionEndpoints)"

Periksa apakah ada endpoint koneksi yang diterima:

connectionEndpoints:
- ipAddress: 192.168.10.2
  projectIdOrNum: '<AGW_TENANT_PROJ_NO>'
  status: ACCEPTED
  subnetwork: https://www.googleapis.com/compute/v1/projects/${PROJ_ID}/regions/${REGION}/subnetworks/subnet-${REGION}-agw

Mendelegasikan otorisasi

Agent Gateway mengamankan dan mengatur traffic alat keluar menggunakan Kebijakan Otorisasi (networksecurity.authzPolicies) yang terintegrasi dengan Kebijakan Akses Terpadu (UAP) Identity-Aware Proxy (IAP).

Meskipun Agent Gateway mendukung aturan ALLOW dan DENY inline dasar, lingkungan perusahaan memerlukan tata kelola terpusat yang berfokus pada identitas. Dengan Kebijakan Akses Terpadu IAM (atau Kebijakan Akses), Anda dapat mengelola aturan akses keluar menggunakan kebijakan akses IAM v3 standar.

figure3

Gambar 3. Arsitektur otorisasi

Alur otorisasi menghubungkan tiga komponen:

  1. Kebijakan Otorisasi Gateway (authzPolicy):
    • Resource regional yang menargetkan Agent Gateway.
    • Dikonfigurasi dengan policyProfile: REQUEST_AUTHZ dan action: CUSTOM untuk merutekan semua pemeriksaan otorisasi keluar ke Ekstensi Authz IAP.
  2. Ekstensi Layanan IAP (authzExtension):
    • Resource regional yang mendelegasikan otorisasi permintaan ke Identity-Aware Proxy (iap.googleapis.com).
    • Mengevaluasi kebijakan dalam mode ENFORCE menggunakan versi kebijakan V2.
  3. Kebijakan dan Binding Akses Terpadu IAM (accessPolicy & policyBinding):
    • Resource IAM v3 global yang berisi aturan akses terperinci.
    • Mengautentikasi identitas utama SPIFFE dari agen panggilan, memverifikasi izin iap.googleapis.com/resources.egressViaIAP universal, dan mengevaluasi kondisi Common Expression Language (CEL) terhadap atribut tujuan.

Men-deploy ekstensi otorisasi

Buat konfigurasi ekstensi otorisasi service-extensions yang mendelegasikan keputusan otorisasi ke layanan IAP:

# create authz extension config file
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
# import iap authz extension (create 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}

Memverifikasi ekstensi otorisasi

Periksa apakah ekstensi otorisasi aktif:

# list authz extensions
gcloud service-extensions authz-extensions list \
  --location=${REGION} \
  --format="table(
    name.basename():label=NAME,
    createTime.date(tz=LOCAL):label=CREATED,
    updateTime.date(tz=LOCAL):label=MODIFIED,
    service:label=SERVICE,
    metadata:label=METADATA,
    timeout:label=TIMEOUT
  )"

Men-deploy kebijakan otorisasi

Buat konfigurasi kebijakan otorisasi network-security yang menargetkan Agent Gateway dan mendelegasikan verifikasi permintaan ke ekstensi otorisasi untuk IAP:

# create authz policy config file
cat > cfg/${AGW_NAME}-authz-policy-iap.yaml << EOF
name: ${AGW_NAME}-authz-policy-iap
target:
  resources:
    - "projects/${PROJ_ID}/locations/${REGION}/agentGateways/${AGW_NAME}"
policyProfile: REQUEST_AUTHZ
action: CUSTOM
customProvider:
  authzExtension:
    resources:
      - "projects/${PROJ_ID}/locations/${REGION}/authzExtensions/${AGW_NAME}-svc-ext-authz-iap"
EOF
# import authz policy config file (create authz policy)
gcloud network-security authz-policies import ${AGW_NAME}-authz-policy-iap \
  --source=cfg/${AGW_NAME}-authz-policy-iap.yaml \
  --location=${REGION}

Memverifikasi kebijakan otorisasi

Periksa apakah kebijakan otorisasi aktif:

# list authz policies
gcloud network-security authz-policies list \
  --location=${REGION} \
  --format="table(
    name.basename():label=NAME,
    action:label=ACTION,
    customProvider.list().sub('\W.*', ''):label=CUSTOM_PROVIDER_TYPE,
    policyProfile:label=POLICY_PROFILE,
    customProvider.authzExtension.resources[0].basename():label=CUSTOM_PROVIDER_RESOURCE
  )"

Membuat kebijakan akses IAM

Agent Gateway kini mendelegasikan pemeriksaan otorisasi ke IAP dan menyelesaikan metadata tujuan dari Agent Registry. Selanjutnya, tentukan aturan Kebijakan Akses Terpadu IAM untuk mengatur eksekusi alat keluar.

IAP mengevaluasi ekspresi atribut CEL terhadap atribut tujuan Agent Registry berikut:

  • Status terdaftar (destination.is_registered):
    • Boolean (true/false) yang menunjukkan apakah tujuan dicatat dalam Agent Registry.
  • Nama server MCP (destination.agent_registry.mcp_server.name):
    • Nama resource server MCP kanonis yang terdaftar di Agent Registry.
  • Metode MCP (destination.agent_registry.mcp_server.method):
    • Metode MCP yang dipanggil (misalnya, tools/call, tools/list, initialize).
  • Nama alat (destination.agent_registry.mcp_server.tool.name):
    • Nama alat tertentu yang dipanggil (misalnya, subtract atau add), yang memungkinkan otorisasi tingkat alat yang terperinci di server MCP terdaftar.

Menentukan aturan kebijakan akses IAM

Manifes aturan kebijakan IAM menentukan:

  • Principal: Identitas principal SPIFFE yang merepresentasikan agen asisten inti Gemini Enterprise.
  • Izin: Izin iap.googleapis.com/resources.egressViaIAP universal yang diperlukan untuk semua traffic keluar yang diatur oleh IAP.
  • Kondisi: Ekspresi CEL (destination.is_registered == true) yang memastikan agen hanya dapat memanggil endpoint yang tercatat dalam Agent Registry.

Buat file manifes aturan kebijakan:

# create access policy rule file
cat > cfg/${UAP_POLICY_NAME}-rules.json << EOF
[
  {
    "description": "allow ge assistant to any registered service",
    "effect": "ALLOW",
    "principals": [
      "principal://${TRUST_DOMAIN}/resources/discoveryengine/projects/${PROJ_NO}/locations/global/engines/${GE_APP_INIT}/assistants/default_assistant/agents/default/core_assistant"
    ],
    "operation": {
      "permissions": [
        "iap.googleapis.com/resources.egressViaIAP"
      ]
    },
    "conditions": {
      "iap.googleapis.com": {
        "expression": \
        "destination.is_registered == true"
      }
    }
  }
]
EOF

Men-deploy kebijakan akses IAM

Buat kebijakan akses IAM global menggunakan aturan yang ditentukan dalam file manifes:

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

Memverifikasi kebijakan akses IAM

Periksa apakah kebijakan akses IAM berhasil dibuat dan periksa detail aturan:

# show iam access policy details
gcloud iam access-policies describe ${UAP_POLICY_NAME} \
  --project=${PROJ_ID} \
  --location=global

Output yang diharapkan:

details:
  rules:
  - conditions:
      iap.googleapis.com:
        expression: destination.is_registered == true
    description: allow ge assistant to any registered service
    effect: ALLOW
    operation:
      permissions:
      - iap.googleapis.com/resources.egressViaIAP
    principals:
    - principal://agents.global.org-${ORG_ID}.system.id.goog/resources/discoveryengine/projects/${PROJ_NO}/locations/global/engines/${GE_APP_INIT}/assistants/default_assistant/agents/default/core_assistant
name: projects/${PROJ_ID}/locations/global/accessPolicies/${UAP_POLICY_NAME}

Mengikat kebijakan akses IAM ke project

Untuk mengaktifkan penerapan di semua Agent Gateway dalam project Anda, buat binding kebijakan yang melampirkan kebijakan akses IAM ke resource project:

# bind iam access policy to project resource
gcloud iam policy-bindings create ${UAP_BINDING_NAME} \
  --policy="projects/${PROJ_ID}/locations/global/accessPolicies/${UAP_POLICY_NAME}" \
  --target-resource="//cloudresourcemanager.googleapis.com/projects/${PROJ_ID}" \
  --project=${PROJ_ID} \
  --location=global

Memverifikasi binding kebijakan akses IAM

Periksa titik pengikatan kebijakan aktif ke kebijakan dan target yang benar:

# show policy binding details
gcloud iam policy-bindings describe ${UAP_BINDING_NAME} \
  --project=${PROJ_ID} \
  --location=global

Output yang diharapkan:

name: projects/${PROJ_ID}/locations/global/policyBindings/${UAP_BINDING_NAME}
policy: projects/${PROJ_ID}/locations/global/accessPolicies/${UAP_POLICY_NAME}
policyKind: ACCESS
target:
  resource: //cloudresourcemanager.googleapis.com/projects/${PROJ_ID}

Bagian Agent Gateway telah selesai... selanjutnya ke bagian server MCP.

6. Server MCP

Di bagian ini, Anda akan membuat server FastMCP kustom yang mengekspos alat add dan subtract, lalu men-deploy-nya ke Cloud Run langsung dari sumber. Selama deployment sumber (--source), Cloud Build akan memaketkan image container menggunakan Dockerfile dan uv yang disertakan (yang menginstal dependensi yang ditentukan dalam pyproject.toml dan meluncurkan server.py).

Setelah layanan Cloud Run di-deploy, Anda mendaftarkan server MCP di Agent Registry beserta spesifikasi alatnya (toolspec.json) agar Gemini Enterprise dapat menemukan dan memanggil alatnya.

Membuat aplikasi server MCP

Buat direktori project math-wizard untuk kode aplikasi:

# create directory for code
mkdir -p math-wizard

Tulis file manifes project Python:

# create python project manifest file
cat > math-wizard/pyproject.toml << 'EOF'
[project]
name = "math-wizard"
version = "0.1.0"
description = "math wizard mcp server"
requires-python = ">=3.12"
dependencies = [
    "fastmcp==2.13.1",
]
EOF

Beberapa fungsi instrumentasi tambahan disertakan dalam kode untuk merekam header HTTP masuk (mcp-session-id, x-forwarded-for, user-agent, dan x-cloud-trace-context) untuk validasi Cloud Logging dan Cloud Trace.

Tulis file kode aplikasi:

# create mcp server application code
cat > math-wizard/server.py << 'EOF'
import asyncio
import json
import logging
import os
from fastmcp import FastMCP
from fastmcp.server.dependencies import get_http_headers
from mcp.types import ToolAnnotations

logger = logging.getLogger(__name__)
logging.basicConfig(format="[%(levelname)s]: %(message)s", level=logging.INFO)

mcp = FastMCP("math wizard mcp server")

def log_network_context(tool_name: str, a: int, b: int) -> None:
    headers = get_http_headers()
    print(json.dumps({
        "severity": "INFO",
        "message": f">>> 🛠️ Tool: '{tool_name}' called with numbers '{a}' and '{b}'",
        "tool": tool_name,
        "mcp_session_id": headers.get("mcp-session-id"),
        "x_forwarded_for": headers.get("x-forwarded-for"),
        "user_agent": headers.get("user-agent"),
        "trace_header": headers.get("x-cloud-trace-context"),
    }), flush=True)

@mcp.tool(
    annotations=ToolAnnotations(
        readOnlyHint=True,
    )
)
def add(a: int, b: int) -> int:
    """Use this to add two numbers together.

    Args:
        a: The first number.
        b: The second number.

    Returns:
        The sum of the two numbers.
    """
    logger.info(f">>> 🛠️ Tool: 'add' called with numbers '{a}' and '{b}'")
    log_network_context("add", a, b)
    return a + b

@mcp.tool(
    annotations=ToolAnnotations(
        readOnlyHint=True,
    )
)
def subtract(a: int, b: int) -> int:
    """Use this to subtract two numbers.

    Args:
        a: The first number.
        b: The second number.

    Returns:
        The difference of the two numbers.
    """
    logger.info(f">>> 🛠️ Tool: 'subtract' called with numbers '{a}' and '{b}'")
    log_network_context("subtract", a, b)
    return a - b

if __name__ == "__main__":
    logger.info(f"🚀 MCP server started on port {os.getenv('PORT', 8080)}")
    asyncio.run(
        mcp.run_async(
            transport="streamable-http",
            host="0.0.0.0",
            port=int(os.getenv("PORT", 8080)),
        )
    )
EOF

Tulis Dockerfile untuk menentukan petunjuk build image container dan perintah startup:

# create dockerfile
cat > math-wizard/Dockerfile << 'EOF'
# use official python 3.12 image
FROM python:3.12-slim

# install uv
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/

# install the project into /app
COPY . /app
WORKDIR /app

# allow statements and log messages to immediately appear in the logs
ENV PYTHONUNBUFFERED=1

# install dependencies
RUN uv sync

EXPOSE 8080

# run the mcp server
CMD ["uv", "run", "server.py"]
EOF

Men-deploy layanan ke Cloud Run

Deploy server MCP dari sumber menggunakan Cloud Build (yang menggunakan akun layanan Compute default project ${PROJ_NO}-compute@developer.gserviceaccount.com):

# deploy cloud run service
gcloud run deploy ${MCP_NAME} \
  --source math-wizard \
  --region=${REGION} \
  --no-invoker-iam-check \
  --ingress=internal \
  --quiet

Memverifikasi deployment Cloud Run

Periksa detail layanan Cloud Run untuk memverifikasi konfigurasi aktifnya:

# show cloud run service details
gcloud run services describe ${MCP_NAME} --region=${REGION}

Output yang diharapkan:

<snip>
✔ Service math-wizard in region ${REGION}

URL:     https://math-wizard-${PROJ_NO}.${REGION}.run.app
Ingress: internal
Traffic:
  100% LATEST (currently math-wizard-00001-<id>)
</snip>

Mendaftarkan server MCP di Agent Registry

Agar Gemini Enterprise dapat menemukan alat persis yang tersedia di server MCP, file spesifikasi alat (toolspec.json) harus diberikan selama pendaftaran ke Agent Registry.

Buat spesifikasi alat MCP

# create tool spec file
cat > cfg/toolspec.json << 'EOF'
{
  "tools": [
    {
      "name": "add",
      "description": "Use this to add two numbers together.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "a": { "type": "integer", "description": "The first number." },
          "b": { "type": "integer", "description": "The second number." }
        },
        "required": ["a", "b"]
      },
      "isReadOnly": true,
      "isDestructive": false,
      "isIdempotent": true,
      "isOpenWorld": false
    },
    {
      "name": "subtract",
      "description": "Use this to subtract two numbers.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "a": { "type": "integer", "description": "The first number." },
          "b": { "type": "integer", "description": "The second number." }
        },
        "required": ["a", "b"]
      },
      "isReadOnly": true,
      "isDestructive": false,
      "isIdempotent": true,
      "isOpenWorld": false
    }
  ]
}
EOF

Mendaftarkan server MCP di Agent Registry

# register mcp server in agent registry
gcloud agent-registry services create ${MCP_NAME} \
  --project=${PROJ_ID} \
  --location=${REGION} \
  --display-name="${MCP_NAME}-${PROJ_NO}.${REGION}.run.app" \
  --description="MANDATORY MATH & ARITHMETIC AGENT: You MUST ALWAYS invoke \
this tool for ANY mathematical calculation, addition (+), subtraction (-), \
sum, difference, or arithmetic question (including simple questions like \
'what is 67 + 345?'). NEVER compute arithmetic yourself and NEVER transfer \
math queries to file_and_coding_agent / code interpreter. Always delegate \
every math question to this tool." \
  --mcp-server-spec-type=tool-spec \
  --mcp-server-spec-content=cfg/toolspec.json \
  --interfaces=protocolBinding=JSONRPC,url="${MCP_URL}"

Memverifikasi server MCP di Agent Registry

Pastikan layanan Cloud Run yang di-deploy tercantum sebagai server MCP terdaftar di region bersama dengan URL endpoint dan alat yang tersedia:

# list registered mcp servers in agent registry
gcloud agent-registry mcp-servers list \
  --location=${REGION} \
  --project=${PROJ_ID} \
  --format="table(
    name.basename():label=REGISTRY_ID,
    displayName:label=DISPLAY_NAME,
    interfaces[0].url:label=ENDPOINT_URL,
    tools[].name.list():label=TOOLS
  )"

Output yang diharapkan:

REGISTRY_ID                                         DISPLAY_NAME                                  ENDPOINT_URL                                              TOOLS
agentregistry-00000000-0000-0000-0012-3456789abcde  math-wizard-${PROJ_NO}.${REGION}.run.app      https://math-wizard-${PROJ_NO}.${REGION}.run.app/mcp      add,subtract

Lihat spesifikasi konfigurasi layanan untuk melihat bahwa layanan tersebut mendaftarkan definisi alat, skema input, dan anotasi perilaku yang tepat untuk setiap alat:

# describe mcp server tool specs
gcloud agent-registry services describe ${MCP_NAME} \
  --location=${REGION} \
  --project=${PROJ_ID} \
  --format="yaml(mcpServerSpec.content.tools)"

Bagian server MCP ini telah selesai... selanjutnya ke bagian Gemini Enterprise.

7. Gemini Enterprise

Di bagian ini, Anda akan membuat dan mengonfigurasi aplikasi Gemini Enterprise dan resource penyimpanan data server MCP kustom yang ditautkan.

Model resource Discovery Engine

Aplikasi Gemini Enterprise (diwakili sebagai resource Engine di Discovery Engine API) adalah lapisan orkestrasi pusat dan antarmuka percakapan untuk pengguna akhir. Layanan ini mengelola sesi chat pengguna, mendasarkan model generatif pada data perusahaan, dan mengoordinasikan eksekusi alat dinamis.

Aplikasi Gemini Enterprise berinteraksi dengan data dan sistem melalui penyimpanan data:

  • Penyimpanan data pengetahuan: Menyerap dan mengindeks konten statis (misalnya, Cloud Storage, Google Drive, BigQuery) untuk retrieval-augmented generation (RAG).
  • Konektor data (penyedia tindakan): Terhubung ke API pihak ketiga atau API kustom yang dinamis. Penyimpanan data server MCP kustom mengekspos alat yang ditentukan oleh Model Context Protocol (MCP), sehingga memungkinkan model memanggil fungsi eksternal secara dinamis selama percakapan.

Perutean egress melalui Agent Gateway

Secara default, Gemini Enterprise merutekan traffic eksekusi alat dan konektor melalui jaringan publik. Namun, untuk workload VPC pribadi dan tata kelola zero-trust, mesin dapat dikonfigurasi untuk merutekan egress melalui Agent Gateway:

  • Saat membuat penyimpanan data server MCP kustom nanti di lab ini, Anda akan mengaktifkan Route egress through Agent Gateway di setelan penyimpanan data.
  • Hal ini mengikat panggilan alat keluar mesin ke Agent Gateway regional Anda, sehingga memastikan semua permintaan MCP membawa Agent Identity aplikasi, menjalani otorisasi runtime menggunakan IAP dan Kebijakan Akses Terpadu (UAP) IAM, serta melintasi lampiran jaringan PSC ke VPC pribadi Anda.

Membuat aplikasi Gemini Enterprise

Metode berikut menggunakan Gemini API discoveryengine.googleapis.com untuk membuat resource dan konfigurasi aplikasi Gemini Enterprise. Untuk mengonfigurasi menggunakan UI Konsol Google Cloud, lihat Membuat aplikasi untuk mengetahui petunjuknya.

# create engine (ge app)
curl -s -X POST "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/default_collection/engines?engineId=${GE_APP_INIT}" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}" -H "Content-Type: application/json" \
  -d @- <<EOF
{
  "displayName": "${GE_APP_DISPLAY_NAME}",
  "dataStoreIds": [],
  "solutionType": "SOLUTION_TYPE_SEARCH",
  "industryVertical": "GENERIC",
  "appType": "APP_TYPE_INTRANET",
  "searchEngineConfig": {
    "searchTier": "SEARCH_TIER_ENTERPRISE",
    "searchAddOns": [
      "SEARCH_ADD_ON_LLM"
    ]
  },
  "commonConfig": {
    "companyName": "${GE_APP_ORG_NAME}"
  }
}
EOF

Memverifikasi pembuatan aplikasi

# fetch engine (ge app) id
export GE_APP_ID=$(curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/default_collection/engines" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" -H "X-Goog-User-Project: ${PROJ_ID}" \
  | jq -r --arg name "${GE_APP_DISPLAY_NAME}" '.engines[] | select(.displayName==$name) | .name | split("/") | last')

echo "engine (ge app) id: ${GE_APP_ID}"

Lihat detail mesin untuk melihat konfigurasi yang dibuat:

# get engine (ge app) details
curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/default_collection/engines/${GE_APP_ID}" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}"

Perhatikan properti yang diisi server berikut dalam respons JSON:

  • name: Jalur resource kanonis (projects/${PROJ_NO}/locations/global/collections/default_collection/engines/${GE_APP_ID}).
  • sessionConfig.sessionManagementPolicy: Secara default ditetapkan ke "VERTEX_AI_MANAGED", yang mempertahankan status multi-turn chat dan panggilan alat di Agent Platform (sebelumnya dikenal sebagai Vertex AI).
  • observabilityConfig.observabilityEnabled: Secara default, nilainya adalah true untuk metrik dasar pengukuran (pencatatan log payload alat dan perintah yang mendetail diaktifkan pada langkah selanjutnya).

Aktifkan penyedia identitas

Aktifkan Google Identity sebagai penyedia identitas untuk autentikasi pengguna akhir di aplikasi Gemini Enterprise Anda.

Metode berikut menggunakan discoveryengine.googleapis.com API untuk mengonfigurasi penyedia identitas aplikasi Gemini Enterprise. Untuk mengonfigurasi menggunakan UI Konsol Google Cloud, lihat Mengonfigurasi penyedia identitas untuk mengetahui petunjuknya.

# set identity provider
curl -s -X PATCH "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/aclConfig" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}" -H "Content-Type: application/json" \
  -d @- <<EOF
{
  "idpConfig": {
    "idpType": "GSUITE"
  }
}
EOF

Memverifikasi penyedia identitas

# show identity provider
curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/aclConfig" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}"

Output "idpType": "GSUITE" sesuai dengan penyedia Google Identity.

(Opsional) Aktifkan lisensi uji coba Gemini Enterprise

Jika Anda menggunakan project yang telah ditetapkan lisensi Gemini Enterprise, Anda dapat melewati langkah ini. Jika Anda menggunakan project baru tanpa lisensi, lanjutkan dan ikuti langkah-langkah berikut.

Buat resource konfigurasi lisensi untuk memberikan hak atas kursi pengguna Gemini Enterprise selama 30 hari. Tindakan ini akan menyetel lisensi default ke uji coba baru, sehingga setiap pengguna yang login akan otomatis diberi tempat:

# configure free trial subscription
curl -s -X POST "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/licenseConfigs?licenseConfigId=free_trial_gemini" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}" -H "Content-Type: application/json" \
  -d @- <<EOF
{
  "subscriptionTier": "SUBSCRIPTION_TIER_SEARCH_AND_ASSISTANT",
  "freeTrial": true
}
EOF

Memverifikasi bahwa lisensi telah diterapkan

# show license config
curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/licenseConfigs/free_trial_gemini" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}"

Periksa "subscriptionTerm": "SUBSCRIPTION_TERM_ONE_MONTH" dan "freeTrial": true.

# verify auto-registration enabled on default user store
curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/userStores/default_user_store" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}"

Periksa ../free_trial_gemini" dan "enableLicenseAutoRegister": true.

Mengaktifkan setelan kemampuan observasi

Dengan mengaktifkan kemampuan observasi di tingkat aplikasi (mesin) Gemini Enterprise, Anda dapat melihat interaksi asisten inti dengan data metrik di Metrics Explorer dan mengorelasikan rekaman aktivitas end-to-end di Cloud Trace.

# set observability on engine (ge app)
curl -s -X PATCH "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/default_collection/engines/${GE_APP_ID}?updateMask=observabilityConfig" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}" -H "Content-Type: application/json" \
  -d @- <<EOF
{
  "observabilityConfig": {
    "observabilityEnabled": true,
    "sensitiveLoggingEnabled": true
  }
}
EOF

Memverifikasi setelan kemampuan pengamatan

# verify observability is enabled on engine (ge app)
curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/default_collection/engines/${GE_APP_ID}" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}" \
  | jq '{observabilityConfig: .observabilityConfig}'

Periksa "sensitiveLoggingEnabled": true.

Mengikat ke Agent Gateway

Merutekan traffic keluar dari Gemini Enterprise melalui Agent Gateway akan membuat batas penegakan keamanan dan tata kelola zero-trust terpusat untuk semua pemanggilan alat agen AI:

  • Penegakan kebijakan terpusat: Agent Gateway berfungsi sebagai proxy inline yang mengevaluasi permintaan alat keluar berdasarkan kebijakan otorisasi dan kontrol tata kelola sebelum traffic keluar dari lingkungan agen.
  • Egress jaringan pribadi: Mengikat Gemini Enterprise ke Agent Gateway memastikan panggilan alat yang menargetkan server MCP pribadi di Cloud Run dirutekan dengan aman melalui Private Service Connect (PSC), sehingga melewati internet publik.
  • Auditabilitas terpadu: Menyediakan logging permintaan, telemetri, dan jejak audit terpusat di semua server MCP dan alat eksternal yang terhubung.

Dengan mengonfigurasi agentGatewaySetting di aplikasi Gemini Enterprise, panggilan alat dan agen keluar yang dimulai oleh kueri pengguna akhir (seperti panggilan ke server MCP kustom yang diimpor dari Agent Registry dan agen A2A) akan otomatis dirutekan melalui Agent Gateway.

Patch mesin agentGatewaySetting untuk mengaktifkan:

# bind engine (ge app) to agent gateway
curl -s -X PATCH "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/default_collection/engines/${GE_APP_ID}?updateMask=agentGatewaySetting.defaultEgressAgentGateway.name" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}" -H "Content-Type: application/json" \
  -d @- <<EOF
{
  "agentGatewaySetting": {
    "defaultEgressAgentGateway": {
      "name": "projects/${PROJ_ID}/locations/${REGION}/agentGateways/${AGW_NAME}"
    }
  }
}
EOF

Memverifikasi binding Agent Gateway

Ambil konfigurasi aplikasi untuk mengonfirmasi pengikatan agentGatewaySetting:

# verify engine (ge app) agent gateway configuration
curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/default_collection/engines/${GE_APP_ID}" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}" \
  | jq '{name: .name, displayName: .displayName, agentGatewaySetting: .agentGatewaySetting}'

Output yang diharapkan:

{
  "name": "projects/${PROJ_NO}/locations/${GE_LOCATION}/collections/default_collection/engines/${GE_APP_ID}",
  "displayName": "${GE_APP_DISPLAY_NAME}",
  "agentGatewaySetting": {
    "defaultEgressAgentGateway": {
      "name": "projects/${PROJ_ID}/locations/${REGION}/agentGateways/${AGW_NAME}"
    }
  }
}

Membuat penyimpanan data server MCP kustom

Di bagian ini, Anda akan menghubungkan server MCP ke Gemini Enterprise dengan membuat penyimpanan data MCP kustom.

Menggunakan Discovery Engine API, proses ini terdiri dari dua langkah:

  1. Buat (:setUpDataConnector): Membuat resource Collection khusus (${MCP_NAME}-%timestamp-collection), melampirkan DataConnector (custom_mcp), dan menyediakan DataStore pendukungnya (..._mcp_data).
  2. Aktifkan (PATCH .../dataConnector?updateMask=actionConfig): Mengaktifkan runtime tindakan konektor (actionState: "ACTIVE") menggunakan spesifikasi alat Agent Registry dan mengikat DataStore (dataStoreIds) ke Engine Gemini Enterprise Anda.
# fetch mcp server agent registry resource name
export MCP_REGISTRY_URI=$(gcloud agent-registry mcp-servers list \
  --location=${REGION} \
  --project=${PROJ_ID} \
  --filter="displayName:${MCP_NAME}" \
  --format="value(name)")

echo "mcp registry name: ${MCP_REGISTRY_URI}"
echo "mcp url: ${MCP_URL}"

Membuat konektor data

# create custom mcp data connector from agent registry and link to engine
curl -s -X POST "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1alpha/projects/${PROJ_ID}/locations/${GE_LOCATION}:setUpDataConnector" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}" \
  -H "Content-Type: application/json" \
  -d @- <<EOF
{
  "collectionId": "${MCP_NAME}-$(date +%s)-collection",
  "collectionDisplayName": "${MCP_NAME}-collection",
  "dataConnector": {
    "dataSource": "custom_mcp",
    "dataSourceVersion": 1,
    "params": {
      "oauth_access_token": "unused"
    },
    "refreshInterval": "86400s",
    "entities": [
      {
        "entityName": "mcp_data"
      }
    ],
    "connectorModes": [
      "FEDERATED"
    ],
    "actionConfig": {
      "isActionConfigured": true,
      "createBapConnection": true,
      "actionParams": {
        "auth_type": "NO_AUTH",
        "instance_uri": "${MCP_URL}",
        "mcp_server_source": "REGISTRY_MCP",
        "registry_mcp_server_name": "${MCP_REGISTRY_URI}",
        "mcp_agent_instructions": "MANDATORY MATH & ARITHMETIC AGENT: Always invoke this tool for any mathematical calculation, addition (+), subtraction (-), sum, or difference.",
        "use_agent_gateway_egress": true,
        "agent_gateway_engine": "projects/${PROJ_ID}/locations/global/collections/default_collection/engines/${GE_APP_ID}"
      }
    }
  }
}
EOF

Memverifikasi pembuatan konektor data

# fetch collection id
export GE_COLLECTION_ID=$(curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1alpha/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}" \
  | jq -r --arg dname "${MCP_NAME}-collection" '.collections[] | select(.displayName == $dname) | .name | split("/") | last' | head -n 1)

echo "ge collection id: ${GE_COLLECTION_ID}"

Periksa apakah kolom "registry_mcp_server_name" diisi dengan UUID Agent Registry untuk server MCP:

# show data connector details
curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1alpha/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/${GE_COLLECTION_ID}/dataConnector" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}" \
  | jq '{name, state, actionState, connectorModes, bapConfig, registry_mcp_server_name: .actionConfig.actionParams.registry_mcp_server_name}'

Lihat entri pendaftaran server MCP di UI Konsol Google Cloud:

echo "mcp server registry page url: https://console.cloud.google.com/agent-platform/agent-registry/mcp-servers/${REGION}/${MCP_REGISTRY_URI##*/}/overview?project=${PROJ_ID}"

Mengaktifkan konektor data

# activate and bind data connector
curl -s -X PATCH "https://discoveryengine.googleapis.com/v1alpha/projects/${PROJ_ID}/locations/global/collections/${GE_COLLECTION_ID}/dataConnector?updateMask=actionConfig" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}" \
  -H "Content-Type: application/json" \
  -d @- <<EOF
{
  "name": "projects/${PROJ_ID}/locations/global/collections/${GE_COLLECTION_ID}/dataConnector",
  "actionConfig": {
    "isActionConfigured": true,
    "createBapConnection": true,
    "actionParams": {
      "auth_type": "NO_AUTH",
      "instance_uri": "${MCP_URL}",
      "mcp_server_source": "REGISTRY_MCP",
      "registry_mcp_server_name": "${MCP_REGISTRY_URI}",
      "mcp_agent_instructions": "MANDATORY MATH & ARITHMETIC AGENT: Always invoke this tool for any mathematical calculation, addition (+), subtraction (-), sum, or difference.",
      "use_agent_gateway_egress": true,
      "agent_gateway_engine": "projects/${PROJ_ID}/locations/global/collections/default_collection/engines/${GE_APP_ID}"
    }
  }
}
EOF

Memverifikasi penautan server MCP kustom

# show engine (ge app) details
curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/default_collection/engines/${GE_APP_ID}" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}" \
  | jq '{name: .name, dataStoreIds: .dataStoreIds, agentGatewaySetting: .agentGatewaySetting}'

Periksa penyimpanan data tertaut "dataStoreIds": "collection-math-wizard-_mcp_data".

# show collection details
curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1alpha/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}" \
  | jq --arg app "${GE_APP_ID}" '.collections[] | select(.dataConnector.actionConfig.actionParams.agent_gateway_engine // "" | endswith($app)) | .dataConnector | {name: .name, state: .state, actionState: .actionState, connectorModes: .connectorModes, actionParams: .actionConfig.actionParams}'

Periksa "state": "ACTIVE" dengan semua parameter yang diisi.

Tindakan alat

Saat memeriksa penyimpanan data math-wizard-collection di dasbor Gemini Enterprise, Anda akan melihat bahwa tab Actions tidak digunakan dan tombol ↻ Reload custom actions dinonaktifkan. Ini adalah perilaku yang diharapkan.

Lihat halaman detail penyimpanan data di UI Konsol Google Cloud:

echo "data store details page url: https://console.cloud.google.com/gemini-enterprise/locations/${GE_LOCATION}/collections/${GE_COLLECTION_ID}/connector/details?project=${PROJ_ID}"

Bergantung pada cara Anda menghubungkan server MCP kustom ke Gemini Enterprise, penemuan dan tata kelola alat ditangani dengan salah satu dari dua cara:

  • MCP Kustom Langsung (BYO_MCP alur kerja): Saat Anda mengonfigurasi server MCP kustom langsung di dalam Gemini Enterprise tanpa Agent Registry, penyimpanan data itu sendiri mengelola katalog alat (connectorModes: ["FEDERATED", "ACTIONS"]). Anda harus membuka tab Tindakan, mengklik ↻ Muat ulang tindakan kustom untuk mengambil skema tools/list, dan mengaktifkan atau menonaktifkan setiap alat secara manual (add dan subtract) di UI.
  • Impor Agent Registry (REGISTRY_MCP alur kerja yang digunakan dalam codelab ini): Saat Anda mengimpor server MCP dari Agent Registry, Agent Registry berfungsi sebagai sumber tepercaya yang resmi untuk endpoint MCP, metadata antarmukanya, dan katalog alatnya (connectorModes: ["FEDERATED"]). Gemini Enterprise secara otomatis mengaktifkan alat MCP yang terdaftar saat runtime melalui Agent Gateway mesin tanpa mengharuskan Anda memuat ulang atau mengalihkan tindakan secara manual di UI penyimpanan data.

Bagian aplikasi Gemini Enterprise telah selesai... selanjutnya ke bagian Validasi.

8. Validasi

Di bagian ini, Anda akan memicu panggilan alat MCP langsung dari aplikasi web Gemini Enterprise dan melacak alur permintaan di seluruh log Agent Gateway, Cloud DNS, firewall VPC, dan Cloud Run. Kemudian, Anda akan memperketat Kebijakan Akses Terpadu IAM untuk mengizinkan subtract sekaligus memblokir add, dengan memverifikasi penerapan zero-trust di gateway.

Akses pengguna

Buat URL untuk aplikasi web Gemini Enterprise:

# fetch app user url
export GE_WIDGET_ID=$(curl -s "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/default_collection/engines/${GE_APP_ID}/widgetConfigs/default_search_widget_config" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}" \
  -H "Content-Type: application/json" \
  | jq -r '.configId')

export GE_APP_USER_URL="https://vertexaisearch.cloud.google.com/home/cid/${GE_WIDGET_ID}"

echo "app user url: ${GE_APP_USER_URL}"

Ikuti link untuk membuka antarmuka chat aplikasi web Gemini Enterprise di browser Anda, lalu klik Mulai.

Menguji kueri agen dalam chat

Di UI chat, pastikan konektor data math-wizard-collection diaktifkan dengan mengklik ikon potongan puzzle untuk Konektor di bagian bawah kotak chat. Anda akan melihat tombol aktif/nonaktif yang muncul (berwarna).

Coba kueri pengujian berikut:

what is 2342345 - 98234798324?
what is 72347234 + 234234?

Verifikasi bahwa asisten menampilkan jawaban yang benar dan menampilkan badge kutipan tindakan interaktif (seperti Math Calculation (8s) 🤖 Agentgateway Agent) di bawah setiap respons, yang mengonfirmasi bahwa alat telah dijalankan.

Memeriksa log di Cloud Logging

Pastikan Gemini Enterprise merutekan panggilan alat melalui Agent Gateway dan jaringan VPC pribadi dengan memeriksa log di Cloud Logging.

1. Memverifikasi otorisasi Agent Gateway & IAP

Pastikan bahwa Agent Gateway mencegat permintaan, menyelesaikan target di Agent Registry, mendelegasikan otorisasi ke IAP, dan mengizinkan panggilan alat:

# show agent gateway logs
gcloud logging read 'resource.type="networkservices.googleapis.com/Gateway"' \
  --project=${PROJ_ID} \
  --limit=5 \
  --format="table( \
    timestamp.date(tz=LOCAL):label=TIMESTAMP, \
    httpRequest.status:label=STATUS, \
    httpRequest.serverIp:label=SERVER_IP, \
    jsonPayload.agentGatewayInfo.mcpInfo.method:label=MCP_METHOD, \
    jsonPayload.agentGatewayInfo.mcpInfo.parameter:label=TOOL, \
    jsonPayload.authzPolicyInfo.result:label=AUTHZ, \
    jsonPayload.agentGatewayInfo.agentRegistryResource.basename():label=REGISTRY_MCP
  )"

Pastikan output berisi:

  • STATUS: 200 (eksekusi berhasil) dan 202 (handshake notifications/initialized).
  • SERVER_IP: IP endpoint PSC Google API (172.16.20.20:443).
  • MCP_METHOD & TOOL: Urutan protokol MCP (notifications/initialized, tools/list, dan tools/call dengan add atau subtract).
  • AUTHZ: ALLOWED (otorisasi IAP mengizinkan keluar).
  • REGISTRY_MCP: ID resource Agent Registry yang telah diselesaikan (agentregistry-...).

2. Memverifikasi transit DNS dan firewall

Pastikan Cloud DNS menyelesaikan nama host ke endpoint PSC dan firewall mengizinkan traffic dari antarmuka Agent Gateway:

# show dns logs
gcloud logging read 'resource.type="dns_query"' \
  --project=${PROJ_ID} \
  --limit=5 \
  --format="table( \
    timestamp.date(tz=LOCAL):label=TIMESTAMP, \
    jsonPayload.queryName:label=QUERY_NAME, \
    jsonPayload.queryType:label=TYPE, \
    jsonPayload.responseCode:label=RCODE, \
    jsonPayload.rdata:label=RDATA
  )"
# show firewall logs
gcloud logging read 'logName:"compute.googleapis.com%2Ffirewall"' \
  --project=${PROJ_ID} \
  --limit=5 \
  --format="table( \
    timestamp.date(tz=LOCAL):label=TIMESTAMP, \
    jsonPayload.connection.src_ip:label=SRC_IP, \
    jsonPayload.connection.dest_ip:label=DEST_IP, \
    jsonPayload.connection.dest_port:label=PORT, \
    jsonPayload.rule_details.reference.basename():label=RULE, \
    jsonPayload.disposition:label=DISPOSITION
  )"

Verifikasi nilai berikut:

  • DNS QUERY_NAME & RDATA: Menyelesaikan math-wizard-...run.app. (data A, NOERROR) ke 172.16.20.20.
  • Firewall SRC_IP & DEST_IP: 192.168.10.2 (IP antarmuka PSC Agent Gateway) ke 172.16.20.20:443.
  • Firewall RULE & DISPOSITION: Cocok firewallPolicy:fw-policy-... dengan ALLOWED.

3. Memverifikasi eksekusi alat Cloud Run

Pastikan bahwa container Cloud Run menerima dan memproses panggilan alat:

# show cloud run logs
gcloud logging read 'resource.type="cloud_run_revision"
  AND textPayload:"Tool:"' \
  --project=${PROJ_ID} \
  --limit=5 \
  --format="value(timestamp.date(tz=LOCAL), textPayload)"

Pastikan textPayload menampilkan entri eksekusi alat (misalnya, >>> 🛠️ Tool: 'subtract' called with numbers '[x]' and '[y]').

Menguji penerapan kebijakan hak istimewa terendah

Dalam kebijakan akses IAM awal, metode atau alat apa pun diizinkan selama tujuan didaftarkan (destination.is_registered == true). Pada langkah ini, perbarui kebijakan untuk menerapkan hak istimewa terendah dengan hanya mengizinkan alat subtract sambil memblokir add.

Memperbarui kebijakan akses IAM

Saat membatasi eksekusi alat MCP, gunakan pola dua aturan:

  1. Aturan 1 (penemuan dan inisialisasi MCP): Mengizinkan metode siklus proses MCP non-panggilan alat (destination.is_registered == true dan destination.agent_registry.mcp_server.method != 'tools/call'). Karena Gemini Enterprise melakukan negosiasi penyiapan dan penemuan streaming (initialize, notifications/initialized, tools/list) sebelum memanggil alat—dan destination.agent_registry.mcp_server.tool.name hanya diisi selama tools/call—Aturan 1 diperlukan agar inisialisasi sesi dan penemuan katalog tetap berfungsi.
  2. Aturan 2 (Pembatasan tingkat alat): Membatasi eksekusi tools/call sehingga hanya alat subtract yang diizinkan (destination.is_registered == true, destination.agent_registry.mcp_server.method == 'tools/call', dan destination.agent_registry.mcp_server.tool.name == 'subtract').

Perbarui file manifes aturan kebijakan akses dengan kedua aturan:

# create access policy rule file (update: allow subtract only)
cat > cfg/${UAP_POLICY_NAME}-rule-update.json << EOF
[
  {
    "description": "allow ge assistant to any registered endpoint to perform mcp discovery and handshake",
    "effect": "ALLOW",
    "principals": [
      "principal://${TRUST_DOMAIN}/resources/discoveryengine/projects/${PROJ_NO}/locations/global/engines/${GE_APP_ID}/assistants/default_assistant/agents/default/core_assistant"
    ],
    "operation": {
      "permissions": [
        "iap.googleapis.com/resources.egressViaIAP"
      ]
    },
    "conditions": {
      "iap.googleapis.com": {
        "expression": \
        "destination.is_registered == true && \
         destination.agent_registry.mcp_server.method != 'tools/call'"
      }
    }
  },
  {
    "description": "allow ge assistant to any registered mcp server with tool call subtract",
    "effect": "ALLOW",
    "principals": [
      "principal://${TRUST_DOMAIN}/resources/discoveryengine/projects/${PROJ_NO}/locations/global/engines/${GE_APP_ID}/assistants/default_assistant/agents/default/core_assistant"
    ],
    "operation": {
      "permissions": [
        "iap.googleapis.com/resources.egressViaIAP"
      ]
    },
    "conditions": {
      "iap.googleapis.com": {
        "expression": \
        "destination.is_registered == true && \
         destination.agent_registry.mcp_server.method == 'tools/call' && \
         destination.agent_registry.mcp_server.tool.name == 'subtract'"
      }
    }
  }
]
EOF

Terapkan aturan yang diperbarui ke kebijakan akses IAM:

# update iam access policy
gcloud iam access-policies update ${UAP_POLICY_NAME} \
  --details-rules=cfg/${UAP_POLICY_NAME}-rule-update.json \
  --project=${PROJ_ID} \
  --location=global

Memverifikasi kebijakan akses IAM

Periksa apakah kebijakan akses IAM baru diterapkan dan hanya alat pengurangan yang diizinkan:

# show iam access policy details
gcloud iam access-policies describe ${UAP_POLICY_NAME} \
  --project=${PROJ_ID} \
  --location=global \
  --flatten="details.rules[]" \
  --format="table( \
    details.rules.principals[0].scope(engines).sub('assistants/default_assistant/agents/default', '...'):label=PRINCIPAL, \
    details.rules.effect:label=EFFECT, \
    details.rules.conditions.'iap.googleapis.com'.expression.sub('\s*&&\s*', '\n&& ').sub('\s*\|\|\s*', '\n|| '):label=EXPRESSION
  )"

Menguji panggilan alat yang dilarang

Kembali ke UI chat aplikasi web Gemini Enterprise dan coba kueri pengujian lain:

what is 100 plus 20?

Asisten mencoba memanggil add, tetapi Agent Gateway dan IAP mengevaluasi kondisi kebijakan IAM sebagai false dan menolak permintaan keluar dengan HTTP 403 Forbidden. Di UI chat, Anda akan melihat asisten menampilkan Calculate Sum dan berputar di 🤖 Agentgateway Agent ... Working on it. saat mencoba kembali panggilan alat yang diblokir. Ini adalah perilaku yang diharapkan. Hal ini mengonfirmasi bahwa Agent Gateway dan IAP secara aktif mencegat dan menolak eksekusi alat yang tidak diizinkan di tingkat jaringan.

Memeriksa ulang log di Cloud Logging

Lihat entri log Agent Gateway dan perhatikan entri 403 baru yang sesuai dengan panggilan alat add yang tidak diizinkan:

# show agent gateway logs
gcloud logging read 'resource.type="networkservices.googleapis.com/Gateway"' \
  --project=${PROJ_ID} \
  --limit=5 \
  --format="table( \
    timestamp.date(tz=LOCAL):label=TIMESTAMP, \
    httpRequest.status:label=STATUS, \
    httpRequest.serverIp:label=SERVER_IP, \
    jsonPayload.agentGatewayInfo.mcpInfo.method:label=MCP_METHOD, \
    jsonPayload.agentGatewayInfo.mcpInfo.parameter:label=TOOL, \
    jsonPayload.authzPolicyInfo.result:label=AUTHZ, \
    jsonPayload.agentGatewayInfo.agentRegistryResource.basename():label=REGISTRY_MCP
  )"

Output yang diharapkan:

TIMESTAMP            STATUS  SERVER_IP         MCP_METHOD                 TOOL  AUTHZ    REGISTRY_MCP
YYYY-MM-DDTHH:MM:SS  403                       tools/call                 add   DENIED   agentregistry-00000000-0000-0000-0012-3456789abcde
YYYY-MM-DDTHH:MM:SS  403
YYYY-MM-DDTHH:MM:SS  202     172.16.20.20:443  notifications/initialized        ALLOWED  agentregistry-00000000-0000-0000-0012-3456789abcde
YYYY-MM-DDTHH:MM:SS          172.16.20.20:443                                   ALLOWED  agentregistry-00000000-0000-0000-0012-3456789abcde
YYYY-MM-DDTHH:MM:SS  200     172.16.20.20:443  initialize                       ALLOWED  agentregistry-00000000-0000-0000-0012-3456789abcde

Periksa apakah permintaan tambahan tidak pernah mencapai backend Cloud Run:

# show cloud run logs
gcloud logging read 'resource.type="cloud_run_revision"
  AND textPayload:"Tool:"' \
  --project=${PROJ_ID} \
  --limit=5 \
  --format="value(timestamp.date(tz=LOCAL), textPayload)"

Perintah tidak menampilkan entri baru, yang mengonfirmasi bahwa Agent Gateway berhasil menerapkan kebijakan akses IAM.

Bagian validasi telah selesai... selanjutnya ke bagian Pembersihan.

9. Pembersihan

Ikuti langkah-langkah berikut untuk menghapus resource dan konfigurasi yang dibuat di lab ini.

Menghapus komponen Gemini Enterprise

# delete gemini enterprise engine (app)
curl -s -X DELETE "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/default_collection/engines/${GE_APP_ID}" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}"

# delete custom mcp collection, data connector, and backing data store
curl -s -X DELETE "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1alpha/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/${GE_COLLECTION_ID}" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}"

# reset identity provider configuration
curl -s -X PATCH "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1/projects/${PROJ_ID}/locations/${GE_LOCATION}/aclConfig" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "X-Goog-User-Project: ${PROJ_ID}" \
  -H "Content-Type: application/json" \
  -d '{"idpConfig":{"idpType":"IDP_TYPE_UNSPECIFIED"}}'

Menghapus komponen server MCP

# delete agent registry service
gcloud -q agent-registry services delete ${MCP_NAME} \
  --location=${REGION} \
  --project=${PROJ_ID}

# delete cloud run service, source-deploy artifact registry repo, and staging bucket
gcloud -q run services delete ${MCP_NAME} \
  --region=${REGION} \
  --project=${PROJ_ID}

gcloud -q artifacts repositories delete cloud-run-source-deploy \
  --location=${REGION} \
  --project=${PROJ_ID}

gcloud -q storage rm --recursive gs://run-sources-${PROJ_ID}-${REGION} \
  --project=${PROJ_ID}

Menghapus kebijakan akses IAM dan Agent Gateway

# delete gateway authorization policy, iap extension, and agent gateway
gcloud -q network-security authz-policies delete ${AGW_NAME}-authz-policy-iap \
  --location=${REGION} \
  --project=${PROJ_ID}

gcloud -q service-extensions authz-extensions delete ${AGW_NAME}-svc-ext-authz-iap \
  --location=${REGION} \
  --project=${PROJ_ID}

gcloud -q network-services agent-gateways delete ${AGW_NAME} \
  --location=${REGION} \
  --project=${PROJ_ID}
# delete iam policy binding and access policy
gcloud -q iam policy-bindings delete ${UAP_BINDING_NAME} \
  --location=global \
  --project=${PROJ_ID}

gcloud -q iam access-policies delete ${UAP_POLICY_NAME} \
  --location=global \
  --project=${PROJ_ID}

Menghapus komponen DNS dan firewall

# delete dns record set, managed zone, and policy
gcloud -q dns record-sets delete "*.run.app." \
  --type=A \
  --zone=priv-zone-run \
  --project=${PROJ_ID}

gcloud -q dns managed-zones delete priv-zone-run \
  --project=${PROJ_ID}

gcloud -q dns policies update dns-policy-${SLUG} \
  --networks="" \
  --project=${PROJ_ID}

gcloud -q dns policies delete dns-policy-${SLUG} \
  --project=${PROJ_ID}
# delete firewall policy association, rule, and policy
gcloud -q compute network-firewall-policies associations delete \
  --name=fw-policy-bind-${SLUG} \
  --firewall-policy=fw-policy-${SLUG} \
  --global-firewall-policy \
  --project=${PROJ_ID}

gcloud -q compute network-firewall-policies rules delete 1001 \
  --firewall-policy=fw-policy-${SLUG} \
  --global-firewall-policy \
  --project=${PROJ_ID}

gcloud -q compute network-firewall-policies delete fw-policy-${SLUG} \
  --global \
  --project=${PROJ_ID}

Menghapus komponen PSC dan jaringan VPC

# delete psc forwarding rule and internal ip address
gcloud -q compute forwarding-rules delete psc2gapis \
  --global \
  --project=${PROJ_ID}

gcloud -q compute addresses delete ip-psc2gapis \
  --global \
  --project=${PROJ_ID}
# delete psc network attachment, subnet, and vpc network
gcloud -q compute network-attachments delete psc-na-${REGION}-agw \
  --region=${REGION} \
  --project=${PROJ_ID}

gcloud -q compute networks subnets delete subnet-${REGION}-agw \
  --region=${REGION} \
  --project=${PROJ_ID}

gcloud -q compute networks delete vnet-${SLUG} \
  --project=${PROJ_ID}

Menghapus penggantian kebijakan organisasi dan file lokal

# delete project-level organization policy overrides
gcloud -q org-policies delete discoveryengine.managed.disableCustomMcpServerConnector --project=${PROJ_ID}
gcloud -q org-policies delete iam.managed.disableAccessPolicyBinding --project=${PROJ_ID}
# remove local project files
rm -rf cfg math-wizard

Dengan demikian, pekerjaan pembersihan telah selesai... selanjutnya kita akan membahas Kesimpulan.

10. Kesimpulan

Selamat! Anda telah membangun arsitektur end-to-end yang memungkinkan aplikasi Gemini Enterprise menemukan dan memanggil alat secara aman di server MCP kustom pribadi:

  • Server MCP kustom & Agent Registry: Men-deploy layanan FastMCP pribadi di Cloud Run (--ingress=internal) dan mendaftarkan endpoint serta skema alatnya (add dan subtract) di Agent Registry.
  • Integrasi Gemini Enterprise: Menyediakan aplikasi Gemini Enterprise, mengikat traffic alat keluar ke Agent Gateway, dan melampirkan server MCP terdaftar sebagai konektor data REGISTRY_MCP.
  • Egress VPC pribadi & tata kelola zero-trust: Eksekusi alat yang dirutekan secara pribadi melalui PSC (172.16.20.20) dan penerapan prinsip hak istimewa terendah tingkat alat menggunakan IAP dan Kebijakan Akses Terpadu IAM (destination.agent_registry.*).

cosmopup

Cosmpup menganggap Codelab sangat keren!

Apa langkah selanjutnya?

Jangan ragu untuk memberikan komentar, pertanyaan, atau koreksi menggunakan formulir masukan ini.

Terima kasih!