Agent Gateway-Ingress zur Agent Runtime mit Model Armor

1. Einführung

In diesem Codelab wird die Agent Gateway-Eingangssteuerung für KI-Agenten untersucht, die in der Agent Runtime gehostet werden.

Agent Gateway im Ingress-Modus (Client-zu-Agent) unterstützt die Steuerung der Kommunikation zwischen Clients – menschlichen Endnutzern, Desktop-Agents, Coding-IDEs, Peer-Agents usw. – und in Agent Runtime gehosteten Agents. In diesem Modus werden Agents vor eingehenden Prompt-Injection-Angriffen oder schädlichen Inhalten geschützt, die von Clients gesendet werden. Der gesamte eingehende Traffic wird mit Autorisierungserweiterungen und Model Armor verarbeitet, um den Netzwerkeinstiegspunkt für alle Agent-Interaktionen zu schützen.

Was Sie erstellen

  • Agent Gateway im eingehenden Modus (Client zu Agent)
  • Model Armor-Autorisierungserweiterung
  • ADK-Agent für Agent Runtime mit Agentenidentität
  • Cloud Storage-Dateidaten, die vom Agent mit MCP abgefragt werden
  • Model Armor-Vorlagen zum Prüfen von LLM-Prompts und ‑Antworten
  • Sensitive Data Protection-Vorlagen zum De-Identifizieren von Daten

figure1

Abbildung 1. Codelab-Architektur

Lerninhalte

  • Agent Gateway bereitstellen, um eingehenden Traffic an einen Agenten zu filtern
  • Model Armor-Autorisierungserweiterungen und ‑Delegierung konfigurieren
  • Benutzerdefinierte Model Armor-Vorlagen erstellen und bereitstellen
  • Benutzerdefinierte Vorlagen für Sensitive Data Protection erstellen und bereitstellen
  • LLM-Prüfrichtlinien testen und validieren

Voraussetzungen

  • Ein Google Cloud-Projekt mit aktivierter Abrechnungsfunktion
  • IAM-Berechtigungen zum Bereitstellen von Netzwerkdiensten, BigQuery-Datasets und Agent Platform-Ressourcen
  • Eine POSIX-kompatible Shell (bash oder zsh) mit installierter Google Cloud CLI (gcloud-Komponente)
  • Befehlszeilentools: git, curl, jq (JSON-Prozessor), Python 3 und uv (Python-Paketmanager)

2. Konzepte

Trafficrichtung und Gateway-Rollen

Agent Gateway fungiert als Agent-fähiger Netzwerkproxy, aber seine operative Rolle ändert sich je nach Richtung des Traffics:

  • Agent-to-anywhere-Modus (Egress):Fungiert als Outbound-Proxy. Wenn ein Agent externe Datenbanktools, MCP-Server von Drittanbietern oder APIs aufruft, verwaltet das Egress-Gateway die Dienstermittlung, das Routing, das gegenseitige TLS (mTLS), das dynamische Einfügen von OAuth-Anmeldedaten und die Zugriffssteuerung für Endpunkte.
  • Client-to-Agent-Modus (Ingress):Fungiert als Frontend-Sicherheitsgateway. Das Hauptziel besteht darin, den Eingang zur Laufzeit für die Agent-Ausführung zu schützen, indem eingehende Prompts in natürlicher Sprache abgefangen und bereinigt werden, bevor sie den Agent-Code oder die KI-Modelle erreichen.

Ingress-Pfad zur Agent Runtime

Clientanfragen, die auf einen in der Agent Runtime gehosteten Agenten ausgerichtet sind, sind für den aiplatform.googleapis.com-API-Endpunkt bestimmt.

POST https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}:query

Dieser eingehende Kommunikationsstream zum API-Endpunkt stellt den Client-zu-Agent-Eingangspfad dar.

Um diesen von Google verwalteten Ingress-Pfad zu schützen, wird Agent Gateway direkt in das Google Front End (GFE) auf der Ebene der API-Bereitstellungsinfrastruktur eingebunden. Wenn Sie einen verwalteten Agent in der Agent Runtime bereitstellen, bindet Google die Autorisierungsrichtlinie für das Ingress-Gateway nativ an eingehende Clientanfragen am Netzwerkrand.

figure2

Abbildung 2. Ingress-Governance mit Agent Gateway für Agent Runtime

Da die Überprüfung auf der Frontend-Ebene erfolgt, bevor Anfragen in die Agent Runtime gelangen, führt diese Architektur zu keinem zusätzlichen Netzwerk-Overhead oder keiner zusätzlichen internen Hop-Latenz. Die Skalierung wird automatisch von der Frontend-Infrastruktur übernommen. Sie müssen also keine internen IP-Adressen, Load Balancer oder benutzerdefinierten DNS-Routen verwalten.

Inline-Bereinigung von Bedrohungen mit Model Armor

Die Auswertung der Anmeldedaten des Aufrufers und die Durchsetzung der IAM-Zugriffssteuerung (roles/aiplatform.user) werden nativ von der aiplatform API-Hostingebene übernommen. Das Ingress-Gateway selbst führt keine Identitätsautorisierung durch, sondern konzentriert sich auf die Inhaltssicherheit mithilfe von Autorisierungserweiterungen, die mit einem CONTENT_AUTHZ-Profil konfiguriert sind. Das Gateway fungiert als Inline-Richtliniendurchsetzungspunkt und fängt die Prompts in natürlicher Sprache ab, bevor sie den Reasoning-Loop des KI-Agents oder das zugrunde liegende LLM erreichen.

