1. Einführung
In diesem Codelab wird die Konnektivität für statische IP-Adressen für Gemini Enterprise mit dem Agent Gateway im agent-to-anywhere-Modus (Ausgang) untersucht. Sie konfigurieren eine Gemini Enterprise-App, um einen benutzerdefinierten MCP-Server (Model Context Protocol) aufzurufen, der durch eine strenge Quell-IP-Zulassungsliste und die OAuth 2.0-Authentifizierung geschützt ist. Dazu leiten Sie den gesamten ausgehenden Traffic über das Agenten-Gateway weiter. Ein Private Service Connect-Netzwerk-Anhang (PSC) verbindet Agent Gateway mit dem VPC-Netzwerk und Cloud NAT bietet eine stabile externe IP-Adresse für ausgehenden Internet-Traffic.
Standardmäßig stammen ausgehende Verbindungen von Gemini Enterprise zu öffentlichen Internetendpunkten aus dynamischen, freigegebenen Google-IP-Adresspools, die nicht an eine einzelne, vom Kunden verwaltete IP-Zulassungsregel gebunden werden können. Wenn Sie das Agent Gateway mit einem AgentConnectivityTemplate im ALL_TRAFFIC-Modus koppeln, wird der gesamte ausgehende Agent-Traffic in das VPC-Netzwerk weitergeleitet. Dort übersetzt Cloud NAT internetgebundene Verbindungen in eine reservierte statische externe IPv4-Adresse, die Sie steuern. Gleichzeitig wird die zentrale MCP-Tool-Verwaltung über die Agent Registry und Identity-Aware Proxy (IAP) beibehalten.
Was Sie erstellen
- Agent Connectivity-Vorlage (
vpcEgress: ALL_TRAFFIC) und Agent Gateway im Ausgehenden-Modus (Agent zu beliebigem Ziel) mit Endpunktüberprüfung der Agent Registry - VPC-Netzwerk, PSC-Netzwerkanhang, Cloud Router und Cloud NAT-Gateway, die an eine reservierte statische externe IPv4-Adresse gebunden sind
- Externer streamfähiger HTTP-MCP-Ressourcenserver (
mcp-sprockets), der von Caddy TLS bereitgestellt wird, durch Firewallregeln streng auf die statische Cloud NAT-IP beschränkt ist und von Nutzern delegierte Google OAuth 2.0-Bearertokens anhand vonhttps://oauth2.googleapis.com/tokeninfoüberprüft - OAuth 2.0-Zustimmungsbildschirm der Google Auth Platform und OAuth 2.0-Clientanmeldedaten für Webanwendungen (
accounts.google.comundoauth2.googleapis.com/token) - MCP-Serverkatalogeintrag und Tool-Spezifikation in der Agent Registry (
toolspec.json) - IAP-Autorisierungserweiterung (Identity-Aware Proxy) und Gateway-Autorisierungsrichtlinie für Agent Gateway
- Gemini Enterprise-App, die an das KI-Agenten-Gateway gebunden und mit einem OAuth 2.0-Datenspeicher für benutzerdefinierte MCP-Server verbunden ist, der aus der Agent Registry importiert wurde
Abbildung 1. Codelab-Architektur
Lerninhalte
- Konfigurieren eines
AgentConnectivityTemplatemitvpcEgress: ALL_TRAFFIC, um den gesamten ausgehenden Agent Gateway-Traffic in ein VPC-Netzwerk weiterzuleiten - Statische externe IPv4-Adresse reservieren und an Cloud NAT in einem PSC-Netzwerkanhang-Subnetz binden
- So stellen Sie einen externen streamfähigen HTTP-MCP-Ressourcenserver bereit, der Google OAuth 2.0-Bearertokens (
oauth2.googleapis.com/tokeninfo) prüft und die Ingress-Firewall streng auf die statische IP-Adresse von Cloud NAT (${NAT_EXT_IP}/32) beschränkt. - So konfigurieren Sie Google Identity OAuth 2.0-Clientanmeldedaten und registrieren einen MCP-Server und sein Tool-Schema in Agent Registry
- So verbinden Sie einen registrierten OAuth 2.0-MCP-Server mit Gemini Enterprise und leiten nutzerdelegierte Tool-Aufrufe über Agent Gateway weiter
- So validieren Sie die statische IP-Übersetzung, die OAuth 2.0-Identitätsbestätigung für Endnutzer (
authenticated_user) und die Durchsetzung von Gateway-Richtlinien mit CLI-Befehlen und Cloud Logging
Voraussetzungen
- Ein Google Cloud-Projekt mit aktivierter Abrechnung
- Eine aktive Gemini Enterprise-Lizenz oder ein 30‑tägiger Testzeitraum
- IAM-Berechtigungen zum Bereitstellen von Netzwerkdiensten, Organisationsrichtlinien, Gemini Enterprise und Agent Platform-Ressourcen
- Eine POSIX-kompatible Shell (
bashoderzsh) mit installierter Google Cloud CLI (gcloud),curlundjq
Damit ist die Einführung abgeschlossen. Weiter geht es mit dem Abschnitt Konzepte.
2. Konzepte
Bereitstellungsreihenfolge
In diesem Codelab wird zuerst die Netzwerk- und Governance-Infrastruktur bereitgestellt, damit statische IP-Ausgangspfade und Gateway-Steuerelemente betriebsbereit sind, bevor MCP-Tools bei Gemini Enterprise registriert und mit Gemini Enterprise verbunden werden:
- Netzwerkinfrastruktur:Reservieren Sie statische externe IPv4-Adressen und stellen Sie die VPC für ausgehenden Traffic, das PSC-Anhangs-Subnetz, den PSC-Netzwerkanhang, den Cloud Router, das Cloud NAT-Gateway und die Firewallregeln für das externe MCP-Netzwerk bereit.
- Konnektivitätsvorlage des KI-Agents und Agent Gateway:Stellen Sie die
AgentConnectivityTemplate(vpcEgress: ALL_TRAFFIC) und die regionaleAgentGatewayim Egress-Modus (AGENT_TO_ANYWHERE) mit Agent Registry-Integration (registries) bereit. - Autorisierungsrichtlinien:Konfigurieren Sie die IAP-Autorisierungserweiterung (
AuthzExtension), die Gateway-Autorisierungsrichtlinie (AuthzPolicy) und die Unified Access Policy für IAM v3 (AccessPolicyundPolicyBinding). - MCP-Server bereitstellen und registrieren:Stellen Sie den externen
mcp-sprockets-OAuth 2.0-Ressourcenserver hinter Caddy TLS bereit, prüfen Sie die Google-OAuth 2.0-tokeninfo-Durchsetzung, beschränken Sie die Ingress-Firewall streng auf die statische Cloud NAT-IP-Adresse (${NAT_EXT_IP}/32) und registrieren Sie die Dienst- und Toolspezifikationen (get_sprocketsundget_sprocket_by_id) in der Agent Registry. - Gemini Enterprise-App und OAuth 2.0-Client:Konfigurieren Sie den Google-Identitätsanbieter, die Testlizenz, den OAuth 2.0-Zustimmungsbildschirm und die Clientanmeldedaten für Webanwendungen (
OAUTH_CLIENT_IDundOAUTH_CLIENT_SECRET), erstellen Sie die Gemini Enterprise-App (Engine) und binden Sie den ausgehenden Egress an das Agent Gateway (agentGatewaySetting). - Benutzerdefinierten MCP-Daten-Connector importieren:Erstellen und aktivieren Sie den
REGISTRY_MCP-Daten-Connector (:setUpDataConnector), der mitauth_type: "OAUTH"konfiguriert ist, um den registrierten MCP-Server-Backing-Datenspeicher mit der Gemini Enterprise App zu verknüpfen. - Validieren:Führen Sie den einmaligen OAuth 2.0-Einwilligungsablauf für Nutzer aus, rufen Sie MCP-Tools über den Gemini Enterprise-Assistenten auf (bestätigen Sie sowohl
egress_source_ipals auchauthenticated_user) und prüfen Sie die Richtliniendurchsetzung und die statische IP-NAT-Übersetzung in Cloud Logging.
Zentrale IdP-Architektur + OAuth-geschützter MCP-Ressourcenserver
In Unternehmensbereitstellungen folgen die Identitätsverwaltung und die Ausführung von Tools der standardmäßigen OAuth 2.0-Trennung von Rollen zwischen einem zentralen Identitätsanbieter (Autorisierungsserver) und einem geschützten MCP-Ressourcenserver:
OAuth 2.0-Rolle | Komponente in diesem Codelab | Zuständigkeit |
Ressourceninhaber | Endnutzer ( | Meldet sich in der Gemini Enterprise Web-App an und erteilt die Einwilligung während des einmaligen 3-legged OAuth 2.0-Autorisierungsablaufs. |
OAuth 2.0-Client | Gemini Enterprise | Enthält |
Autorisierungsserver | Google Identity OAuth 2.0 ( | Authentifiziert den Nutzer während der Weiterleitung zur Einwilligung im Browser und stellt Gemini Enterprise die OAuth 2.0-Zugriffs- und ‑Aktualisierungstokens aus. |
Ressourcenserver | Externer | Erzwingt die Layer 3-Netzwerkidentität mithilfe der VPC-Firewall ( |
Da die Browser-Einwilligungsweiterleitung (accounts.google.com) und der Backchannel-Tokenaustausch (oauth2.googleapis.com/token) über von Google verwaltete OAuth 2.0-Endpunkte erfolgen, empfängt die Firewall des externen MCP-Servers nur JSON-RPC-Anfragen (POST /mcp) für die MCP-Laufzeit vom Agent Gateway über Cloud NAT. So kann die Eingangsfirewall streng auf ${NAT_EXT_IP}/32 beschränkt werden.
Discovery Engine-Ressourcenmodell
Eine Gemini Enterprise-App (in der Discovery Engine API als Engine-Ressource dargestellt) ist die zentrale Orchestrierungsebene und Konversationsschnittstelle für Endnutzer. Sie verwaltet Nutzer-Chatsitzungen, stützt generative Modelle auf Unternehmensdaten und koordiniert die dynamische Ausführung von Tools.
Gemini Enterprise-Apps interagieren über Datenspeicher mit Daten und Systemen:
- Wissensdatenspeicher:Statische Inhalte (z. B. Cloud Storage, Google Drive, BigQuery) für RAG (Retrieval Augmented Generation) aufnehmen und indexieren.
- Daten-Connectors (Aktionsanbieter): Sie können eine Verbindung zu dynamischen Drittanbieter- oder benutzerdefinierten APIs herstellen. Ein benutzerdefinierter MCP-Server-Datenspeicher stellt Tools bereit, die durch das Model Context Protocol (MCP) definiert werden. So kann das Modell während einer Unterhaltung dynamisch externe Funktionen aufrufen.
Gemini Enterprise-Ausgang
Gemini Enterprise leitet Anfragen für benutzerdefinierte MCP-Server-Tools an das Agenten-Gateway weiter, wenn sowohl agentGatewaySetting für Engine als auch use_agent_gateway_egress: true für DataConnector konfiguriert sind.
Abbildung 2. Gemini Enterprise-Ausgangsarchitektur
Die Gemini Enterprise App organisiert das Tool-Routing in vier wichtigen Bereichen:
- Widget (
default_search_widget_config)- :
- Stellt die Webclient-Schnittstelle bereit. Das Widget empfängt Prompts vom Nutzer, löst die einmalige OAuth 2.0-Nutzereinwilligungsweiterleitung aus, wenn ein Tool eine Autorisierung erfordert, und startet Chatsitzungen mit der zugrunde liegenden Engine.
- Core Assistant (
assistants/default_assistant/agents/default/core_assistant)- :
- Der konversationelle Reasoning-Root-Agent in der Engine. Bei der Auswertung einer Nutzeranfrage prüft der Core Assistant die verfügbaren Tools und delegiert die Ausführung an den synthetisierten Agent Gateway-Unteragenten.
- Datenspeicher und Daten-Connector
- :
DataStore:Wird in einem dediziertenCollectionbereitgestellt, wenn:setUpDataConnectorausgeführt wird. Es verknüpft (dataStoreIds) die importierten Tool-Schemas der Agent Registry (get_sprockets,get_sprocket_by_id), Argumenttypen und Agent-Anweisungen mit dem Gemini Enterprise-Engine.DataConnector:Verwaltet dieREGISTRY_MCP-Aktionsverbindung (createBapConnection: true) zum Remote-MCP-Server (instance_uri), löst die MCP-Serverressource der Agenten-Registry (registry_mcp_server_name) auf, hängt das im Nutzer-Vault gespeicherte OAuth 2.0-Bearer-Token (Authorization: Bearer [access_token]) an und aktiviert den Agenten-Gateway-Ausgang (use_agent_gateway_egress: true).
- Agent Identity, Agent Registry und Agent Gateway
- :
- Wenn der Data Connector den ausgehenden Tool-Aufruf sendet, wird der Traffic an das in
agentGatewaySettingangegebene Gateway weitergeleitet. Der Gacklaxiekern-Assistent erstellt ein SPIFFE-Identitätstoken, das seine Workload-Identität bestätigt:principal://agents.global.org-.../agents/default/core_assistant. - Agent Gateway wird über das Feld
registriesin Agent Registry eingebunden, um Zielendpunkte und registrierte Tool-Schemas dynamisch aufzulösen. Autorisierungsrichtlinien werden mit IAP ausgewertet und zulässige Anfragen werden überAgentConnectivityTemplatein das VPC-Netzwerk weitergeleitet. Dabei wird der NutzerheaderAuthorization: Bearerbeibehalten.
- Wenn der Data Connector den ausgehenden Tool-Aufruf sendet, wird der Traffic an das in
VPC-Verbindung des Gateways und statisches IP-NAT
Agent Gateway unterstützt VPC-Netzwerkverbindungen über eine AgentConnectivityTemplate-Ressource, auf die von agentConnectivityTemplate auf dem Gateway verwiesen wird. Die Vorlage egressNetworkConfig definiert, wie Traffic über eine PSC-Netzwerkverbindung in Ihre VPC gelangt:
PRIVATE_RANGES_ONLY(Standard): Leitet nur private IP-Bereiche nach RFC 1918, RFC 6598 und Klasse E über die PSC-Netzwerkverbindung weiter. Internet-Traffic umgeht Ihre VPC und wird direkt über den standardmäßigen Internet-Ausgang von Google weitergeleitet.ALL_TRAFFIC(in diesem Codelab verwendet): Leitet den gesamten ausgehenden Traffic vom Agent Gateway, einschließlich des öffentlichen Internets und der externen Partner-MCP-Endpunkte, über die PSC-Netzwerkverbindung (10.10.10.2) in Ihr VPC-Subnetz weiter.
Wenn Sie im ALL_TRAFFIC-Modus arbeiten, sind für das PSC-Anhangssubnetz zwei Konfigurationen erforderlich:
- Privater Google-Zugriff (
--enable-private-ip-google-access): Sorgt dafür, dass interne Aufrufe von Google Cloud APIs (*.googleapis.com) weiterhin privat über das Google-Netzwerk weitergeleitet werden. - Cloud Router und Cloud NAT (
MANUAL_ONLY): Internetgebundener Traffic, der in das PSC-Anhangssubnetz eingeht, folgt der Standardroute (0.0.0.0/0) über Cloud NAT. Dabei wird die Quellnetzwerkadressübersetzung (Source Network Address Translation, SNAT) für Ihre reservierte statische externe IPv4-Adresse (${NAT_EXT_IP}) durchgeführt. Externe Firewalls können den eingehenden Zugriff daher streng auf${NAT_EXT_IP}/32beschränken.
Einschränkungen und Anforderungen
- Nur StreamableHTTP:Der alte SSE-Transport (Server-Sent Events) wird nicht unterstützt. MCP-Server müssen StreamableHTTP verwenden.
- Überschreiben der Organisationsrichtlinie:Sie müssen die Organisationsrichtlinie für benutzerdefinierte MCP-Datenspeicher explizit überschreiben, bevor Sie den Datenconnector registrieren.
- Regionale Ausrichtung:Bei Gemini Enterprise wird die regionale Ausrichtung zwischen dem App-Standort, dem Agent Gateway und der Agent Registry erzwungen:
Standort der Gemini Enterprise App | Standort des KI-Agenten-Gateways und des NAT | Speicherort der Agent Registry |
|
|
|
|
|
|
|
|
|
Damit ist der Konzeptteil abgeschlossen. Weiter geht es mit dem Abschnitt Einrichtung.
3. Einrichtung
Erforderliche IAM-Rollen
Für dieses Codelab sind die folgenden Rollen erforderlich:
Domain | Erforderliche IAM-Rollen |
Projekt und IAM |
|
Netzwerk und Gateway |
|
Gemini Enterprise und Registry |
|
Arbeitslasten |
|
Beobachtbarkeit |
|
Alternativ können Sie eine allgemeine einfache Rolle wie roles/owner in Kombination mit roles/orgpolicy.policyAdmin verwenden, da mit roles/owner allein keine Organisationsrichtlinien geändert werden können.
Auf Ihr Projekt zugreifen
In diesem Codelab wird ein einzelnes Google Cloud-Projekt verwendet. Für die Konfigurationsschritte werden die gcloud-Befehlszeile und Linux-Shell-Befehle verwendet.
Rufen Sie zuerst die Befehlszeile Ihres Google Cloud-Projekts auf:
- Cloud Shell unter
shell.cloud.google.comoder - Ein lokales Terminal mit
gcloudCLI installiert
Projekt-ID festlegen
# set target project id
gcloud config set project SET_YOUR_PROJECT_ID_HERE
Sitzung authentifizieren
# login to gcloud cli
gcloud auth login
# login for gcloud api
gcloud auth application-default login
Shell-Umgebungsvariablen festlegen
# set custom var for slug (eg, "foo") and region preference
export SLUG="foo"
export REGION="us-central1"
export ZONE="us-central1-a"
echo ${SLUG}
echo ${REGION}
echo ${ZONE}
# 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 MCP_NAME="mcp-sprockets"
echo ${AGW_NAME}
echo ${AGW_URI}
echo ${MCP_NAME}
# create resource vars for gemini enterprise (automatic)
export GE_LOCATION="global"
export GE_APP_ORG_NAME="${SLUG}, Inc."
export GE_APP_DISPLAY_NAME="${SLUG} ${GE_LOCATION} app"
export GE_APP_NAME="app-${SLUG}-${GE_LOCATION}"
export GE_APP_INIT="${GE_APP_NAME}_$(date +%s)"
echo ${GE_LOCATION}
echo ${GE_APP_ORG_NAME}
echo ${GE_APP_DISPLAY_NAME}
echo ${GE_APP_NAME}
echo ${GE_APP_INIT}
Vertrauenswürdige Domains für die Identität von KI‑Agenten festlegen
Mit der if-then-else-Anweisung wird geprüft, ob das Projekt zu einer Organisation gehört, um die richtige Vertrauensdomäne für die Identitäten des Haupt-Agents festzulegen.
# 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}"
Abrechnungs- und Kontingentprojekt festlegen
# 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}
Lokales Verzeichnis für Konfigurationsdateien erstellen
# create config folder
mkdir -p cfg
gcloud cli aktualisieren (empfohlen)
Wenn Sie eine selbstverwaltete Installation des Google Cloud SDK ausführen (d. h. außerhalb von Cloud Shell), aktualisieren Sie die Komponenten auf die neueste Version.
# update gcloud cli
gcloud components update
API-Dienste aktivieren
# enable google cloud apis
gcloud services enable \
agentregistry.googleapis.com \
aiplatform.googleapis.com \
cloudapiregistry.googleapis.com \
cloudresourcemanager.googleapis.com \
compute.googleapis.com \
discoveryengine.googleapis.com \
dns.googleapis.com \
iam.googleapis.com \
iap.googleapis.com \
logging.googleapis.com \
monitoring.googleapis.com \
networkconnectivity.googleapis.com \
networksecurity.googleapis.com \
networkservices.googleapis.com \
orgpolicy.googleapis.com \
serviceextensions.googleapis.com \
serviceusage.googleapis.com
Organisationsrichtlinien
Standardmäßige Einschränkungen für verwaltete Organisationsrichtlinien und Sandbox-Richtlinien für Google Cloud können die in diesem Codelab verwendeten Funktionen einschränken:
compute.vmExternalIpAccess: Beschränkt externe IPv4-Adressen auf Compute Engine-VMs in gesperrten Sandbox-Organisationen.discoveryengine.managed.disableCustomMcpServerConnector: Beschränkt die Erstellung von Datenconnectors, die einen benutzerdefinierten MCP-Server (custom_mcp) als Datenquelle verwenden (wird standardmäßig erzwungen).discoveryengine.managed.allowedEgressFqdns: Beschränkt ausgehende Domains (instance_uriFQDNs) für Daten-Connectors, wenn VPC Service Controls (VPC-SC) aktiv ist oder das Projekt inenforcedProjectsaufgeführt ist.discoveryengine.managed.allowedDataSources: Beschränkt die zulässigen Daten-Connectortypen (dataSource), wenn VPC-SC aktiv ist oder das Projekt inenforcedProjectsaufgeführt wird.
Überschreiben Sie alle geerbten Einschränkungen von Organisationsrichtlinien auf Projektebene.
Benutzerdefinierte MCP-Einschränkung deaktivieren
# disable data connector constraint (allow custom mcp servers)
gcloud org-policies set-policy "/dev/stdin" <<EOF
name: projects/${PROJ_ID}/policies/discoveryengine.managed.disableCustomMcpServerConnector
spec:
rules:
- enforce: false
EOF
Einschränkungen für bedingte Daten-Connectors deaktivieren
# disable egress fqdn constraint on project
gcloud org-policies set-policy "/dev/stdin" <<EOF
name: projects/${PROJ_ID}/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_ID}/policies/discoveryengine.managed.allowedDataSources
spec:
rules:
- enforce: false
EOF
Einschränkung für Zugriffsrichtlinie deaktivieren
# 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
Externe IP-Adressen zulassen
# allow external ip address for vms on project
gcloud org-policies set-policy "/dev/stdin" <<EOF
name: projects/${PROJ_ID}/policies/compute.vmExternalIpAccess
spec:
rules:
- allowAll: true
EOF
Organisationsrichtlinien prüfen
Prüfen Sie, ob compute.vmExternalIpAccess auf allowAll: True und die anderen Richtlinien auf enforce: False gesetzt sind:
# verify effective org policy constraints on project
for policy in \
discoveryengine.managed.disableCustomMcpServerConnector \
discoveryengine.managed.allowedEgressFqdns \
discoveryengine.managed.allowedDataSources \
iam.managed.disableAccessPolicyBinding \
compute.vmExternalIpAccess; do
gcloud org-policies describe ${policy} \
--project=${PROJ_ID} \
--effective \
--format="flattened[no-pad](name.basename(),spec.rules[0])"
done
Bindungen des Dienst-Agents prüfen (Vorsichtsmaßnahme)
In einem neuen Projekt stellt Google Cloud automatisch den Agent Gateway-Dienst-Agent bereit und gewährt ihm roles/agentgateway.serviceAgent, wenn networkservices.googleapis.com zum ersten Mal aktiviert wird. Wenn Sie ein vorhandenes Projekt wiederverwenden, in dem durch vorherige Bereinigungen möglicherweise Standardbindungen für Dienst-Agents entfernt wurden, führen Sie die folgenden Befehle als zusätzliche Sicherheitsmaßnahme aus, um sicherzustellen, dass die Identitäts- und Rollenbindung intakt sind:
# 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"
Das war der Einrichtungsteil. Weiter geht es mit dem Abschnitt Netzwerk.
4. Netzwerk
In diesem Abschnitt reservieren Sie die statischen externen IPv4-Adressen, erstellen das interne VPC-Netzwerk für ausgehenden Traffic und das isolierte externe VPC-Netzwerk, stellen die PSC-Netzwerkverbindung bereit, konfigurieren Cloud NAT und erstellen Firewallregeln.
Statische externe IP-Adressen reservieren
Reservieren Sie zwei regionale statische externe IPv4-Adressen für Cloud NAT und die externe MCP-Server-VM:
# reserve static external ipv4 address for cloud nat
gcloud compute addresses create ip-${SLUG}-nat \
--region=${REGION}
# reserve static external ipv4 address for the mcp server
gcloud compute addresses create ip-${SLUG}-mcp \
--region=${REGION}
Statische externe IP-Adressen prüfen
Für Gemini Enterprise ist es erforderlich, dass für Remote-MCP-Endpunkte HTTPS mit einem öffentlich vertrauenswürdigen TLS-Zertifikat verwendet wird. Anstatt eine benutzerdefinierte Domain für dieses Lab zu registrieren, verwenden Sie sslip.io, einen kostenlosen DNS-Dienst mit Platzhalter, der jeden Hostnamen mit einer IP-Adresse (z. B. mcp.[IP].sslip.io) direkt in diese IP-Adresse auflöst. Da Zertifizierungsstellen wie Let's Encrypt keine Zertifikate für reine IP-Adressen ausstellen, bietet dieser sslip.io-Hostname dem Caddy-Reverse-Proxy einen gültigen Domainnamen, um automatisch ein vertrauenswürdiges TLS-Zertifikat für den MCP-Server bereitzustellen.
Exportieren Sie beide IPv4-Adressen und erstellen Sie den sslip.io-Domainnamen und die URL für den externen MCP-Server:
# export static ip addresses and set vars for domain
export NAT_EXT_IP=$(gcloud compute addresses describe ip-${SLUG}-nat \
--region=${REGION} \
--format="value(address)")
export MCP_EXT_IP=$(gcloud compute addresses describe ip-${SLUG}-mcp \
--region=${REGION} \
--format="value(address)")
export MCP_DOMAIN="mcp.${MCP_EXT_IP}.sslip.io"
export MCP_URL="https://${MCP_DOMAIN}/mcp"
echo "cloud nat external ip : ${NAT_EXT_IP}"
echo "mcp server external ip : ${MCP_EXT_IP}"
echo "mcp url : ${MCP_URL}"
Beispielausgabe:
cloud nat external ip : 203.0.113.10
mcp server external ip : 203.0.113.20
mcp url : https://mcp.203.0.113.20.sslip.io/mcp
Internes Netzwerk erstellen
Wenn die Konnektivitätsvorlage für das Agent Gateway für die Verwendung eines egressNetworkConfig mit einem networkAttachment konfiguriert ist, muss das Subnetz, in dem die PSC-Netzwerkverbindung gehostet wird, mindestens ein /28-CIDR-Block sein und privater Google-Zugriff (--enable-private-ip-google-access) muss aktiviert sein.
Globales VPC-Netzwerk für den internen Agent Gateway-Ausgang erstellen:
# create vpc network
gcloud compute networks create vnet-${SLUG}-internal --subnet-mode=custom
# create subnet for agent gateway psc na
gcloud compute networks subnets create subnet-${REGION}-agw \
--network=vnet-${SLUG}-internal \
--range=10.10.10.0/28 \
--region=${REGION} \
--enable-private-ip-google-access
Interne Firewallregeln erstellen
Erstellen Sie eine Firewallrichtlinie, die den gesamten ausgehenden Traffic mit aktiviertem Logging zulässt. Damit wird der Traffic überwacht, der vom Agent Gateway an das interne VPC-Netzwerk übertragen wird. Cloud NGFW unterstützt sowohl die Essentials- als auch die Standardstufe für Netzwerksicherheit und Traffic-Monitoring.
# create fw policy
gcloud compute network-firewall-policies create fw-policy-${SLUG}-internal --global
# create fw policy rule
gcloud compute network-firewall-policies rules create 1001 \
--description="allow all out and log" \
--firewall-policy=fw-policy-${SLUG}-internal \
--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}-internal \
--firewall-policy=fw-policy-${SLUG}-internal \
--network=vnet-${SLUG}-internal \
--global-firewall-policy
PSC-Netzwerkanhang erstellen
Erstellen Sie einen Private Service Connect-Netzwerkanhang (PSC), der so konfiguriert ist, dass Verbindungen von Agent Gateway automatisch akzeptiert werden. Mit dem Netzwerkanhang wird die Nutzer-VPC-Netzwerkseite der Verbindung eingerichtet, um eine sichere Verbindung mit der Ersteller-Seite des Agent Gateway für ausgehenden Egress-Traffic herzustellen. Weitere Informationen zu Subnetzanforderungen und IP-Bereichsspezifikationen finden Sie unter VPC-Konnektivität konfigurieren.
# create psc network attachment
gcloud compute network-attachments create psc-na-${REGION}-agw \
--region=${REGION} \
--subnets=subnet-${REGION}-agw \
--connection-preference=ACCEPT_AUTOMATIC
PSC-Netzwerkanhang prüfen
# show psc network attachment details
gcloud compute network-attachments describe psc-na-${REGION}-agw --region=${REGION}
Rufen Sie den Ressourcen-URI des PSC-Netzwerkanhangs ab und speichern Sie ihn in der Umgebungsvariable PSC_NA_URI. Auf diesen URI wird in der Agent Gateway-Konfiguration (networkConfig.egress.networkAttachment) verwiesen, um die PSC-Schnittstelle für den ausgehenden Netzwerkverkehr in das VPC-Netzwerk bereitzustellen:
# 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}
Cloud NAT erstellen
Cloud NAT wird verwendet, um die Quell-IP-Adresse des Agent Gateway-Ausgangstraffics in die reservierte öffentliche IP-Adresse für das Routing über das öffentliche Internet zu übersetzen.
Nur Quellen aus dem Subnetz des Agent Gateway-Netzwerkanhangs für ausgehenden Traffic können Cloud NAT verwenden.
# create router for nat
gcloud compute routers create cr-nat-${SLUG}-${REGION} \
--network=vnet-${SLUG}-internal \
--asn=16550 \
--region=${REGION}
# create nat
gcloud compute routers nats create nat-${SLUG}-${REGION} \
--router=cr-nat-${SLUG}-${REGION} \
--region=${REGION} \
--nat-custom-subnet-ip-ranges="subnet-${REGION}-agw" \
--nat-external-ip-pool="ip-${SLUG}-nat" \
--enable-logging \
--log-filter=ALL
Cloud NAT prüfen
Prüfen Sie den Cloud NAT-Status und ob die erwartete natIP-Quelle konfiguriert ist:
# verify cloud nat configuration
gcloud compute routers nats describe nat-${SLUG}-${REGION} \
--router=cr-nat-${SLUG}-${REGION} \
--region=${REGION} \
--format="yaml(name,natIps,subnetworks.name)"
Beispielausgabe:
name: nat-foo-us-central1
natIps:
- https://www.googleapis.com/compute/v1/projects/[PROJ_ID]/regions/us-central1/addresses/ip-foo-nat
Externes Netzwerk erstellen
Erstellen Sie ein separates, isoliertes VPC-Netzwerk zum Hosten der VM des externen MCP-Servers.
# create vpc network
gcloud compute networks create vnet-${SLUG}-external --subnet-mode=custom
# create subnet for mcp server
gcloud compute networks subnets create subnet-${REGION}-mcp \
--network=vnet-${SLUG}-external \
--range=240.240.240.0/24 \
--region=${REGION} \
--enable-private-ip-google-access
Externe Firewallregeln erstellen
Erstellen Sie zwei Firewallregeln für eingehenden Traffic im externen VPC-Netzwerk:
2001: Ermöglicht den eingehenden TCP-Port80, damit Let's Encrypt die ACME HTTP-01-Domainvalidierungsabfrage für${MCP_DOMAIN}abschließen kann.2002: Ermöglicht anfangs den eingehenden TCP-Port443von0.0.0.0/0, um die TLS-Bereitschaft und die OAuth 2.0-tokeninfo-Durchsetzung über die lokale Shell zu überprüfen, bevor er streng auf${NAT_EXT_IP}/32beschränkt wird.
# create fw policy
gcloud compute network-firewall-policies create fw-policy-${SLUG}-external --global
# create fw policy rules
gcloud compute network-firewall-policies rules create 2001 \
--description="allow in any http" \
--firewall-policy=fw-policy-${SLUG}-external \
--global-firewall-policy \
--action=allow \
--direction=INGRESS \
--layer4-configs=tcp:80 \
--src-ip-ranges=0.0.0.0/0 \
--dest-ip-ranges=240.240.240.0/24 \
--enable-logging
gcloud compute network-firewall-policies rules create 2002 \
--description="allow in any https" \
--firewall-policy=fw-policy-${SLUG}-external \
--global-firewall-policy \
--action=allow \
--direction=INGRESS \
--layer4-configs=tcp:443 \
--src-ip-ranges=0.0.0.0/0 \
--dest-ip-ranges=240.240.240.0/24 \
--enable-logging
# bind fw policy to network
gcloud compute network-firewall-policies associations create \
--name=fw-policy-bind-${SLUG}-external \
--firewall-policy=fw-policy-${SLUG}-external \
--network=vnet-${SLUG}-external \
--global-firewall-policy
Damit ist der Netzwerkteil abgeschlossen. Fahren Sie mit dem Abschnitt Agent Gateway fort.
5. Agent Gateway
In diesem Abschnitt stellen Sie die Agent Connectivity Template mit vpcEgress: ALL_TRAFFIC bereit, stellen das regionale Agent Gateway bereit, delegieren die Autorisierung an Identity-Aware Proxy (IAP) und definieren IAM Unified Access Policy-Regeln, um ausgehende Netzwerkanfragen zu steuern.
Konnektivitätsvorlage erstellen
Die Spezifikation der Konnektivitätsvorlage definiert:
egressNetworkConfig.networkAttachment:Verweist auf die PSC-Netzwerkverbindung, die das Agent Gateway mit Ihrem VPC-Netzwerk verbindet.egressNetworkConfig.vpcEgress:AufALL_TRAFFICfestgelegt, damit alle ausgehenden Agent-Verbindungen (einschließlich öffentlicher MCP-Endpunkte im Internet) in das VPC-Netzwerk geleitet und über die Cloud NAT-Quell-IP-Adressübersetzung beendet werden.
Konfigurationsdatei für die Konnektivitätsvorlage erstellen und importieren:
# create connectivity template config file (vpcEgress: ALL_TRAFFIC)
cat > cfg/act-${AGW_NAME}.yaml << EOF
accessPath: AGENT_TO_ANYWHERE
name: projects/${PROJ_NO}/locations/${REGION}/agentConnectivityTemplates/act-${AGW_NAME}
deploymentModel: CENTRALIZED
egressNetworkConfig:
networkAttachment: ${PSC_NA_URI}
vpcEgress: ALL_TRAFFIC
EOF
# import connectivity template file (create template)
gcloud network-services agent-connectivity-templates import act-${AGW_NAME} \
--source="cfg/act-${AGW_NAME}.yaml" \
--location=${REGION}
KI‑Agenten-Gateway erstellen
In der Spezifikation für das Agent Gateway wird Folgendes definiert:
agentConnectivityTemplate:Verweist auf die Verbindungsvorlage, damit das Gateway die PSC-Netzwerkverbindung für die VPC-Verbindung verwenden kann.registries:Das Gateway wird mit der regionalen Agent Registry verknüpft, um katalogisierte MCP-Endpunkte und Tool-Schemas aufzulösen.
Konfigurationsdatei für das KI-Agenten-Gateway erstellen und importieren:
# create agent gateway config file
cat > cfg/${AGW_NAME}.yaml << EOF
name: ${AGW_NAME}
protocols:
- MCP
googleManaged:
governedAccessPath: AGENT_TO_ANYWHERE
agentConnectivityTemplate: projects/${PROJ_NO}/locations/${REGION}/agentConnectivityTemplates/act-${AGW_NAME}
registries:
- "//agentregistry.googleapis.com/projects/${PROJ_ID}/locations/${REGION}"
EOF
# import agent gateway config file (create gateway)
gcloud network-services agent-gateways import ${AGW_NAME} \
--source="cfg/${AGW_NAME}.yaml" \
--location=${REGION}
Agent Gateway-Bereitstellung überprüfen
Prüfen Sie die Konfiguration der Agent-Registrierung und der Konnektivitätsvorlage:
# verify agent gateway deployment details
gcloud network-services agent-gateways describe ${AGW_NAME} \
--location=${REGION} \
--format="yaml(name,agentConnectivityTemplate,registries)"
Beispielausgabe:
agentConnectivityTemplate: projects/[PROJ_NO]/locations/us-central1/agentConnectivityTemplates/act-foo-us-central1
name: projects/[PROJ_ID]/locations/us-central1/agentGateways/agw-foo-us-central1-ata
registries:
- //agentregistry.googleapis.com/projects/[PROJ_ID]/locations/us-central1
Prüfen Sie den PSC-Netzwerkanhang, um die Gateway-Verbindung zu bestätigen:
# show psc network attachment details
gcloud compute network-attachments describe psc-na-${REGION}-agw \
--region=${REGION} \
--format="yaml(connectionEndpoints)"
Beispielausgabe:
connectionEndpoints:
- ipAddress: 10.10.10.2
projectIdOrNum: '[TENANT_PROJ_NO]'
status: ACCEPTED
subnetwork: https://www.googleapis.com/compute/v1/projects/[PROJ_ID]/regions/us-central1/subnetworks/subnet-us-central1-agw
Autorisierung delegieren
Agent Gateway schützt und steuert ausgehenden Tool-Traffic mithilfe von Autorisierungsrichtlinien (networksecurity.authzPolicies), die in Identity-Aware Proxy (IAP) Unified Access Policies (UAP) eingebunden sind.
Agent Gateway unterstützt zwar grundlegende Inline-ALLOW- und DENY-Regeln, in Unternehmensumgebungen ist jedoch eine zentrale, identitätsbezogene Verwaltung erforderlich. Mit einheitlichen IAM-Zugriffsrichtlinien (oder Zugriffsrichtlinien) verwalten Sie Egress-Zugriffsregeln mit standardmäßigen IAM v3-Zugriffsrichtlinien.
Abbildung 3. Autorisierungsarchitektur
Der Autorisierungsablauf verbindet drei Komponenten:
- Richtlinie zur Gateway-Autorisierung (
authzPolicy):- Eine regionale Ressource, die auf das Agent Gateway ausgerichtet ist.
- Konfiguriert mit
policyProfile: REQUEST_AUTHZundaction: CUSTOM, um alle ausgehenden Autorisierungsprüfungen an die IAP-Autorisierungserweiterung weiterzuleiten.
- IAP-Diensterweiterung (
authzExtension):- Eine regionale Ressource, die die Autorisierung von Anfragen an Identity-Aware Proxy (
iap.googleapis.com) delegiert. - Bewertet Richtlinien im
ENFORCE-Modus mit der RichtlinienversionV2.
- Eine regionale Ressource, die die Autorisierung von Anfragen an Identity-Aware Proxy (
- IAM Unified Access Policy and Binding (
accessPolicy&policyBinding):- Globale IAM v3-Ressourcen mit detaillierten Zugriffsregeln.
- Authentifiziert die SPIFFE-Identität des aufrufenden Agents, prüft die universelle Berechtigung
iap.googleapis.com/resources.egressViaIAPund wertet CEL-Bedingungen (Common Expression Language) anhand von Zielattributen aus.
Autorisierungserweiterung bereitstellen
# 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 authz extension config file (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}
Autorisierungserweiterung überprüfen
Prüfen Sie, ob die Autorisierungserweiterung aktiv ist:
# list authz extensions
gcloud service-extensions authz-extensions list \
--location=${REGION} \
--format="table(
name.basename():label=NAME,
createTime.date(tz=LOCAL):label=CREATED,
service:label=SERVICE,
metadata:label=METADATA,
timeout:label=TIMEOUT
)"
Autorisierungsrichtlinie bereitstellen
Erstellen Sie eine network-security-Autorisierungsrichtlinienkonfiguration, die auf Agent Gateway ausgerichtet ist und die Anfrageüberprüfung an die Autorisierungserweiterung für IAP delegiert:
# 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}
Autorisierungsrichtlinie prüfen
Prüfen Sie, ob die Autorisierungsrichtlinie aktiv ist:
# list authz policies
gcloud network-security authz-policies list \
--location=${REGION} \
--format="table(
name.basename():label=NAME,
action:label=ACTION,
policyProfile:label=POLICY_PROFILE,
customProvider.authzExtension.resources[0].basename():label=CUSTOM_PROVIDER_RESOURCE
)"
IAM-Zugriffsrichtlinien erstellen
Agent Gateway delegiert Autorisierungsprüfungen jetzt an IAP und löst Zielmetadaten aus Agent Registry auf. Definieren Sie als Nächstes eine IAM Unified Access Policy-Regel, um die Ausführung ausgehender Tools zu steuern.
IAP wertet CEL-Attributausdrücke anhand der folgenden Zielattribute der Agent Registry aus:
- Registrierter Status (
destination.is_registered):- Boolescher Wert (
true/false), der angibt, ob das Ziel in der Agent Registry katalogisiert ist.
- Boolescher Wert (
- Name des MCP-Servers (
destination.agent_registry.mcp_server.name):- Kanonischer MCP-Server-Ressourcenname, der in Agent Registry registriert ist.
- MCP-Methode (
destination.agent_registry.mcp_server.method):- Die aufgerufene MCP-Methode, z. B.
tools/call,tools/listoderinitialize.
- Die aufgerufene MCP-Methode, z. B.
- Tool name (
destination.agent_registry.mcp_server.tool.name):- Der Name des aufgerufenen Tools, z. B.
get_sprocket_by_idoderget_sprockets. Dies ermöglicht eine detaillierte Autorisierung auf Tool-Ebene auf registrierten MCP-Servern.
- Der Name des aufgerufenen Tools, z. B.
IAM-Zugriffsrichtlinienregel definieren
Das Manifest der IAM-Richtlinienregel gibt Folgendes an:
- Principals:Die SPIFFE-Hauptidentität, die den Gemini Enterprise-Kernassistenten-Agenten repräsentiert.
- Berechtigungen:Die universelle Berechtigung
iap.googleapis.com/resources.egressViaIAPist für den gesamten ausgehenden Traffic erforderlich, der über IAP gesteuert wird. - Bedingungen:Ein CEL-Ausdruck (
destination.is_registered == true), der dafür sorgt, dass der Agent nur Endpunkte aufrufen kann, die in der Agent Registry katalogisiert sind.
Manifestdatei für die Richtlinienregel erstellen:
# create access policy rule file
cat > cfg/uap-policy-${SLUG}-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
IAM-Zugriffsrichtlinie bereitstellen
Erstellen Sie die globale IAM-Zugriffsrichtlinie mit den in der Manifestdatei definierten Regeln:
# create iam access policy
gcloud iam access-policies create uap-policy-${SLUG} \
--details-rules=cfg/uap-policy-${SLUG}-rules.json \
--project=${PROJ_ID} \
--location=global
IAM-Zugriffsrichtlinie überprüfen
Prüfen Sie, ob die IAM-Zugriffsrichtlinie erfolgreich erstellt wurde, und sehen Sie sich die Regeldetails an:
# show iam access policy details
gcloud iam access-policies describe uap-policy-${SLUG} \
--project=${PROJ_ID} \
--location=global
Beispielausgabe:
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/app-foo-global_[EPOCH]/assistants/default_assistant/agents/default/core_assistant
name: projects/[PROJ_ID]/locations/global/accessPolicies/uap-policy-foo
IAM-Zugriffsrichtlinie an Projekt binden
Wenn Sie die Erzwingung für alle Agent-Gateways in Ihrem Projekt aktivieren möchten, erstellen Sie eine Richtlinienbindung, mit der die IAM-Zugriffsrichtlinie an die Projektressource angehängt wird:
# bind iam access policy to project resource
gcloud iam policy-bindings create uap-bind-${SLUG} \
--policy="projects/${PROJ_ID}/locations/global/accessPolicies/uap-policy-${SLUG}" \
--target-resource="//cloudresourcemanager.googleapis.com/projects/${PROJ_ID}" \
--project=${PROJ_ID} \
--location=global
IAM-Zugriffsrichtlinienbindung prüfen
Prüfen Sie, ob die aktiven Richtlinienbindungspunkte auf die richtige Richtlinie und das richtige Ziel verweisen:
# show policy binding details
gcloud iam policy-bindings describe uap-bind-${SLUG} \
--project=${PROJ_ID} \
--location=global
Damit ist der Teil zum Agent Gateway abgeschlossen. Fahren Sie mit dem Abschnitt zum MCP-Server fort.
6. MCP-Server
In diesem Abschnitt stellen Sie einen externen FastMCP-OAuth 2.0-Ressourcenserver (mcp-sprockets) bereit, der die Tools get_sprockets und get_sprocket_by_id zur Verfügung stellt. Außerdem prüfen Sie, ob er Google OAuth 2.0-Bearertokens kryptografisch anhand von https://oauth2.googleapis.com/tokeninfo validiert. Als Nächstes schränken Sie die externe Firewallregel auf die statische IP-Adresse von Cloud NAT ein.
Externen MCP-Server bereitstellen
Ein Startskript installiert Caddy und FastMCP, startet den mcp-sprockets-Server auf 127.0.0.1:8080 und konfiguriert Caddy für die Bereitstellung von HTTPS auf ${MCP_DOMAIN}.
Jedes Mal, wenn Gemini Enterprise ein MCP-Tool aufruft (z. B. get_sprockets und get_sprocket_by_id), führt der Server folgende Schritte aus:
- Liest die Quell-IP des Anrufers aus dem
X-Forwarded-For-Header (egress_source_ip). - Extrahieren Sie den
Authorization: Bearer [access_token]-Header und prüfen Sie das Token anhand des Google OAuth 2.0-Bestätigungsendpunkts (https://oauth2.googleapis.com/tokeninfo?access_token=[token]). - Geben Sie
"authenticated_user"([user_email]) zusammen mit"egress_source_ip"zurück. Dies beweist, dass der externe MCP-Server sowohl die statische IP-Adresse von Cloud NAT als auch die Google OAuth 2.0-Identität des Endnutzers bestätigt hat.
# create startup script for the sprockets mcp server vm
cat > cfg/server-startup.sh << 'EOF'
#!/bin/bash
set -euo pipefail
MCP_DOMAIN=$(curl -s -H "Metadata-Flavor: Google" \
http://metadata.google.internal/computeMetadata/v1/instance/attributes/mcp-domain)
export DEBIAN_FRONTEND=noninteractive
apt-get update -y
apt-get install -y caddy python3-venv curl
mkdir -p /opt/mcp-sprockets
python3 -m venv /opt/mcp-sprockets/venv
/opt/mcp-sprockets/venv/bin/pip install --upgrade pip
/opt/mcp-sprockets/venv/bin/pip install "fastmcp>=2.14.0" "uvicorn>=0.34.0"
cat <<'PYEOF' > /opt/mcp-sprockets/main.py
import json
import urllib.parse
import urllib.request
from typing import Any, Dict
from fastmcp import FastMCP
from fastmcp.server.dependencies import get_http_headers
from mcp.types import ToolAnnotations
mcp = FastMCP("mcp-sprockets")
SPROCKETS = {
"SPK-101": {"id": "SPK-101", "model": "ANSI-40-12T", "teeth": 12, "pitch_in": 0.5, "material": "1045 Carbon Steel", "stock": 140, "unit_price": 18.50},
"SPK-102": {"id": "SPK-102", "model": "ANSI-40-24T", "teeth": 24, "pitch_in": 0.5, "material": "1045 Carbon Steel", "stock": 85, "unit_price": 29.00},
"SPK-103": {"id": "SPK-103", "model": "ANSI-60-16T", "teeth": 16, "pitch_in": 0.75, "material": "304 Stainless Steel", "stock": 60, "unit_price": 42.00},
"SPK-104": {"id": "SPK-104", "model": "ANSI-60-32T", "teeth": 32, "pitch_in": 0.75, "material": "304 Stainless Steel", "stock": 35, "unit_price": 68.00},
"SPK-105": {"id": "SPK-105", "model": "ANSI-80-20T", "teeth": 20, "pitch_in": 1.0, "material": "4140 Alloy Steel", "stock": 50, "unit_price": 95.00}
}
def verify_google_oauth_token(headers: Dict[str, str]) -> str:
token = headers.get("authorization", "")[7:].strip() if headers.get("authorization", "").lower().startswith("bearer ") else ""
if not token:
return "unauthenticated (missing Bearer token)"
url = "https://oauth2.googleapis.com/tokeninfo?" + urllib.parse.urlencode({"access_token": token})
with urllib.request.urlopen(url, timeout=5) as resp:
info = json.loads(resp.read().decode("utf-8"))
return info.get("email", info.get("sub", "verified-oauth-user"))
@mcp.tool(
description="list all sprockets in the inventory catalog",
annotations=ToolAnnotations(
readOnlyHint=True,
destructiveHint=False,
idempotentHint=True,
openWorldHint=False
)
)
def get_sprockets() -> Dict[str, Any]:
headers = get_http_headers(include_all=True)
caller_ip = headers.get("x-forwarded-for", "unknown").split(",")[0].strip()
try:
user_email = verify_google_oauth_token(headers)
except Exception as exc:
return {"egress_source_ip": caller_ip, "authenticated_user": None, "error": f"OAuth token verification failed: {exc}"}
return {
"egress_source_ip": caller_ip,
"authenticated_user": user_email,
"sprockets": list(SPROCKETS.values())
}
@mcp.tool(
description="fetch details of a specific sprocket by its ID (eg, SPK-101)",
annotations=ToolAnnotations(
readOnlyHint=True,
destructiveHint=False,
idempotentHint=True,
openWorldHint=False
)
)
def get_sprocket_by_id(sprocket_id: str) -> Dict[str, Any]:
headers = get_http_headers(include_all=True)
caller_ip = headers.get("x-forwarded-for", "unknown").split(",")[0].strip()
try:
user_email = verify_google_oauth_token(headers)
except Exception as exc:
return {"egress_source_ip": caller_ip, "authenticated_user": None, "error": f"OAuth token verification failed: {exc}"}
sprocket = SPROCKETS.get(sprocket_id.upper())
if sprocket:
return {
"egress_source_ip": caller_ip,
"authenticated_user": user_email,
"sprocket": sprocket
}
return {
"egress_source_ip": caller_ip,
"authenticated_user": user_email,
"error": f"Sprocket '{sprocket_id}' not found."
}
app = mcp.http_app(stateless_http=True)
PYEOF
cat <<'SVCEOF' > /etc/systemd/system/mcp-sprockets.service
[Unit]
Description=Sprockets FastMCP Server
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/mcp-sprockets
ExecStart=/opt/mcp-sprockets/venv/bin/uvicorn main:app --host 127.0.0.1 --port 8080 --forwarded-allow-ips="*"
Restart=always
[Install]
WantedBy=multi-user.target
SVCEOF
systemctl daemon-reload
systemctl enable --now mcp-sprockets.service
systemctl restart mcp-sprockets.service
cat <<CADDYEOF > "/etc/caddy/Caddyfile"
${MCP_DOMAIN} {
reverse_proxy 127.0.0.1:8080
}
CADDYEOF
systemctl restart caddy
EOF
# create vm instance
gcloud compute instances create vm-${MCP_NAME} \
--zone=${ZONE} \
--machine-type=e2-micro \
--image-family=debian-12 \
--image-project=debian-cloud \
--shielded-secure-boot \
--network-interface="subnet=subnet-${REGION}-mcp,address=${MCP_EXT_IP}" \
--metadata="mcp-domain=${MCP_DOMAIN}" \
--metadata-from-file="startup-script=cfg/server-startup.sh"
MCP-Serverbereitschaft und OAuth 2.0-tokeninfo-Validierung prüfen
Warten Sie einige Minuten, bis das Start-up-Script FastMCP und Caddy installiert und das Let's Encrypt-TLS-Zertifikat bereitgestellt hat.
# poll until caddy serves valid tls and fastmcp responds to tools/list
for i in $(seq 1 30); do
RESP=$(curl -s -X POST "${MCP_URL}" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc": "2.0", "id": 1, "method": "tools/list", "params": {}}' || true)
if echo "${RESP}" | grep -q "get_sprockets"; then
echo "mcp server and let's encrypt tls ready"
break
fi
echo "...waiting for mcp server and let's encrypt tls (attempt ${i}/30)..."
sleep 5
done
Prüfen Sie die DNS-Auflösung von sslip.io, das von Caddy bereitgestellte Let's Encrypt-TLS-Zertifikat und die FastMCP-tools/list-Antwort:
# query mcp server for tools list
curl -v -X POST "${MCP_URL}" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc": "2.0", "id": 1, "method": "tools/list", "params": {}}' \
2>&1 | grep -E "Connected to|subject:|issuer:|SSL certificate|HTTP/|event:|data:"
Beispielausgabe:
* Connected to mcp.203.0.113.20.sslip.io (203.0.113.20) port 443
* subject: CN=mcp.203.0.113.20.sslip.io
* issuer: C=US; O=Let's Encrypt; CN=E5
* SSL certificate verify ok.
> POST /mcp HTTP/2
< HTTP/2 200
event: message
data: {"jsonrpc":"2.0","id":1,"result":{"tools":[{"name":"get_sprockets","description":"list all sprockets in the inventory catalog","inputSchema":{"properties":{},"type":"object"},"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":true}},{"name":"get_sprocket_by_id","description":"fetch details of a specific sprocket by its ID (eg, SPK-101)","inputSchema":{"properties":{"sprocket_id":{"type":"string"}},"required":["sprocket_id"],"type":"object"},"annotations":{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":true}}]}}
Bevor Sie die externe Firewall sperren, führen Sie einen Test tools/call durch, bei dem Sie ein Google OAuth 2.0-Bearer-Token (gcloud auth print-access-token) übergeben, um zu prüfen, ob mcp-sprockets das Token anhand von https://oauth2.googleapis.com/tokeninfo validiert und Ihre "authenticated_user"-E-Mail-Adresse zusammen mit der Quell-IP-Adresse des Aufrufers zurückgibt:
# query mcp server (test tools/call with google oauth 2.0 bearer token)
curl -s -X POST "${MCP_URL}" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "get_sprocket_by_id",
"arguments": {"sprocket_id": "SPK-105"}
}
}' | sed -n 's/^data: //p' | jq '.result.structuredContent'
Beispielausgabe (mit Ihrer direkten Cloud Shell-IP-Adresse vor der Firewall-Sperrung und Ihrer bestätigten Google OAuth-E-Mail-Adresse):
{
"egress_source_ip": "198.51.100.154",
"authenticated_user": "user@example.com",
"sprocket": {
"id": "SPK-105",
"model": "ANSI-80-20T",
"teeth": 20,
"pitch_in": 1.0,
"material": "4140 Alloy Steel",
"stock": 50,
"unit_price": 95.0
}
}
Firewall auf statische Cloud NAT-IP-Adresse beschränken
Aktualisieren Sie die Firewallrichtlinie für das externe VPC-Netzwerk, damit der TCP-Port 443 Traffic nur von der statischen externen IP-Adresse von Cloud NAT (${NAT_EXT_IP}/32) akzeptiert:
# create fw policy rule allowing https only from cloud nat static ip
gcloud compute network-firewall-policies rules create 2003 \
--description="allow in any https from nat ip" \
--firewall-policy=fw-policy-${SLUG}-external \
--global-firewall-policy \
--action=allow \
--direction=INGRESS \
--layer4-configs=tcp:443 \
--src-ip-ranges="${NAT_EXT_IP}/32" \
--dest-ip-ranges=240.240.240.0/24 \
--enable-logging
# delete temporary open fw policy rules
gcloud compute network-firewall-policies rules delete 2001 \
--firewall-policy=fw-policy-${SLUG}-external \
--global-firewall-policy
gcloud compute network-firewall-policies rules delete 2002 \
--firewall-policy=fw-policy-${SLUG}-external \
--global-firewall-policy
Prüfen Sie, ob die Regeln für die externe Firewallrichtlinie vorhanden sind:
# list all rules in the global network firewall policy
gcloud compute network-firewall-policies describe fw-policy-${SLUG}-external \
--global \
--flatten="rules[]" \
--format="table(
rules.priority:label=RULE,
rules.action:label=ACTION,
rules.direction:label=DIRECTION,
firstof(
rules.match.srcIpRanges,
rules.match.srcAddressGroups,
rules.match.srcSecureTags.name
).map().sub('projects/[^/]+/(locations/global/|global/)', '').list():label=SRC,
firstof(
rules.targetForwardingRules,
rules.match.destIpRanges,
rules.targetType
).map().sub('projects/[^/]+/(locations/global/|global/)', '').list():label=DST
)"
Prüfen Sie, ob direkte Verbindungen außerhalb der statischen Cloud NAT-IP-Adresse jetzt blockiert werden:
# query mcp server
curl -i --connect-timeout 5 "${MCP_URL}" \
|| echo "Expected: Direct access blocked (not originating from ${NAT_EXT_IP})"
Beispielausgabe:
curl: (28) Connection timed out after 5001 milliseconds
Expected: Direct access blocked (not originating from 203.0.113.10)
Das war der Teil zum MCP-Server. Als Nächstes geht es mit dem Abschnitt zur Agent Registry weiter.
7. Agent Registry
Die Agent Registry ist ein zentrales Inventar aller KI-Agenten, MCP-Server und Endpunkte (APIs) im KI-Ökosystem. Außerdem ist es ein Katalog, in dem andere registrierte Tools und Dienste für die Verwendung durch KI-Anwendungen aufgeführt, gesucht und gefunden werden können. Agent Gateway verwendet das Registrierungsdatenmodell als Governance-Framework, um die Ausgaberichtlinien zu erzwingen. IAM-Rollenzuweisungen für Hauptkonten, die Agents aufrufen, werden anhand der Richtlinie geprüft, die an die Registry-Ressource gebunden ist.
In diesem Abschnitt registrieren Sie den MCP-Server und sein Tool-Schema (toolspec.json) in der Agent Registry. Damit Gemini Enterprise über Agent Gateway mit Google APIs und ‑Diensten interagieren kann, erstellen Sie außerdem einen einzelnen Registrierungsendpunktdienst (oauth2-googleapis), der die Google API-Schnittstellen angibt, die von Gemini Enterprise zum Tauschen des Autorisierungscodes gegen Tokens verwendet werden.
MCP-Server registrieren
Damit Gemini Enterprise die auf dem MCP-Server verfügbaren Tools erkennen kann, müssen Sie beim Registrieren des Dienstes in der Agent Registry eine Tool-Spezifikationsdatei (cfg/toolspec.json) angeben.
MCP-Tool-Spezifikation erstellen
# create tool spec file for the sprockets mcp server
cat <<'EOF' > cfg/toolspec.json
{
"tools": [
{
"name": "get_sprockets",
"description": "List all sprockets in the inventory catalog.",
"inputSchema": {
"type": "object",
"properties": {}
},
"isReadOnly": true,
"isDestructive": false,
"isIdempotent": true,
"isOpenWorld": false
},
{
"name": "get_sprocket_by_id",
"description": "Fetch details of a specific sprocket by its ID (e.g., SPK-101).",
"inputSchema": {
"type": "object",
"properties": {
"sprocket_id": {
"type": "string",
"description": "The sprocket identifier (e.g., SPK-101, SPK-105)."
}
},
"required": [
"sprocket_id"
]
},
"isReadOnly": true,
"isDestructive": false,
"isIdempotent": true,
"isOpenWorld": false
}
]
}
EOF
MCP-Serverdienst erstellen
# create registry service (mcp server)
gcloud agent-registry services create ${MCP_NAME} \
--project=${PROJ_ID} \
--location=${REGION} \
--display-name="${MCP_DOMAIN}" \
--description="MANDATORY SPROCKETS INVENTORY & CATALOG AGENT: You MUST \
ALWAYS invoke this tool (get_sprockets or get_sprocket_by_id) for ANY question \
about sprockets, inventory catalog listings, sprocket IDs (SPK-101 through \
SPK-105), ANSI models (ANSI-40, ANSI-60, ANSI-80), tooth counts, pitch, \
material, stock levels, unit prices, authenticated_user, or egress_source_ip \
verification. NEVER guess or fabricate inventory data yourself and NEVER \
transfer sprocket queries to file_and_coding_agent or web search. Always \
delegate every sprocket or inventory lookup to this tool." \
--mcp-server-spec-type=tool-spec \
--mcp-server-spec-content=cfg/toolspec.json \
--interfaces=protocolBinding=JSONRPC,url="${MCP_URL}"
MCP-Server in Agent Registry überprüfen
Prüfen Sie, ob der Dienst in der Region als registrierter MCP-Server aufgeführt ist, zusammen mit seiner Endpunkt-URL und den verfügbaren Tools:
# list registry regional mcp servers
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
)"
Beispielausgabe:
REGISTRY_ID DISPLAY_NAME ENDPOINT_URL TOOLS
agentregistry-00000000-0000-0000-5c39-1f6e542bb2b8 mcp.203.0.113.20.sslip.io https://mcp.203.0.113.20.sslip.io/mcp get_sprockets,get_sprocket_by_id
Sehen Sie sich die Dienstkonfigurationsspezifikation an, um zu sehen, dass sie die genauen Tool-Definitionen, Eingabeschemas und Verhaltensanmerkungen für jedes Tool registriert:
# describe mcp server tool specs
gcloud agent-registry services describe ${MCP_NAME} \
--location=${REGION} \
--project=${PROJ_ID} \
--format="yaml(mcpServerSpec.content.tools)"
OAuth-Endpunkt registrieren
Damit das Gemini Enterprise-DataConnector-Backend (das im Autorisierungsablauf als OAuth-Client fungiert) POST-Anfragen über das Agent Gateway an den Google OAuth 2.0-Autorisierungsserver (https://oauth2.googleapis.com/token) senden kann, muss der Token-Endpunkt in der Agent Registry registriert sein, damit IAP destination.is_registered == true auswerten kann.
Endpunktdienst erstellen
# create registry service (endpoint)
gcloud agent-registry services create oauth2-googleapis \
--project=${PROJ_ID} \
--location=${REGION} \
--display-name="oauth2.googleapis.com" \
--description="google oauth2 endpoint" \
--endpoint-spec-type=no-spec \
--interfaces=protocolBinding=JSONRPC,url=https://oauth2.googleapis.com
Endpunktregistrierung prüfen
# list registry regional endpoints
gcloud agent-registry endpoints list \
--project=${PROJ_ID} \
--location=${REGION} \
--flatten="interfaces[]" \
--format="table(
displayName,
name.basename():label=ENDPOINT_ID,
interfaces.url:label=URL
)"
Erwartete Ausgabe:
DISPLAY_NAME ENDPOINT_ID URL
oauth2.googleapis.com agentregistry-00000000-0000-0000-0012-3456789abcde https://oauth2.googleapis.com
IAM-Zugriffsrichtlinie
Da in der IAM-Zugriffsrichtlinie eine Zulassungsrichtlinie für jeden registrierten Dienst definiert ist, der von der Agentenidentität core_assistant der Gemini Enterprise-App angefordert wird, sind keine zusätzlichen IAM-Richtlinienbindungen für den OAuth-Tokenaustausch erforderlich.
- conditions:
iap.googleapis.com:
expression: destination.is_registered == true
description: allow ge assistant to any registered service
effect: ALLOW
Das war der Abschnitt zur Agent Registry. Weiter geht es mit Gemini Enterprise.
8. Gemini Enterprise
In diesem Abschnitt konfigurieren Sie den Identitätsanbieter, die Testlizenz und die OAuth 2.0-Clientanmeldedaten von Google Identity, erstellen eine Gemini Enterprise-App (${GE_APP_ID}), binden den ausgehenden Egress an Ihr Agent Gateway (${AGW_URI}) und verbinden den registrierten sprockets MCP-Server als OAuth 2.0-benutzerdefinierten MCP-Datenspeicher.
Gemini Enterprise-App erstellen
Bei der folgenden Methode wird die discoveryengine.googleapis.com API verwendet, um die Ressourcen und Konfiguration der Gemini Enterprise-App zu erstellen. Eine Anleitung zum Konfigurieren über die Google Cloud Console-Benutzeroberfläche finden Sie unter App erstellen.
# 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}"
},
"observabilityConfig": {
"observabilityEnabled": true,
"sensitiveLoggingEnabled": true
}
}
EOF
App-Erstellung bestätigen
# 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}"
So rufen Sie die Engine-Details auf, um die erstellte Konfiguration zu sehen:
# 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}"
Identitätsanbieter aktivieren
Aktivieren Sie Google Identity als Identitätsanbieter für die Endnutzerauthentifizierung in Ihrer Gemini Enterprise-App.
Bei der folgenden Methode wird die discoveryengine.googleapis.com API verwendet, um den Identitätsanbieter der Gemini Enterprise-App zu konfigurieren. Eine Anleitung zur Konfiguration über die Google Cloud Console-Benutzeroberfläche finden Sie unter Identitätsanbieter konfigurieren.
# 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
Identitätsanbieter bestätigen
# 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}"
Die Ausgabe "idpType": "GSUITE" entspricht dem Google-Identitätsanbieter.
(Optional) Gemini Enterprise-Testlizenz aktivieren
Wenn Sie ein Projekt mit zugewiesenen Gemini Enterprise-Lizenzen verwenden, können Sie diesen Schritt überspringen. Wenn Sie ein neues Projekt ohne Lizenz verwenden, fahren Sie mit den folgenden Schritten fort.
Erstellen Sie eine Lizenzkonfigurationsressource, um Gemini Enterprise-Nutzerplätze für 30 Tage zu autorisieren. Dadurch wird die Standardlizenz auf den neuen Testzeitraum festgelegt. Jeder Nutzer, der sich anmeldet, erhält automatisch eine Lizenz:
# 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
Prüfen, ob die Lizenz angewendet wurde
# 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}"
Prüfen Sie, ob "subscriptionTerm": "SUBSCRIPTION_TERM_ONE_MONTH" und "freeTrial": true vorhanden sind.
# 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}"
Prüfen Sie, ob ../free_trial_gemini" und "enableLicenseAutoRegister": true vorhanden sind.
OAuth 2.0-Einwilligung und ‑Anmeldedaten konfigurieren
Damit Gemini Enterprise (der OAuth 2.0-Client) ein von einem Nutzer delegiertes Google OAuth 2.0-Bearer-Token abrufen und in Ihrem Namen an den mcp-sprocketsRessourcenserver senden kann, müssen Sie den OAuth-Zustimmungsbildschirm der Google Auth Platform konfigurieren und eine OAuth 2.0-Client-ID für Webanwendungen in Ihrem Projekt erstellen.
1. OAuth-Zustimmungsbildschirm konfigurieren
Geben Sie die direkte Google Cloud Console-URL für die Google Auth Platform-Übersicht in Ihrem Projekt aus:
# print google auth platform consent screen url
echo "https://console.cloud.google.com/auth/overview?project=${PROJ_ID}"
- Öffnen Sie die URL in Ihrem Browser und klicken Sie auf Erste Schritte, falls sie noch nicht für Ihr Projekt konfiguriert ist.
- Legen Sie unter App-Informationen den App-Namen auf
mcp-sprockets-oauthfest und wählen Sie Ihre E‑Mail-Adresse (${USER_IDENTITY}) als E‑Mail-Adresse für Nutzersupport aus. Klicken Sie dann auf Weiter. - Wählen Sie unter Zielgruppe die Option Intern aus (empfohlen, wenn Ihr Konto zu einer Google Workspace-Organisation gehört) oder Extern (wenn Sie ein privates Konto verwenden). Wenn Sie Extern auswählen, fügen Sie
${USER_IDENTITY}unter **Zielgruppe – Testnutzer** hinzu. Klicken Sie dann auf Weiter. - Geben Sie unter Kontaktdaten Ihre E‑Mail-Adresse ein, akzeptieren Sie die Richtlinienvereinbarung und klicken Sie auf Erstellen.
2. OAuth 2.0-Client-ID für die Webanwendung erstellen
Geben Sie die direkte Google Cloud Console-URL für die Seite Clients aus:
# print google auth platform clients url
echo "https://console.cloud.google.com/auth/clients?project=${PROJ_ID}"
- Öffnen Sie die URL und klicken Sie auf + Client erstellen.
- Wählen Sie Webanwendung als Anwendungstyp aus und legen Sie Name auf
ge-mcp-sprockets-clientfest. - Klicken Sie das Kästchen für Dieser Client wird von einem KI-basierten Agenten verwendet an, um den OAuth-Client für KI-Agenten-Workflows festzulegen, die im Namen von Nutzern ausgeführt werden.
- Klicken Sie unter Autorisierte Weiterleitungs-URIs auf + URI hinzufügen und fügen Sie den OAuth-Callback-URI für Gemini Enterprise hinzu:
https://vertexaisearch.cloud.google.com/oauth-redirect
- Klicken Sie auf Erstellen, kopieren Sie die generierte Client-ID und den Clientschlüssel und exportieren Sie sie in Ihrer Shell-Sitzung:
Legen Sie die OAuth 2.0-Client-ID und den Clientschlüssel fest, die im vorherigen Schritt generiert wurden:
# set oauth 2.0 client id (paste in id)
export OAUTH_CLIENT_ID="SET_YOUR_OAUTH_CLIENT_ID_HERE"
# set oauth 2.0 client secret (paste in secret)
export OAUTH_CLIENT_SECRET="SET_YOUR_OAUTH_CLIENT_SECRET_HERE"
Prüfen Sie, ob die Client-ID festgelegt ist:
# print oauth 2.0 client id
echo "oauth client id: ${OAUTH_CLIENT_ID}"
An Agent Gateway binden
Wenn ausgehender Traffic von Gemini Enterprise über Agent Gateway weitergeleitet wird, wird eine zentrale Erzwingungs- und statische IP-Routinggrenze für alle Tool-Aufrufe von KI-Agenten eingerichtet:
- Zentrale Richtliniendurchsetzung:Agent Gateway fungiert als Inline-Proxy, der ausgehende Toolanfragen anhand von Autorisierungsrichtlinien auswertet, bevor der Traffic die Agent-Umgebung verlässt.
- Determinierter VPC- und Cloud NAT-Ausgang:Wenn Sie Gemini Enterprise an ein Agent Gateway binden, das mit
vpcEgress: ALL_TRAFFICkonfiguriert ist, werden Tool-Aufrufe über den PSC-Netzwerkanhang weitergeleitet und über Ihre reservierte statische Cloud NAT-IP-Adresse beendet. - Einheitliche Prüfbarkeit:Bietet zentralisiertes Anfragelogging und Audit-Trails für alle verbundenen MCP-Server.
Patchen Sie die Engine agentGatewaySetting, um Folgendes zu aktivieren:
# 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": "${AGW_URI}"
}
}
}
EOF
Agent-Gateway-Bindung überprüfen
Rufen Sie die App-Konfiguration ab, um die agentGatewaySetting-Bindung zu bestätigen:
# 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 print-access-token)" \
-H "X-Goog-User-Project: ${PROJ_ID}" \
| jq '{name: .name, displayName: .displayName, agentGatewaySetting: .agentGatewaySetting}'
Beispielausgabe:
{
"name": "projects/[PROJ_NO]/locations/global/collections/default_collection/engines/app-foo-global_[EPOCH]",
"displayName": "foo global app",
"agentGatewaySetting": {
"defaultEgressAgentGateway": {
"name": "projects/[PROJ_ID]/locations/us-central1/agentGateways/agw-foo-us-central1-ata"
}
}
}
Benutzerdefinierten MCP-Server-Datenspeicher erstellen
In diesem Abschnitt verbinden Sie den mcp-sprockets-Server mit Gemini Enterprise, indem Sie einen benutzerdefinierten OAuth 2.0-MCP-Datenspeicher erstellen, der mit Google Identity (https://accounts.google.com/o/oauth2/v2/auth und https://oauth2.googleapis.com/token) konfiguriert ist.
Mit der Discovery Engine API ist das ein zweistufiger Prozess:
- Erstellen (
:setUpDataConnector): Erstellt eine dedizierteCollection-Ressource (${MCP_NAME}-collection-%timestamp), hängt dieDataConnector(custom_mcp) anauth_type: "OAUTH"an und stellt die zugrunde liegendeDataStore(..._mcp_data) bereit. - Aktivieren (
PATCH .../dataConnector?updateMask=actionConfig): Aktiviert die Connector-Aktionslaufzeit (actionState: "ACTIVE") mithilfe der Tool-Spezifikation der Agent Registry, der Google Identity OAuth 2.0-Parameter und bindet dieDataStore(dataStoreIds) an Ihre Gemini Enterprise-Engine.
# 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_DOMAIN}" \
--format="value(name)")
echo "mcp registry name: ${MCP_REGISTRY_URI}"
echo "mcp url: ${MCP_URL}"
Daten-Connector erstellen
# create custom mcp data connector with google identity oauth 2.0 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}-collection-$(date +%s)",
"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": "OAUTH",
"instance_uri": "${MCP_URL}",
"auth_uri": "https://accounts.google.com/o/oauth2/v2/auth",
"auth_uri_params": "&access_type=offline&prompt=consent",
"token_uri": "https://oauth2.googleapis.com/token",
"client_id": "${OAUTH_CLIENT_ID}",
"client_secret": "${OAUTH_CLIENT_SECRET}",
"scopes": "openid email profile",
"client_secret_basic_override": true,
"mcp_server_source": "REGISTRY_MCP",
"registry_mcp_server_name": "${MCP_REGISTRY_URI}",
"mcp_agent_instructions": "MANDATORY SPROCKETS INVENTORY & CATALOG AGENT: Always invoke get_sprockets or get_sprocket_by_id for any question about sprockets, inventory catalog listings, sprocket IDs (SPK-101 through SPK-105), ANSI models (ANSI-40, ANSI-60, ANSI-80), tooth counts, pitch, material, stock levels, unit prices, authenticated_user, or egress_source_ip verification.",
"use_agent_gateway_egress": true,
"agent_gateway_engine": "projects/${PROJ_ID}/locations/global/collections/default_collection/engines/${GE_APP_ID}"
}
}
}
}
EOF
Erstellung des Daten-Connectors prüfen
# 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}"
Prüfen Sie, ob das Feld "registry_mcp_server_name" mit der Agent Registry-UUID für den MCP-Server ausgefüllt ist und "auth_type" OAUTH ist:
# 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, auth_type: .actionConfig.actionParams.auth_type, registry_mcp_server_name: .actionConfig.actionParams.registry_mcp_server_name}'
So rufen Sie den MCP-Serverregistrierungseintrag in der Google Cloud Console auf:
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}"
Daten-Connector aktivieren
# activate and bind data connector with google identity oauth 2.0
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": "OAUTH",
"instance_uri": "${MCP_URL}",
"auth_uri": "https://accounts.google.com/o/oauth2/v2/auth",
"auth_uri_params": "&access_type=offline&prompt=consent",
"token_uri": "https://oauth2.googleapis.com/token",
"client_id": "${OAUTH_CLIENT_ID}",
"client_secret": "${OAUTH_CLIENT_SECRET}",
"scopes": "openid email profile",
"client_secret_basic_override": true,
"mcp_server_source": "REGISTRY_MCP",
"registry_mcp_server_name": "${MCP_REGISTRY_URI}",
"mcp_agent_instructions": "MANDATORY SPROCKETS INVENTORY & CATALOG AGENT: Always invoke get_sprockets or get_sprocket_by_id for any question about sprockets, inventory catalog listings, sprocket IDs (SPK-101 through SPK-105), ANSI models (ANSI-40, ANSI-60, ANSI-80), tooth counts, pitch, material, stock levels, unit prices, authenticated_user, or egress_source_ip verification.",
"use_agent_gateway_egress": true,
"agent_gateway_engine": "projects/${PROJ_ID}/locations/global/collections/default_collection/engines/${GE_APP_ID}"
}
}
}
EOF
Verknüpfungen mit benutzerdefinierten MCP-Servern überprüfen
# 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}'
Suchen Sie nach dem verknüpften Datenspeicher "dataStoreIds": ["mcp-sprockets-collection-[EPOCH]_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, auth_type: .actionConfig.actionParams.auth_type}'
Prüfen Sie, ob "state": "ACTIVE" und "auth_type": "OAUTH" vorhanden sind.
Tool-Aktionen
Wenn Sie den mcp-sprockets-collection-Datenspeicher im Gemini Enterprise-Dashboard untersuchen, werden Sie feststellen, dass der Tab Aktionen nicht verwendet wird und die Schaltfläche ↻ Benutzerdefinierte Aktionen neu laden deaktiviert ist. Das ist ganz normal.
So rufen Sie die Seite mit den Datenspeicherdetails in der Google Cloud Console-UI auf:
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}"
Je nachdem, wie Sie einen benutzerdefinierten MCP-Server mit Gemini Enterprise verbinden, werden die Tool-Erkennung und ‑Verwaltung auf eine von zwei Arten gehandhabt:
- Direkter benutzerdefinierter MCP (
BYO_MCP-Workflow): Wenn Sie einen benutzerdefinierten MCP-Server direkt in Gemini Enterprise ohne Agent Registry konfigurieren, wird der Toolkatalog (connectorModes: ["FEDERATED", "ACTIONS"]) vom Datenspeicher selbst verwaltet. Sie müssen den Tab Aktionen öffnen, auf ↻ Benutzerdefinierte Aktionen neu laden klicken, um dastools/list-Schema abzurufen, und einzelne Tools (addundsubtract) manuell in der Benutzeroberfläche aktivieren oder deaktivieren. - Agent Registry Import (
REGISTRY_MCP-Workflow, der in diesem Codelab verwendet wird): Wenn Sie einen MCP-Server aus der Agent Registry importieren, dient die Agent Registry als maßgebliche Quelle für den MCP-Endpunkt, seine Schnittstellenmetadaten und seinen Toolkatalog (connectorModes: ["FEDERATED"]). Gemini Enterprise aktiviert die registrierten MCP-Tools automatisch zur Laufzeit über die Engine-Einstellung Agent Gateway, ohne dass Sie Aktionen in der Benutzeroberfläche des Datenspeichers manuell neu laden oder ein- und ausschalten müssen.
Damit ist der Teil zu Gemini Enterprise abgeschlossen. Weiter geht es mit dem Abschnitt Überprüfen.
9. Validieren
In diesem Abschnitt führen Sie den einmaligen Google OAuth 2.0-Nutzerzustimmungsablauf aus, rufen MCP-Tools auf dem externen mcp-sprockets-Server von Gemini Enterprise auf und prüfen, ob der externe MCP-Server sowohl Ihre reservierte statische Cloud NAT-IP-Adresse (egress_source_ip) als auch Ihre Google OAuth 2.0-Identität (authenticated_user) validiert hat.
Nutzerzugriff
Erstellen Sie die URL für die Gemini Enterprise-Webanwendung:
# 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 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}"
OAuth-Einwilligung erteilen
Bevor Sie den KI-Agenten abfragen, müssen Sie einen einmaligen OAuth 2.0-Zustimmungsablauf durchlaufen, mit dem Sie Gemini Enterprise die Berechtigung erteilen, ein Zugriffstoken für Ihre Google-Identität (${USER_IDENTITY}) abzurufen. So kann Gemini Enterprise ausgehende Tool-Aufrufe über Agent Gateway authentifizieren, damit der externe mcp-sprockets-Server Ihre Identität bei jeder Anfrage bestätigen kann.
- Öffnen Sie
${GE_APP_USER_URL}in Ihrem Browser und klicken Sie auf Erste Schritte. - Klicken Sie im Chatfeld auf das Symbol Connectors (das Puzzlesymbol) und dann neben
mcp-sprockets-collectionauf Authorize (Autorisieren). - Ein neues Fenster wird geöffnet, in dem Sie aufgefordert werden, ein Konto auszuwählen, um mit
mcp-sprockets-oauth(dem von Ihnen konfigurierten App-Namen für den OAuth-Zustimmungsbildschirm) fortzufahren. Wählen Sie dort Ihr Nutzerkonto (${USER_IDENTITY}) aus. - Prüfen Sie auf dem OAuth-Zustimmungsbildschirm von Google die angeforderten Berechtigungen, die es Google (dem Identitätsanbieter) ermöglichen, Ihre Nutzeridentität (
openid,email,profile) mitmcp-sprockets-oauthzu teilen, und klicken Sie dann auf Weiter. - Klicken Sie noch einmal auf das Symbol Connectors und prüfen Sie, ob der Schalter für
mcp-sprockets-collectionaktiviert ist. Das bedeutet, dass die Autorisierung erfolgreich war.
KI-Agentenabfragen testen
UI-Tests für den Chat mit dem Assistenten
Geben Sie die folgende Testanfrage im Chat ein:
look up sprocket SPK-105 and confirm the model, material, unit_price, authenticated_user, and egress_source_ip
Zweite Anfrage im Chat stellen:
list all sprockets in the inventory catalog and report the authenticated_user and egress_source_ip
Prüfen Sie, ob der Assistent die richtigen Antworten zurückgibt und ein interaktives Badge für die Quellenangabe von Aktionen anzeigt.
Wenn unter jeder Antwort beispielsweise „Sprocket Lookup SPK-105 (5s)Agent Gateway“ steht, wurde das Tool ausgeführt.
Prüfen Sie, ob der Assistent die Kettenradspezifikationen zusammen mit "authenticated_user" zurückgibt, die mit ${USER_IDENTITY} übereinstimmen, und "egress_source_ip", die mit Ihrem reservierten ${NAT_EXT_IP} übereinstimmen.
Assistant streamAssist API-Tests
Nachdem Ihr Nutzerkonto den OAuth 2.0-Connector autorisiert hat, können Sie die default_assistant:streamAssist API auch direkt über die CLI aufrufen und prüfen, ob der externe mcp-sprockets-Server sowohl Ihre statische Cloud NAT-IP-Adresse (${NAT_EXT_IP}) als auch Ihre bestätigte Google OAuth 2.0-Identität (${USER_IDENTITY}) zurückgibt:
Senden Sie die folgende Testanfrage:
# query engine (ge app) streamAssist
curl -s -X POST "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1alpha/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/default_collection/engines/${GE_APP_ID}/assistants/default_assistant:streamAssist" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "X-Goog-User-Project: ${PROJ_ID}" \
-H "Content-Type: application/json" \
-d @- <<EOF | jq -r '.[].answer.replies[]?.groundedContent?.content?.text // empty'
{
"query": {
"text": "look up sprocket SPK-103 and confirm the model, material, unit_price, authenticated_user, and egress_source_ip"
},
"toolsSpec": {
"vertexAiSearchSpec": {
"dataStoreSpecs": [
{
"dataStore": "projects/${PROJ_NO}/locations/${GE_LOCATION}/collections/default_collection/dataStores/${GE_COLLECTION_ID}_mcp_data"
}
]
}
}
}
EOF
Beispielausgabe:
Here are the details for sprocket SPK-103 from the inventory catalog:
- Model: ANSI-60-16T
- Material: 304 Stainless Steel
- Unit Price: $42.00
- Authenticated User (Google OAuth 2.0): user@example.com
- Egress Source IP (Cloud NAT): 203.0.113.10
Versuchen Sie es mit einer anderen Anfrage:
# query engine (ge app) streamAssist
curl -s -X POST "https://${GE_LOCATION}-discoveryengine.googleapis.com/v1alpha/projects/${PROJ_ID}/locations/${GE_LOCATION}/collections/default_collection/engines/${GE_APP_ID}/assistants/default_assistant:streamAssist" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "X-Goog-User-Project: ${PROJ_ID}" \
-H "Content-Type: application/json" \
-d @- <<EOF | jq -r '.[].answer.replies[]?.groundedContent?.content?.text // empty'
{
"query": {
"text": "find a sprocket model i can get for under \$20 and report the details, authenticated_user, and egress_source_ip"
},
"toolsSpec": {
"vertexAiSearchSpec": {
"dataStoreSpecs": [
{
"dataStore": "projects/${PROJ_NO}/locations/${GE_LOCATION}/collections/default_collection/dataStores/${GE_COLLECTION_ID}_mcp_data"
}
]
}
}
}
EOF
Logs in Cloud Logging prüfen
Prüfen Sie anhand der Logs in Cloud Logging, ob Gemini Enterprise die Tool-Aufrufe über das Agent Gateway, die PSC-Netzwerkverbindung und Cloud NAT weitergeleitet hat.
KI-Agenten-Gateway-Logs prüfen
Prüfen Sie, ob das Agent Gateway die Anfrage abgefangen, das Ziel in der Agent Registry aufgelöst, die Autorisierungsrichtlinie ausgewertet und den Tool-Aufruf weitergeleitet hat:
# show agent gateway logs
gcloud logging read \
"resource.type=networkservices.googleapis.com/Gateway
AND resource.labels.location=${REGION}" \
--project=${PROJ_ID} \
--limit=8 \
--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
)"
Beispielausgabe:
TIMESTAMP STATUS SERVER_IP MCP_METHOD TOOL AUTHZ REGISTRY_MCP
YYYY-MM-DDTHH:MM:SS.ZZZ 200 203.0.113.20:443 tools/call get_sprocket_by_id ALLOWED agentregistry-00000000-0000-0000-5c39-1f6e542bb2b8
YYYY-MM-DDTHH:MM:SS.ZZZ 200 203.0.113.20:443 tools/list ALLOWED agentregistry-00000000-0000-0000-5c39-1f6e542bb2b8
YYYY-MM-DDTHH:MM:SS.ZZZ 202 203.0.113.20:443 notifications/initialized ALLOWED agentregistry-00000000-0000-0000-5c39-1f6e542bb2b8
YYYY-MM-DDTHH:MM:SS.ZZZ 200 203.0.113.20:443 initialize ALLOWED agentregistry-00000000-0000-0000-5c39-1f6e542bb2b8
Prüfen Sie, ob die Ausgabe Folgendes enthält:
STATUS:200(erfolgreiche Ausführung) und202(notifications/initialized-Handshake).SERVER_IP:Externe MCP-Server-IP und ‑Port (${MCP_EXT_IP}:443).MCP_METHODundTOOL:Die MCP-Protokollsequenz (initialize,notifications/initialized,tools/listundtools/callmitget_sprocket_by_id).AUTHZ:ALLOWED(IAP-Autorisierung für Egress zulässig).REGISTRY_MCP:Aufgelöste Agent Registry-Ressourcen-ID (agentregistry-...).
Cloud NAT-Logs prüfen
Prüfen Sie, ob Cloud NAT die ausgehende Verbindung von der IP-Adresse des Agent Gateway-PSC-Netzwerkanhangs (10.10.10.2) zu Ihrer reservierten statischen externen IPv4-Adresse (${NAT_EXT_IP}) übersetzt hat, als die Verbindung zu ${MCP_EXT_IP}:443 hergestellt wurde:
# show cloud nat logs
gcloud logging read \
"resource.type=nat_gateway
AND resource.labels.gateway_name=nat-${SLUG}-${REGION}
AND jsonPayload.connection.dest_ip=${MCP_EXT_IP}" \
--project=${PROJ_ID} \
--limit=8 \
--format="table(
timestamp.date('', tz=LOCAL):label=TIMESTAMP,
jsonPayload.allocation_status:label=ALLOCATION_STATUS,
jsonPayload.connection.src_ip:label=SRC_IP,
jsonPayload.connection.nat_ip:label=NAT_IP,
jsonPayload.connection.dest_ip:label=DEST_IP,
jsonPayload.connection.dest_port:label=PORT
)"
Beispielausgabe:
TIMESTAMP ALLOCATION_STATUS SRC_IP NAT_IP DEST_IP PORT
YYYY-MM-DDTHH:MM:SS.ZZZ OK 10.10.10.2 203.0.113.10 203.0.113.20 443
Firewall-Logs prüfen
Prüfen Sie, ob die interne Firewallrichtlinie (fw-policy-${SLUG}-internal) ausgehenden Traffic vom Agent Gateway zum Internetziel zulässt:
# show firewall policy logs (internal)
gcloud logging read \
"logName:compute.googleapis.com%2Ffirewall
AND jsonPayload.rule_details.reference:fw-policy-${SLUG}-internal" \
--project=${PROJ_ID} \
--limit=8 \
--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.vpc.vpc_name:label=VPC_NETWORK,
jsonPayload.rule_details.reference.basename():label=POLICY,
jsonPayload.rule_details.priority:label=RULE,
jsonPayload.rule_details.direction:label=DIRECTION,
jsonPayload.disposition:label=DISPOSITION
)"
Prüfen Sie, ob die externe Firewallrichtlinie (fw-policy-${SLUG}-external) eingehenden Traffic zum MCP-Server von der öffentlichen NAT-IP-Adresse des internen Netzwerks zugelassen hat:
# show firewall policy logs (external)
gcloud logging read \
"logName:compute.googleapis.com%2Ffirewall
AND jsonPayload.rule_details.reference:fw-policy-${SLUG}-external" \
--project=${PROJ_ID} \
--limit=8 \
--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.vpc.vpc_name:label=VPC_NETWORK,
jsonPayload.rule_details.reference.basename():label=POLICY,
jsonPayload.rule_details.priority:label=RULE,
jsonPayload.rule_details.direction:label=DIRECTION,
jsonPayload.disposition:label=DISPOSITION
)"
Das war der Abschnitt zur Validierung. Weiter geht es mit dem Abschnitt Bereinigen.
10. Bereinigen
Führen Sie die folgenden Schritte aus, um die in diesem Lab erstellten Ressourcen und Konfigurationen zu löschen.
Gemini Enterprise-Komponenten entfernen
# 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"}}'
Wenn Sie die OAuth 2.0-Clientanmeldedaten (ge-mcp-sprockets-client) entfernen möchten, öffnen Sie die Seite „Google Auth Platform / Clients“ und klicken Sie neben ge-mcp-sprockets-client auf das Symbol Löschen (Papierkorb):
# print google auth platform clients url
echo "https://console.cloud.google.com/auth/clients?project=${PROJ_ID}"
MCP-Server und Agent Registry-Komponenten entfernen
# delete external mcp server vm
gcloud -q compute instances delete vm-${MCP_NAME} --zone=${ZONE}
# delete agent registry mcp service
gcloud -q agent-registry services delete ${MCP_NAME} --location=${REGION}
# delete agent registry oauth2 endpoint
gcloud -q agent-registry services delete oauth2-googleapis --location=${REGION}
KI-Agenten-Gateway-Komponenten entfernen
# delete gateway authz policy and iap service extension
gcloud -q network-security authz-policies delete ${AGW_NAME}-authz-policy-iap \
--location=${REGION}
gcloud -q service-extensions authz-extensions delete ${AGW_NAME}-svc-ext-authz-iap \
--location=${REGION}
# delete agent gateway and connectivity template
gcloud -q network-services agent-gateways delete ${AGW_NAME} \
--location=${REGION}
gcloud -q network-services agent-connectivity-templates delete act-${AGW_NAME} \
--location=${REGION}
# delete iam unified access policy binding and access policy
gcloud -q iam policy-bindings delete uap-bind-${SLUG} \
--location=global \
--project=${PROJ_ID}
gcloud -q iam access-policies delete uap-policy-${SLUG} \
--location=global \
--project=${PROJ_ID}
Firewallkomponenten entfernen
# delete network firewall policy associations
gcloud -q compute network-firewall-policies associations delete \
--name=fw-policy-bind-${SLUG}-internal \
--firewall-policy=fw-policy-${SLUG}-internal \
--global-firewall-policy
gcloud -q compute network-firewall-policies associations delete \
--name=fw-policy-bind-${SLUG}-external \
--firewall-policy=fw-policy-${SLUG}-external \
--global-firewall-policy
# delete custom firewall policy rules
gcloud -q compute network-firewall-policies rules delete 1001 \
--firewall-policy=fw-policy-${SLUG}-internal \
--global-firewall-policy
gcloud -q compute network-firewall-policies rules delete 2003 \
--firewall-policy=fw-policy-${SLUG}-external \
--global-firewall-policy
# delete network firewall policies
gcloud -q compute network-firewall-policies delete fw-policy-${SLUG}-internal \
--global
gcloud -q compute network-firewall-policies delete fw-policy-${SLUG}-external \
--global
Netzwerkkomponenten entfernen
# delete cloud nat gateway and cloud router
gcloud -q compute routers nats delete nat-${SLUG}-${REGION} \
--router=cr-nat-${SLUG}-${REGION} \
--region=${REGION}
gcloud -q compute routers delete cr-nat-${SLUG}-${REGION} \
--region=${REGION}
# delete psc network attachment
gcloud -q compute network-attachments delete psc-na-${REGION}-agw \
--region=${REGION}
# delete subnets
gcloud -q compute networks subnets delete subnet-${REGION}-agw \
--region=${REGION}
gcloud -q compute networks subnets delete subnet-${REGION}-mcp \
--region=${REGION}
# delete reserved static external ip addresses
gcloud -q compute addresses delete ip-${SLUG}-nat ip-${SLUG}-mcp \
--region=${REGION}
# delete internal and external vpc networks
gcloud -q compute networks delete \
vnet-${SLUG}-internal \
vnet-${SLUG}-external
Überschreibungen von Organisationsrichtlinien und lokale Dateien entfernen
# delete project-level organization policy overrides
for policy in \
discoveryengine.managed.disableCustomMcpServerConnector \
discoveryengine.managed.allowedEgressFqdns \
discoveryengine.managed.allowedDataSources \
iam.managed.disableAccessPolicyBinding \
compute.vmExternalIpAccess; do
gcloud -q org-policies delete ${policy} --project=${PROJ_ID} 2>/dev/null || true
done
# remove local project files
rm -rf cfg
Damit ist die Bereinigung abgeschlossen. Weiter geht es mit dem Fazit.
11. Fazit
Glückwunsch! Sie haben eine End-to-End-Architektur erstellt, die es einer Gemini Enterprise-App ermöglicht, Tools auf einem externen, durch IP-Zulassungslisten und OAuth 2.0 geschützten benutzerdefinierten MCP-Server sicher zu erkennen und aufzurufen:
- Ausgehender VPC-Traffic mit statischer IP-Adresse (
ALL_TRAFFICund Cloud NAT): Der gesamte ausgehende Agent Gateway-Traffic wurde über eine PSC-Netzwerkverbindung (10.10.10.2) weitergeleitet und internetgebundene Anfragen wurden mithilfe von Cloud NAT in eine reservierte statische externe IPv4-Adresse (${NAT_EXT_IP}) übersetzt. - OAuth 2.0-MCP-Ressourcenserver und Agent Registry:Ein externer streamfähiger HTTP-FastMCP-Server (
mcp-sprockets) wurde bereitgestellt, der durch eine strenge Quell-IP-Firewall-Zulassungsliste (${NAT_EXT_IP}/32) und die Google OAuth 2.0-tokeninfo-Bestätigung geschützt ist. Sein Endpunkt und sein Tool-Schema (get_sprocketsundget_sprocket_by_id) wurden in der Agent Registry registriert. - Gemini Enterprise – OAuth 2.0-Integration und ‑Governance:Eine Gemini Enterprise App wurde bereitgestellt, der ausgehende Tool-Traffic wurde an Agent Gateway gebunden, der registrierte MCP-Server wurde als OAuth 2.0-
REGISTRY_MCP-Daten-Connector angehängt und sowohlegress_source_ipals auchauthenticated_userwurden zusammen mit Cloud Logging-Telemetriedaten überprüft.

Cosmopup findet Codelabs einfach super!
Wie geht es weiter?
- In der Dokumentation zur Gemini Enterprise Agent Platform finden Sie Informationen zu erweiterten Funktionen und Tutorials.
- Model Armor-Schutzmaßnahmen in Agent Gateway konfigurieren, um die KI-Sicherheit zu erhöhen.
- Semantische Governance-Richtlinien können verwendet werden, um Geschäftsregeln und Compliance für Anfragen in natürlicher Sprache durchzusetzen.
Wenn Sie Kommentare, Fragen oder Korrekturen haben, können Sie uns diese gern über dieses Feedbackformular mitteilen.
Vielen Dank!