Wenn ein eingehender Nutzer-Prompt im Frontend-Dienst eintrifft, initiiert das Gateway einen ext_proc-Callout (externe Verarbeitung) an den regionalen Model Armor-Autorisierungserweiterungsdienst, der den Aufruf an die Model Armor-Datenebene streamt. Model Armor fungiert als Firewall für natürliche Sprache und bewertet den Text anhand aktiver Vorlagen, um nach Sicherheitsrisiken zu suchen:

  • Indirekte Prompt Injections und Jailbreaking-Versuche
  • Schädliche URLs, toxische Sprache oder unsichere Inhalte
  • Verlust von personenidentifizierbaren Informationen (PII) und vertraulichen Daten

Wenn die Vorlage Sensitive Data Protection-Filter (SDP) enthält, führt Model Armor einen zusätzlichen gRPC-Aufruf an den Cloud SDP-Dienst aus. Cloud SDP prüft die Nutzlast anhand der angegebenen Vorlage, führt die angeforderte De-Identifizierung oder Schwärzung durch und gibt das bereinigte Ergebnis zurück, damit es sicher weitergeleitet werden kann.

Wenn ein Richtlinienverstoß oder eine nicht geschwärzte Übereinstimmung mit sensiblen Daten erkannt wird, blockiert oder schwärzt das Gateway die Nutzlast am Edge, bevor sie in die Laufzeitumgebung gelangt. Dadurch bleibt die ausgeführte KI-Agent-Anwendung geschützt und verarbeitet niemals schädliche oder nicht geschwärzte Nutzlasten.

Damit sind wir mit den Konzepten fertig. Weiter geht es mit dem Abschnitt Einrichtung.

3. Einrichtung

Erforderliche IAM-Rollen

Die folgenden Rollen sind erforderlich, um die Ressourcen in diesem Codelab zu erstellen:

Kategorie

Erforderliche IAM-Rolle (ID)

Beschreibung

API-Verwaltung

roles/serviceusage.serviceUsageAdmin

Google Cloud API-Dienste aktivieren

Netzwerk und Gateway

roles/networkservices.admin

KI-Agenten-Gateway bereitstellen

Service Extensions

roles/serviceextensions.admin

Routing-Erweiterungen konfigurieren

Netzwerksicherheit

roles/networksecurity.admin

Autorisierungsrichtlinien bereitstellen

Schutz sensibler Daten

roles/dlp.admin

SDP-Prüfungs- und De-Identifikationsvorlagen verwalten

Model Armor

roles/modelarmor.admin

Sicherheitsvorlagen erstellen und verwalten

Agent Platform

roles/aiplatform.admin

Agent Runtime-Arbeitslasten bereitstellen

Cloud Storage

roles/storage.admin

Bereitstellung und Kundendaten-Buckets verwalten

IAM-Verwaltung

roles/resourcemanager.projectIamAdmin

Berechtigungen auf Projektebene für die Agent-Identität binden

Logs und Prüfung

roles/logging.viewer

Traces und Audit-Logs prüfen

Alternativ können Sie eine allgemeine einfache Rolle wie roles/admin oder die alte Rolle roles/owner verwenden.

Auf Ihr Projekt zugreifen

In diesem Codelab wird ein einzelnes Google Cloud-Projekt verwendet. Bei den Konfigurationsschritten werden die gcloud-Befehlszeile und Linux-Shell-Befehle verwendet.

Rufen Sie zuerst die Befehlszeile Ihres Google Cloud-Projekts auf:

Projekt-ID festlegen

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"
echo ${SLUG}
echo ${REGION}
# create project vars (automatic)
export PROJ_ID=$(gcloud config list --format="value(core.project)")
export PROJ_NO=$(gcloud projects describe ${PROJ_ID} --format="value(projectNumber)")
export ORG_ID=$(gcloud projects get-ancestors ${PROJ_ID} --format="value(id)" | tail -n 1)
export USER_IDENTITY=$(gcloud config get-value account)
echo ${PROJ_ID}
echo ${PROJ_NO}
echo ${ORG_ID}
echo ${USER_IDENTITY}
# create resource vars (automatic)
export AGW_NAME="agw-${SLUG}-${REGION}-cta"
export AGW_URI="projects/${PROJ_ID}/locations/${REGION}/agentGateways/${AGW_NAME}"
export RE_AGENT_NAME="agent-crm"
export RE_AGENT_ID_SET="principalSet://agents.global.org-${ORG_ID}.system.id.goog/attribute.platformContainer/aiplatform/projects/${PROJ_NO}"
export STAGING_BUCKET="agent-staging-${PROJ_NO}"
export DATA_BUCKET="customer-data-${PROJ_NO}"
export MCP_URL="https://storage.mtls.googleapis.com/storage/mcp"
echo ${AGW_NAME}
echo ${AGW_URI}
echo ${RE_AGENT_NAME}
echo ${RE_AGENT_ID_SET}
echo ${STAGING_BUCKET}
echo ${DATA_BUCKET}
echo ${MCP_URL}
# create local dir for config files
mkdir -p cfg

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 apis (agent platform bundle, part 1)
gcloud services enable \
  agentregistry.googleapis.com \
  aiplatform.googleapis.com \
  apphub.googleapis.com \
  apptopology.googleapis.com \
  cloudapiregistry.googleapis.com \
  cloudtrace.googleapis.com \
  compute.googleapis.com \
  dataform.googleapis.com \
  iam.googleapis.com \
  iamconnectors.googleapis.com \
  iap.googleapis.com \
  logging.googleapis.com \
  modelarmor.googleapis.com \
  monitoring.googleapis.com \
  networksecurity.googleapis.com \
  networkservices.googleapis.com \
  notebooks.googleapis.com \
  observability.googleapis.com
# enable google apis (agent platform bundle, part 2)
gcloud services enable \
  securitycenter.googleapis.com \
  saasservicemgmt.googleapis.com \
  storage.googleapis.com \
  telemetry.googleapis.com \
  texttospeech.googleapis.com
# enable google apis (all the rest)
gcloud services enable \
  dlp.googleapis.com

Damit ist die Einrichtung abgeschlossen. Weiter geht es mit dem Abschnitt Gateway.

4. Gateway

Stellen Sie ein von Google verwaltetes Agent Gateway bereit, das im Client-to-Agent-Modus (CLIENT_TO_AGENT) ausgeführt wird. Anders als bei Egress-Gateways, für die Agent Registry-Zuordnungen zum Weiterleiten ausgehender Aufrufe erforderlich sind, wird das Ingress-Gateway direkt an die Frontend-Ebene gebunden, um als Inline-Durchsetzungspunkt für eingehende Prompts zu dienen, die auf Agent Runtime ausgerichtet sind.

Während Ausgangsrichtlinien auf der Gateway-Ebene oft im DRY_RUN-Modus beginnen, wird die Inhaltsverwaltung für eingehende Daten (CONTENT_AUTHZ) direkt im erzwungenen Modus bereitgestellt. Das detaillierte Audit-Logging oder die aktive Blockierung wird stattdessen vorgelagert in den einzelnen Model Armor-Vorlagen gesteuert.

Gateway erstellen

# create agent gateway config file
cat > cfg/${AGW_NAME}.yaml <<EOF
name: ${AGW_NAME}
protocols:
  - MCP
googleManaged:
  governedAccessPath: CLIENT_TO_AGENT
EOF
# import agent gateway config file (create gateway)
gcloud network-services agent-gateways import ${AGW_NAME} \
  --source="cfg/${AGW_NAME}.yaml" \
  --location=${REGION}

Gateway überprüfen

# list agent gateways (in region)
gcloud network-services agent-gateways list --location=${REGION}
# show agent gateway details (verify deployment state)
gcloud network-services agent-gateways describe ${AGW_NAME} --location=${REGION}

Damit ist der Gateway-Teil abgeschlossen. Weiter geht es mit dem Abschnitt Model Armor.

5. Model Armor

SDP-Vorlagen

Erstellen Sie eine Inspektions- und De-Identifikationsvorlage für Sensitive Data Protection (SDP), die in der Model Armor-Antwortvorlage verwendet werden soll. Bei dieser Konfiguration werden US-Sozialversicherungsnummern (SSNs) zur Schwärzung gekennzeichnet.

Prüfvorlage erstellen

Mit der Vorlage zum Prüfen werden sensible Informationen (US_SOCIAL_SECURITY_NUMBER) in den Daten identifiziert.

# create inspect template
curl -fsS -X POST "https://dlp.googleapis.com/v2/projects/${PROJ_ID}/locations/${REGION}/inspectTemplates" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "Content-Type: application/json" -H "x-goog-user-project: ${PROJ_ID}" \
  -d @- << EOF
{
  "templateId": "agw-ssn-inspect-template",
  "inspectTemplate": {
    "displayName": "ssn inspect template",
    "inspectConfig": {
      "infoTypes": [
        { "name": "US_SOCIAL_SECURITY_NUMBER" }
      ],
      "minLikelihood": "POSSIBLE"
    }
  }
}
EOF

De-Identifikationsvorlage erstellen

In der Vorlage für die De-Identifikation wird die Transformation angegeben, die auf die von der Prüfungsvorlage gefundenen Sozialversicherungsnummern angewendet werden soll. In diesem Fall wird die Sozialversicherungsnummer durch den Infotyp ersetzt.

# create de-identify template
curl -fsS -X POST "https://dlp.googleapis.com/v2/projects/${PROJ_ID}/locations/${REGION}/deidentifyTemplates" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "Content-Type: application/json" -H "x-goog-user-project: ${PROJ_ID}" \
  -d @- << EOF
{
  "templateId": "agw-ssn-redaction-template",
  "deidentifyTemplate": {
    "displayName": "SSN Redaction Template",
    "deidentifyConfig": {
      "infoTypeTransformations": {
        "transformations": [{
          "primitiveTransformation": { "replaceWithInfoTypeConfig": {} }
        }]
      }
    }
  }
}
EOF

SDP-Vorlagen prüfen

# get (describe) inspect template
curl -fsS -X GET "https://dlp.googleapis.com/v2/projects/${PROJ_ID}/locations/${REGION}/inspectTemplates" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "Content-Type: application/json" -H "x-goog-user-project: ${PROJ_ID}" | jq
# get (describe) de-identify template
curl -fsS -X GET "https://dlp.googleapis.com/v2/projects/${PROJ_ID}/locations/${REGION}/deidentifyTemplates" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "Content-Type: application/json" -H "x-goog-user-project: ${PROJ_ID}" | jq

Model Armor-Vorlagen

Der Standardendpunkt für die Model Armor API ist global (modelarmor.googleapis.com). Model Armor-Ressourcen für Vorlagen und Bewertungs-Engines sind jedoch auf bestimmte geografische Regionen beschränkt. Der Google Cloud Regional Endpoint Proxy (REP) oder regionale API-Endpunkt für Model Armor ist https://modelarmor.${LOCATION}.rep.googleapis.com/.

Wenn Sie gcloud model-armor ... ausführen, versucht die CLI standardmäßig, API-Anfragen an den globalen Standardendpunkt (https://modelarmor.googleapis.com/) zu senden. Mit einer API-Endpunktüberschreibung werden alle SDK-/CLI-HTTP-Anfragen für Model Armor direkt an die regionale rep.googleapis.com-API-Ebene weitergeleitet, auf der diese standortbezogenen Vorlagen tatsächlich erstellt, gespeichert und abgefragt werden.

API-Überschreibung festlegen

# set api endpoint override per location
gcloud config set api_endpoint_overrides/modelarmor "https://modelarmor.${REGION}.rep.googleapis.com/"

API-Überschreibung prüfen

# view api overrides on active gcloud config
gcloud config list api_endpoint_overrides/

Anfragefiltervorlage erstellen

Erstellen Sie eine Vorlage für Anfragenfilter, um Hassrede, Belästigung, sexuell eindeutige Inhalte und URI-Injection-Angriffe zu blockieren. Die Protokollierung wird aktiviert, um detaillierte Ereignisinformationen zur Richtliniendurchsetzung zu erfassen. Benutzerdefinierte Fehlercodes und ‑meldungen werden auch für den Fall konfiguriert, dass eine Anfrage blockiert wird.

# create model armor template (request)
gcloud beta model-armor templates create ${AGW_NAME}-modar-req-template \
  --project=${PROJ_ID} \
  --location=${REGION} \
  --rai-settings-filters='[
    { "filterType": "HATE_SPEECH", "confidenceLevel": "MEDIUM_AND_ABOVE" },
    { "filterType": "HARASSMENT", "confidenceLevel": "MEDIUM_AND_ABOVE" },
    { "filterType": "SEXUALLY_EXPLICIT", "confidenceLevel": "MEDIUM_AND_ABOVE" }
  ]' \
  --pi-and-jailbreak-filter-settings-enforcement=enabled \
  --pi-and-jailbreak-filter-settings-confidence-level=medium-and-above \
  --template-metadata-enforcement-type=INSPECT_AND_BLOCK \
  --malicious-uri-filter-settings-enforcement=enabled \
  --template-metadata-custom-llm-response-safety-error-code=798 \
  --template-metadata-custom-llm-response-safety-error-message="ahoy! model response blocked by content filter :(" \
  --template-metadata-custom-prompt-safety-error-code=799 \
  --template-metadata-custom-prompt-safety-error-message="ahoy! the request was blocked by ye content filter... so rephrase the prompt and try again!" \
  --template-metadata-ignore-partial-invocation-failures \
  --template-metadata-log-operations \
  --template-metadata-log-sanitize-operations

Antwortfiltervorlage erstellen

Erstellen Sie eine Antwortfiltervorlage, um dieselben Inhalte wie die Anfragefiltervorlage zu blockieren. DLP ist für den Antwortabschnitt konfiguriert, um Sozialversicherungsnummern für Nachrichten zu anonymisieren, die vom Agent an den Client zurückgegeben werden.

# create model armor template (response)
gcloud beta model-armor templates create ${AGW_NAME}-modar-resp-template \
  --project=${PROJ_ID} \
  --location=${REGION} \
  --rai-settings-filters='[
      { "filterType": "HATE_SPEECH", "confidenceLevel": "MEDIUM_AND_ABOVE" },
      { "filterType": "HARASSMENT", "confidenceLevel": "MEDIUM_AND_ABOVE" },
      { "filterType": "SEXUALLY_EXPLICIT", "confidenceLevel": "MEDIUM_AND_ABOVE" }
  ]' \
  --malicious-uri-filter-settings-enforcement=enabled \
  --advanced-config-inspect-template=projects/${PROJ_ID}/locations/${REGION}/inspectTemplates/agw-ssn-inspect-template \
  --advanced-config-deidentify-template=projects/${PROJ_ID}/locations/${REGION}/deidentifyTemplates/agw-ssn-redaction-template \
  --template-metadata-enforcement-type=INSPECT_AND_BLOCK \
  --template-metadata-custom-llm-response-safety-error-code=798 \
  --template-metadata-custom-llm-response-safety-error-message="ahoy! model response blocked by content filter :(" \
  --template-metadata-custom-prompt-safety-error-code=799 \
  --template-metadata-custom-prompt-safety-error-message="ahoy! the request was blocked by ye content filter... so rephrase the prompt and try again!" \
  --template-metadata-ignore-partial-invocation-failures \
  --template-metadata-log-operations \
  --template-metadata-log-sanitize-operations

Model Armor-Vorlagen prüfen

# list model armor templates
gcloud model-armor templates list --location=${REGION}
# show request filter template details
gcloud model-armor templates describe ${AGW_NAME}-modar-req-template --location=${REGION}
# show response filter template details
gcloud model-armor templates describe ${AGW_NAME}-modar-resp-template --location=${REGION}

IAM-Berechtigungen

Model Armor führt API-Aufrufe aus, um den Dienst „Sensitive Data Protection“ (SDP) aufzurufen. Erteilen Sie der Dienstidentität von Model Armor IAM-Berechtigungen, damit sie SDP-Vorlagen zum Prüfen und De-Identifizieren verwenden kann.

IAM-Richtlinie für Sensitive Data Protection binden

# grant dlp (sdp) user role to the model armor service identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="serviceAccount:service-${PROJ_NO}@gcp-sa-modelarmor.iam.gserviceaccount.com" \
  --role="roles/dlp.user"

IAM-Berechtigungen überprüfen

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

Damit sind wir am Ende des Model Armor-Teils. Weiter geht es mit dem Abschnitt Autorisierung.

6. Autorisierung

IAM-Berechtigungen

Wenn Sie Inline-Traffic mit Model Armor untersuchen möchten, sind für den Dienst-Agent für Dienst-Erweiterungen (DEP) explizite IAM-Bindungen erforderlich (auch für Ressourcen innerhalb desselben Projekts):

  • roles/modelarmor.calloutUser und roles/serviceusage.serviceUsageConsumer:Im Gateway-Projekt erteilt, um Inline-Prüfungsaufrufe zu ermöglichen.
  • roles/modelarmor.user:Wird für das Vorlagenprojekt gewährt, um den Zugriff auf Model Armor-Vorlagen und deren Bewertung zu ermöglichen.

IAM-Richtlinie für Model Armor binden

# grant model armor callout user role to dep (service extension) service agent
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="serviceAccount:service-${PROJ_NO}@gcp-sa-dep.iam.gserviceaccount.com" \
  --role="roles/modelarmor.calloutUser"

# grant service usage consumer role to dep (service extension) service agent
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="serviceAccount:service-${PROJ_NO}@gcp-sa-dep.iam.gserviceaccount.com" \
  --role="roles/serviceusage.serviceUsageConsumer"

# grant model armor user role to dep (service extension) service agent
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="serviceAccount:service-${PROJ_NO}@gcp-sa-dep.iam.gserviceaccount.com" \
  --role="roles/modelarmor.user"

IAM-Berechtigungen überprüfen

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

Autorisierungserweiterung

Die Konfiguration der Autorisierungserweiterung für Agent Gateway definiert die Integrationseinstellungen, die auf eingehenden und ausgehenden Nutzlast-Traffic angewendet werden. Die Konfiguration definiert den externen Verarbeitungsservice (service), der auf die regionale Model Armor API verweist, und verknüpft die spezifischen Anfrage- und Antwortvorlagen über das Metadatenfeld model_armor_settings.

Autorisierungserweiterung erstellen

# create authz extension config file (enforced mode)
cat > cfg/${AGW_NAME}-svc-ext-authz-modar.yaml <<EOF
name: ${AGW_NAME}-svc-ext-authz-modar
service: modelarmor.${REGION}.rep.googleapis.com
metadata:
  model_armor_settings: '[
    {
      "request_template_id": "projects/${PROJ_ID}/locations/${REGION}/templates/${AGW_NAME}-modar-req-template",
      "response_template_id": "projects/${PROJ_ID}/locations/${REGION}/templates/${AGW_NAME}-modar-resp-template"
    }
  ]'
failOpen: true
timeout: 5s
EOF

Autorisierungserweiterung importieren

# import authz extension file
gcloud service-extensions authz-extensions import ${AGW_NAME}-svc-ext-authz-modar \
  --source=cfg/${AGW_NAME}-svc-ext-authz-modar.yaml \
  --location=${REGION}

Autorisierungserweiterung überprüfen

# list authz extensions
gcloud service-extensions authz-extensions list --location=${REGION}
# show authz extension details
gcloud service-extensions authz-extensions describe ${AGW_NAME}-svc-ext-authz-modar \
  --location=${REGION}

Autorisierungsrichtlinie

In Autorisierungsrichtlinien wird anhand von Richtlinienprofilen der Typ der durchgeführten Auswertung bestimmt. Während anfragebasierte Profile (REQUEST_AUTHZ) HTTP-Header auswerten, wird bei dieser Konfiguration ein inhaltsbasiertes Autorisierungsprofil (CONTENT_AUTHZ) verwendet, um die Model Armor-Erweiterung für die detaillierte Nutzlastprüfung an das Gateway zu binden.

Autorisierungsrichtlinie erstellen

# create authz policy config file (attach dry-run authz extension)
cat > cfg/${AGW_NAME}-authz-policy-modar.yaml <<EOF
name: ${AGW_NAME}-authz-policy-modar
target:
  resources:
    - "projects/${PROJ_ID}/locations/${REGION}/agentGateways/${AGW_NAME}"
policyProfile: CONTENT_AUTHZ
action: CUSTOM
customProvider:
  authzExtension:
    resources:
      - "projects/${PROJ_ID}/locations/${REGION}/authzExtensions/${AGW_NAME}-svc-ext-authz-modar"
EOF

Autorisierungsrichtlinie importieren

# import authz policy config file (enable authz policy)
gcloud beta network-security authz-policies import ${AGW_NAME}-authz-policy-modar \
  --source=cfg/${AGW_NAME}-authz-policy-modar.yaml \
  --location=${REGION}

Autorisierungsrichtlinie prüfen

# list authz policies
gcloud beta network-security authz-policies list --location=${REGION}
# show authz policy details
gcloud beta network-security authz-policies describe ${AGW_NAME}-authz-policy-modar \
  --location=${REGION}

Damit ist die Autorisierung abgeschlossen. Als Nächstes geht es mit dem Abschnitt Codebase weiter.

7. Codebasis

Der Agent-Code und die für dieses Codelab verwendeten Dateidaten werden in einem Google Cloud-GitHub-Repository verwaltet. Bei den folgenden Schritten wird das Repository lokal geklont, die erforderlichen Dateien werden in die aktuelle Arbeitsverzeichnisstruktur kopiert und temporäre Dateien werden gelöscht.

Remote-Artefakte abrufen

# clone remote repository to temp local dir
git clone https://github.com/GoogleCloudPlatform/cloud-networking-solutions.git ./temp_agw_cuj_arun_ingress_modar
# copy agent runtime and endpoint definitions to working project dir
cp -r temp_agw_cuj_arun_ingress_modar/codelabs/agw-cuj-arun-ingress-modar/agent-crm ./agent-crm
# remove temporary directory
rm -rf temp_agw_cuj_arun_ingress_modar

Ein Staging-Speicher-Bucket wird von Agent Runtime verwendet, um den verpackten Agent-Anwendungscode und die zugehörigen Abhängigkeitsartefakte hochzuladen, zu erstellen und bereitzustellen.

Storage-Bucket für das Staging erstellen

# create storage bucket
gcloud storage buckets create gs://${STAGING_BUCKET} --location=${REGION}

Speicher-Bucket überprüfen

# list storage buckets
gcloud storage buckets list --format="value(storage_url)"

Damit sind wir mit dem Teil zur Codebasis abgeschlossen. Als Nächstes geht es mit dem Abschnitt GCS-Kundendaten weiter.

Kundendaten

Cloud Storage-Bucket zum Speichern von Kundendaten erstellen Der Agent liest direkt über die Standard-Google Cloud-Clientbibliothek, indem er den Cloud Storage-MCP-Endpunkt aufruft.

Storage-Bucket für Kundendaten erstellen

# create storage bucket
gcloud storage buckets create gs://${DATA_BUCKET} --location=${REGION}

Speicher-Bucket überprüfen

# list storage buckets
gcloud storage buckets list --format="value(storage_url)"

Kundendaten hochladen

# copy local data to bucket
gcloud storage cp -r ./agent-crm/data/* gs://${DATA_BUCKET}/

Kundendaten bestätigen

# list bucket objects
gcloud storage ls gs://${DATA_BUCKET}/ --long

Damit schließen wir den Abschnitt zu GCS-Kundendaten ab. Als Nächstes folgt der Abschnitt zum ADK-Agent.

8. ADK-Agent

Der agent-crm-ADK-Agent, der in der Agent Runtime bereitgestellt wird, wird im Bereitstellungsskript mit den folgenden Einstellungen konfiguriert, um in die Agent Platform eingebunden zu werden:

  • "identity_type": types.IdentityType.AGENT_IDENTITY, um eine eindeutige SPIFFE-basierte Prinzipalidentität für den Agenten bereitzustellen
  • "client_to_agent_config": {"agent_gateway": "${AGW_URI}"}, um den gesamten eingehenden Traffic für den Agenten an den Pfad für die Richtlinienauswertung und ‑durchsetzung des Agent-Gateways weiterzuleiten.

Außerdem wird dem Agent die mTLS-MCP-Server-URL für den Cloud Storage-MCP-Server und der Name des Daten-Buckets übergeben, um das GCS-MCP-Tool über eine sichere Verbindung aufzurufen.

KI-Agent bereitstellen

# deploy agent
uv --directory agent-crm run python3 deploy_agent.py \
  --project=${PROJ_ID} \
  --region=${REGION} \
  --src-dir=./agent \
  --staging-bucket=${STAGING_BUCKET} \
  --display-name="${RE_AGENT_NAME}" \
  --description="agent for customer data" \
  --mcp-server-url="${MCP_URL}" \
  --data-bucket=${DATA_BUCKET} \
  --enable-telemetry \
  --enable-agent-identity \
  --agent-gateway-ingress=${AGW_URI} \
  --allow-token-sharing

Deployment prüfen

Deployment-Vitals abrufen

# fetch agent runtime (reasoning engine) resource id
export RE_ENGINE_ID=$(curl -s -X GET "https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  | jq -r --arg name "${RE_AGENT_NAME}" '.reasoningEngines[] | select(.displayName==$name) | .name | split("/") | last')
echo ${RE_ENGINE_ID}
# fetch agent runtime (reasoning engine) agent identity
export RE_AGENT_IDENTITY=$(gcloud agent-registry agents list \
  --project=${PROJ_ID} --location=${REGION} --filter="displayName=${RE_AGENT_NAME}" \
  --format="value(attributes.'agentregistry.googleapis.com/system/RuntimeIdentity'.principal)")
echo ${RE_AGENT_IDENTITY}

Gateway-Konfiguration prüfen

# show agent runtime config details (gateway config)
curl -s -X GET "https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  | jq '{displayName: .displayName, name: .name, effectiveIdentity: .spec.effectiveIdentity, agentGatewayConfig: .spec.deploymentSpec.agentGatewayConfig}'

IAM-Berechtigungen

IAM-Richtlinien für die Identität des Agents binden

# grant mcp tool user role to agent set (all agent runtime agents in project)
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="${RE_AGENT_ID_SET}" \
  --role="roles/mcp.toolUser"
# grant storage object viewer role to agent identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="${RE_AGENT_IDENTITY}" \
  --role="roles/storage.objectViewer"

# grant aiplatform user role to agent identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="${RE_AGENT_IDENTITY}" \
  --role="roles/aiplatform.user"

# grant cloudtrace agent role to agent identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="${RE_AGENT_IDENTITY}" \
  --role="roles/cloudtrace.agent"

# grant cloud monitoring metric writer role to agent identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="${RE_AGENT_IDENTITY}" \
  --role="roles/monitoring.metricWriter"
# grant cloud logging log writer role to agent identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="${RE_AGENT_IDENTITY}" \
  --role="roles/logging.logWriter"

# grant telemetry writer role to agent identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="${RE_AGENT_IDENTITY}" \
  --role="roles/telemetry.writer"

# grant service usage consumer role to agent identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="${RE_AGENT_IDENTITY}" \
  --role="roles/serviceusage.serviceUsageConsumer"

# grant browser role to agent identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="${RE_AGENT_IDENTITY}" \
  --role="roles/browser"

IAM-Berechtigungen überprüfen

# show agent identity roles on project
gcloud projects get-iam-policy ${PROJ_ID} \
  --flatten="bindings[].members" \
  --filter="bindings.members:${RE_AGENT_IDENTITY}" \
  --format="table(bindings.members.sub('^.*locations/', 'principal://agents.[...]/locations/'):label=PRINCIPAL_IDENTITY, bindings.role:label=ROLE)"
# show agent set roles on project
gcloud projects get-iam-policy ${PROJ_ID} \
  --flatten="bindings[].members" \
  --filter="bindings.members:${RE_AGENT_ID_SET}" \
  --format="table(bindings.members.sub('^.*platformContainer/', 'principalSet://agents.[...]/'):label=PRINCIPAL_IDENTITY, bindings.role:label=ROLE)"

Damit schließen wir den Teil zum ADK-Agenten ab. Weiter geht es mit dem Abschnitt Testen.

9. Test

Abfragen über die Befehlszeile senden

Sicheren Prompt testen

# post query to agent streamQuery
curl --no-buffer -s -X POST "https://${REGION}-aiplatform.googleapis.com/v1beta1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}:streamQuery" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "Content-Type: application/json" -H "X-Goog-User-Project: ${PROJ_ID}" \
  -d @- <<EOF | jq -r --unbuffered 'if type == "array" then .[] else . end | select(.content.parts != null) | .content.parts[].text // empty'
{
  "input": {
    "message": "what are the names of our west customers?",
    "user_id": "test-user"
  }
}
EOF

Die Antwort sollte so aussehen: „Unsere Kunden im Westen sind: Bob Johnson und Alice Brown.“

Entfernungs-Trigger testen

# post query to agent streamQuery
curl --no-buffer -s -X POST "https://${REGION}-aiplatform.googleapis.com/v1beta1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}:streamQuery" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "Content-Type: application/json" -H "X-Goog-User-Project: ${PROJ_ID}" \
  -d @- <<EOF | jq -r --unbuffered 'if type == "array" then .[] else . end | select(.content.parts != null) | .content.parts[].text // empty'
{
  "input": {
    "message": "what are ssn's for bob johnson and alice brown?",
    "user_id": "test-user"
  }
}
EOF

Einen anderen sicheren Prompt testen

# post query to agent streamQuery
curl --no-buffer -s -X POST "https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}:streamQuery" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "Content-Type: application/json" -H "X-Goog-User-Project: ${PROJ_ID}" \
  -d @- <<EOF | jq -r --unbuffered 'if type == "array" then .[] else . end | select(.content.parts != null) | .content.parts[].text // empty'
{
  "input": {
    "message": "what are bob johnson's and alice brown's email addresses?",
    "user_id": "test-user"
  }
}
EOF

Audit-Logs

Trace-Logs ansehen

Wenn die Telemetrie aktiviert ist, streamt die Agent Runtime strukturierte Ereignisse, die Nutzeranfragen, Tool-Parameter, Ausführungsabläufe und Ausgaben der Modellauswahl darstellen.

# show agent runtime (reasoning engine) telemetry and trace logs
gcloud logging read \
  "logName:\"projects/${PROJ_ID}/logs/aiplatform.googleapis.com%2Freasoning_engine_stdout\" AND labels.managed-by=\"reasoning-engine\"" \
  --project=${PROJ_ID} \
  --limit=15 \
  --format="table(
    timestamp.date(format=\"%I:%M:%S %p\", tz=LOCAL):label=TIME,
    trace.basename().sub('^(.{8}).*$', '\\1'):label=TRACE_ID,
    labels.\"event.name\".scope(-1):label=EVENT,
    jsonPayload.content.role:label=ROLE,
    jsonPayload.content.parts[0].text:label=TEXT_CONTENT,
    jsonPayload.content.parts[0].function_call.name:label=TOOL_CALL
  )"

In der TRACE_ID werden die Nutzeranfrage, die Zwischenaufrufe von Tools und die Modellentscheidungen in einer einzigen Zeitachse zusammengefasst:

TIME         TRACE_ID  EVENT                  ROLE   TEXT_CONTENT                                     TOOL_CALL
HH:MM:SS PM  3070a1fd  gen_ai.choice          model  Bob Johnson's SSN is 219-45-7895.
                                                     Alice Brown's SSN is 219-45-7896.
HH:MM:SS PM  3070a1fd  gen_ai.user.message    user
HH:MM:SS PM  3070a1fd  gen_ai.user.message    model                                                   read_customer_file
HH:MM:SS PM  3070a1fd  gen_ai.user.message    user
HH:MM:SS PM  3070a1fd  gen_ai.user.message    model                                                   read_customer_file
HH:MM:SS PM  3070a1fd  gen_ai.user.message    user
HH:MM:SS PM  3070a1fd  gen_ai.user.message    model                                                   list_customer_files
HH:MM:SS PM  3070a1fd  gen_ai.user.message    user   what are ssn's for bob johnson and alice brown?
HH:MM:SS PM  3070a1fd  gen_ai.system.message
HH:MM:SS PM  3070a1fd  gen_ai.choice          model                                                   read_customer_file

Bereinigungsprotokolle von Model Armor ansehen

Diese Logs zeigen die bidirektionale Inline-Bedrohungs- und Bereinigungsanalyse in Echtzeit, die von Model Armor durchgeführt wird, während der Traffic durch das Agent Gateway fließt.

# show model armor logs
gcloud logging read \
  "logName:\"projects/${PROJ_ID}/logs/modelarmor.googleapis.com%2Fsanitize_operations\"" \
  --project=${PROJ_ID} \
  --limit=50 \
  --format="table(
    timestamp.date(format=\"%I:%M:%S %p\", tz=LOCAL):label=TIME,
    jsonPayload.sanitizationResult.sanitizationVerdict:label=VERDICT,
    jsonPayload.sanitizationInput.byteItem.byteData.decode(base64).decode(utf-8).sub('\n', ' \\\\\\\\n ').trailoff(123):label=INPUT_DATA
  )"

Beachten Sie den Logeintrag für die bereinigte und blockierte Anfrage.

TIME         VERDICT                                 INPUT_DATA
HH:MM:SS PM  MODEL_ARMOR_SANITIZATION_VERDICT_ALLOW  Bob Johnson's email address is bob.j@example.com. \n Alice Brown's email address is alice.b...
HH:MM:SS PM  MODEL_ARMOR_SANITIZATION_VERDICT_ALLOW  what are bob johnson's and alice brown's email addresses?
HH:MM:SS PM  MODEL_ARMOR_SANITIZATION_VERDICT_BLOCK  6��
HH:MM:SS PM  MODEL_ARMOR_SANITIZATION_VERDICT_ALLOW  what are ssn's for bob johnson and alice brown?
HH:MM:SS PM  MODEL_ARMOR_SANITIZATION_VERDICT_ALLOW  Our west customers are: Bob Johnson and Alice Brown.
HH:MM:SS PM  MODEL_ARMOR_SANITIZATION_VERDICT_ALLOW  what are the names of our west customers?

Das war der Testteil. Fahren Sie mit dem Abschnitt Bereinigen fort.

10. Bereinigen

# remove agent iam bindings
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_IDENTITY}" --role="roles/storage.objectViewer"
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_IDENTITY}" --role="roles/aiplatform.user"
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_IDENTITY}" --role="roles/cloudtrace.agent"
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_IDENTITY}" --role="roles/monitoring.metricWriter"

# next
# remove more agent and agent set iam bindings
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_IDENTITY}" --role="roles/logging.logWriter"
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_IDENTITY}" --role="roles/telemetry.writer"
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_IDENTITY}" --role="roles/serviceusage.serviceUsageConsumer"
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_IDENTITY}" --role="roles/browser"

# next
# remove rest of iam bindings
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_ID_SET}" --role="roles/mcp.toolUser"
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="serviceAccount:service-${PROJ_NO}@gcp-sa-modelarmor.iam.gserviceaccount.com" --role="roles/dlp.user"

# next
# delete agent runtime (reasoning engine) agent
curl -s -X DELETE "https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}?force=true" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "Content-Type: application/json"

# next
# delete storage
gcloud -q storage rm --recursive gs://${STAGING_BUCKET}
gcloud -q storage rm --recursive gs://${DATA_BUCKET}

# next
# delete authz resources
gcloud -q beta network-security authz-policies delete ${AGW_NAME}-authz-policy-modar --location=${REGION}

gcloud -q beta service-extensions authz-extensions delete ${AGW_NAME}-svc-ext-authz-modar --location=${REGION} --async

# next
# remove dep (service extensions) service agent iam bindings
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} \
  --member="serviceAccount:service-${PROJ_NO}@gcp-sa-dep.iam.gserviceaccount.com" \
  --role="roles/modelarmor.calloutUser"

gcloud -q projects remove-iam-policy-binding ${PROJ_ID} \
  --member="serviceAccount:service-${PROJ_NO}@gcp-sa-dep.iam.gserviceaccount.com" \
  --role="roles/serviceusage.serviceUsageConsumer"

gcloud -q projects remove-iam-policy-binding ${PROJ_ID} \
  --member="serviceAccount:service-${PROJ_NO}@gcp-sa-dep.iam.gserviceaccount.com" \
  --role="roles/modelarmor.user"

# next
# delete model armor templates
gcloud -q model-armor templates delete ${AGW_NAME}-modar-resp-template --location=${REGION}
gcloud -q model-armor templates delete ${AGW_NAME}-modar-req-template --location=${REGION}

# unset model armor api endpoint override
gcloud config unset api_endpoint_overrides/modelarmor

# next
# delete sdp (dlp) templates
curl -fsS -X DELETE "https://dlp.googleapis.com/v2/projects/${PROJ_ID}/locations/${REGION}/deidentifyTemplates/agw-ssn-redaction-template" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "x-goog-user-project: ${PROJ_ID}"

curl -fsS -X DELETE "https://dlp.googleapis.com/v2/projects/${PROJ_ID}/locations/${REGION}/inspectTemplates/agw-ssn-inspect-template" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "x-goog-user-project: ${PROJ_ID}"

# next
# delete agent gateway ingress
gcloud -q network-services agent-gateways delete ${AGW_NAME} --location=${REGION} --async

# end

Damit ist die Bereinigung abgeschlossen. Fahren Sie mit dem Abschnitt Zusammenfassung fort.

11. Fazit

Das wars! Sie haben das Lab erfolgreich abgeschlossen. Sie haben Agent Gateway bereitgestellt und den eingehenden Traffic zu einem KI-Agenten verwaltet.

cosmopup

Cosmopup findet Codelabs einfach toll!

Wie geht es weiter?

Wenn Sie Anmerkungen, Fragen oder Korrekturen haben, können Sie uns diese gern über dieses Feedbackformular mitteilen.

Vielen Dank!