Traffico in uscita di Agent Gateway da Agent Runtime a MCP esterno

1. Introduzione

Questo codelab esplora la governance del traffico in uscita di Agent Gateway per gli agenti AI che accedono a server Model Context Protocol (MCP) esterni ospitati al di fuori di Google Cloud.

Le app di AI, dai chatbot autonomi ai sistemi autonomi con workflow multi-agente, possono richiamare dinamicamente strumenti esterni. Fornire agli agenti un accesso controllato per eseguire query sui database, recuperare contenuti web ed eseguire azioni è essenziale per agenti sicuri e produttivi. Tuttavia, negli ambienti aziendali, proteggere l'esecuzione degli strumenti dell'agente è una sfida. Se un agente ha accesso diretto alla rete, gli attacchi di prompt injection o le allucinazioni del modello possono indurre l'agente a esfiltrare dati sensibili o a eseguire comandi distruttivi.

Per gestire gli agenti autonomi su larga scala, Agent Gateway fornisce un punto di applicazione centralizzato e zero-trust integrato direttamente nell'architettura di Agent Platform. Anziché fare affidamento su implementazioni personalizzate uniche per ogni applicazione o codice agente, Agent Gateway fornisce routing di rete, governance degli agenti e sicurezza di runtime applicata a livello di piattaforma.

Quando Agent Gateway funziona in modalità di uscita (agent-to-anywhere), funge da proxy per tutte le richieste in uscita dagli agenti configurati per utilizzare il gateway. Ogni richiesta di carico di lavoro dell'agente viene autenticata utilizzando l'identità dell'agente univoca e autorizzata utilizzando le norme di Identity-Aware Proxy (IAP). Le chiamate allo strumento MCP vengono decodificate e ispezionate dinamicamente per l'applicazione delle norme. Gli amministratori della sicurezza possono applicare in modo centralizzato autorizzazioni granulari per garantire che gli agenti possano richiamare solo endpoint e metodi approvati.

Cosa crei

  • Agent Gateway in modalità in uscita (da agente a ovunque)
  • Estensione di autorizzazione Identity-Aware Proxy (IAP)
  • Agente ADK di Agent Runtime con identità dell'agente
  • Agent Registry con endpoint API e MCP di Google
  • Connettività dello strumento MCP esterno ai set di dati pubblici di Data Commons
  • Criteri di autorizzazione con controllo dell'accesso IAM

figure1

Fig. 1 Architettura del codelab

Cosa imparerai

  • Come eseguire il deployment di Agent Gateway in una sequenza di configurazione strutturata
  • Come eseguire la transizione delle policy di autorizzazione dalla modalità dry run alla modalità di applicazione forzata
  • Come registrare gli endpoint API di Google e i server MCP nel registry dell'agente
  • Come utilizzare le norme di autorizzazione condizionale basate sugli attributi del protocollo MCP
  • Come controllare i log di Agent Gateway per convalidare la governance in uscita

Cosa serve

  • Un progetto cloud Google Cloud con la fatturazione abilitata
  • Autorizzazioni IAM per il provisioning dei servizi di rete e delle risorse di Agent Platform
  • Una shell compatibile con POSIX (bash o zsh) con Google Cloud CLI (componenti gcloud e bq) installata
  • Strumenti a riga di comando: git, curl, jq (processore JSON), Python 3 e uv (gestore pacchetti Python)
  • Una chiave API Data Commons senza costi per accedere ai set di dati di test delle query

2. Concetti

Sequenza di deployment

Questo codelab segue una sequenza di configurazione strutturata in modo che gli agenti abbiano accesso alle risorse necessarie all'inizializzazione e la connettività possa essere confermata prima di applicare le policy di accesso forzato.

Questo codelab utilizza la seguente sequenza di deployment:

  1. Avvia in modalità DRY_RUN: assicurati che le richieste dell'agente arrivino correttamente al gateway e lo attraversino (modalità solo controllo).
  2. Registra tutti i servizi:registra tutti i componenti agentici nel registro degli agenti e conferma l'accesso agli strumenti dell'agente.
  3. Crea policy di autorizzazione:crea e applica policy di autorizzazione per consentire il traffico in uscita dagli agenti a server ed endpoint MCP.
  4. Passa alla modalità ENFORCED: aggiorna il criterio di estensione dell'autorizzazione per applicare i criteri e bloccare il traffico in uscita non autorizzato.

figure2

Fig. 2 Sequenza di deployment

Topologia di routing in uscita

L'uscita di Agent Gateway (da agente a ovunque) funge da proxy in uscita centralizzato e Zero Trust per i carichi di lavoro agentici. Quando un agente effettua una richiesta a un'API o a uno strumento esterno, la richiesta in uscita viene intercettata da Agent Gateway e valutata in base alle norme di governance prima di essere indirizzata alla destinazione. In un'architettura di Google Cloud Agent Platform, Agent Gateway fornisce la connettività del piano dati a:

  • Reti private (VPC): traffico in uscita che ha come target API aziendali interne, microservizi, database ospitati all'interno di VPC privati e reti on-premise o cross-cloud raggiungibili tramite connettività ibrida.
  • Reti esterne (internet): traffico in uscita che ha come target servizi web di terze parti, API SaaS o endpoint pubblici.
  • Servizi AI e Agent Platform:traffico in uscita che ha come target API Cloud gestite, foundation model, endpoint MCP di Google (come BigQuery) e servizi di governance della piattaforma (Agent Registry e criteri IAP).

figure3

Fig. 3. Topologia di routing in uscita di Agent Gateway

Questo codelab si concentra sul traffico in uscita da un agente personalizzato su Agent Runtime che ha come target un endpoint server MCP esterno di terze parti accessibile su internet.

Ispezione del protocollo MCP

L'uscita di Agent Gateway (agent-to-anywhere) è in grado di analizzare i contenuti delle richieste MCP e valutare le norme di accesso in base agli attributi del protocollo granulare. I criteri di uscita dal server da agente a MCP possono includere condizioni, espresse in Common Expression Language (CEL), che vengono applicate in fase di runtime a ogni richiesta.

Le chiamate MCP in genere utilizzano il formato del protocollo di trasferimento JSON-RPC e il trasporto HTTP. I dettagli del metodo MCP richiamato (ad es. tools/call), il nome dello strumento di destinazione e gli eventuali argomenti sono contenuti nel payload JSON nel corpo HTTP.

L'attributo iap.googleapis.com/mcp.toolName viene estratto da Agent Gateway analizzando il corpo JSON per trovare l'identificatore dello strumento specificato nella richiesta.

Attributi come iap.googleapis.com/mcp.tool.isReadOnly e mcp.tool.isDestructive non vengono in genere inviati in ogni corpo della richiesta. Si tratta invece di annotazioni (metadati) associate allo strumento. Pertanto, quando Agent Gateway estrae toolName dal corpo, cerca la definizione dello strumento e le proprietà associate da Agent Registry, dove sono stati registrati i contenuti di toolspec.json.

figure4

Fig. 4. Ispezione MCP di Agent Gateway

Le espressioni CEL utilizzate nelle condizioni IAM di IAP utilizzano il formato standard api.getAttribute('iap.googleapis.com/ATTRIBUTE_NAME', 'DEFAULT_VALUE')== 'DESIRED_VALUE'.

Questa tabella descrive gli attributi di governance in uscita del gateway dell'agente che possono essere applicati alle richieste del server MCP:

Attributo

Metodo / posizione MCP

Descrizione

mcp.toolName

tools/call (corpo)

Identificatore dello strumento di destinazione richiesto nel payload RPC (ad es. "delete_instance")

mcp.tool.isReadOnly

Agent Registry (toolspec.json)

Indica se lo strumento è di sola lettura (non modifica il suo ambiente)

mcp.tool.isDestructive

Agent Registry (toolspec.json)

Indica se la chiamata allo strumento potrebbe comportare modifiche non reversibili o perdita di dati

mcp.tool.isIdempotent

Agent Registry (toolspec.json)

Indica se l'esecuzione ripetuta dello strumento con argomenti identici produce lo stesso stato

mcp.tool.isOpenWorld

Agent Registry (toolspec.json)

Indica se lo strumento va oltre i sistemi interni delimitati per raggiungere la rete internet pubblica illimitata

Con questo si conclude la parte sui concetti. Passiamo ora alla sezione Configurazione.

3. Configurazione

Ruoli IAM richiesti

Per creare le risorse in questo Codelab sono necessari i seguenti ruoli:

Categoria

Ruolo IAM richiesto (ID)

Descrizione

Gestione delle API

roles/serviceusage.serviceUsageAdmin

Abilita i servizi API Google Cloud

Networking e gateway

roles/networkservices.admin

Esegui il provisioning di Agent Gateway

Service Extensions

roles/serviceextensions.admin

Configurare le estensioni di routing

Sicurezza di rete

roles/networksecurity.admin

Deployment dei criteri di autorizzazione

Agent Registry

roles/agentregistry.admin

Host consentiti del catalogo

Vertex AI e agenti

roles/aiplatform.admin

Esegui il deployment dei carichi di lavoro di Agent Runtime

Criteri in uscita

roles/iap.admin

Applica le norme di roles/iap.egressor

Cloud Storage

roles/storage.admin

Gestisci i bucket di staging del deployment

Log e revisione

roles/logging.viewer

Esaminare le tracce e i log di controllo

In alternativa, utilizza un ruolo di base generico come roles/admin o un ruolo legacy come roles/owner.

Accedere al progetto

Questo codelab utilizza un singolo progetto cloud di Google. I passaggi di configurazione utilizzano i comandi della shell Linux e dell'interfaccia a riga di comando gcloud.

Inizia accedendo alla riga di comando del tuo progetto Google Cloud:

Imposta l'ID progetto

gcloud config set project SET_YOUR_PROJECT_ID_HERE

Autentica sessione

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

Imposta le variabili di ambiente della shell

# set custom var for slug (eg, "foo") and region preference
export SLUG="foo"
export REGION="us-central1"
export MREGION="us"
echo ${SLUG}
echo ${REGION}
echo ${MREGION}
# 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)
echo ${PROJ_ID}
echo ${PROJ_NO}
echo ${ORG_ID}
# create resource vars (automatic)
export AGW_NAME="agw-${SLUG}-${REGION}-ata"
export AGW_URI="projects/${PROJ_ID}/locations/${REGION}/agentGateways/${AGW_NAME}"
export RE_AGENT_NAME="agent-datacommons"
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 MCP_DISPLAY_NAME="api.datacommons.org"
export MCP_RESOURCE_NAME="${REGION}-datacommons-mcp"
export MCP_URL="https://api.datacommons.org/mcp"
echo ${AGW_NAME}
echo ${AGW_URI}
echo ${RE_AGENT_NAME}
echo ${RE_AGENT_ID_SET}
echo ${STAGING_BUCKET}
echo ${MCP_DISPLAY_NAME}
echo ${MCP_RESOURCE_NAME}
echo ${MCP_URL}
# create local dir for config files
mkdir -p cfg

Se esegui un'installazione autogestita di Google Cloud SDK (ovvero al di fuori di Cloud Shell), aggiorna i componenti all'ultima versione.

# update gcloud cli
gcloud components update

Abilitare i servizi API

# 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

Con questo si conclude la parte di configurazione… passiamo ora alla sezione Gateway.

4. Gateway

Prima di applicare i controlli dell'accesso, implementa Agent Gateway e configura la relativa estensione di autorizzazione in modalità DRY_RUN. In questo modo, le chiamate agli strumenti in uscita vengono eseguite correttamente durante la registrazione dei risultati della valutazione a fini di audit.

Agent Gateway utilizza un registro regionale per supportare le risorse di Agent Runtime regionali.

Crea gateway

# create agent gateway config file (regional registry)
cat > cfg/${AGW_NAME}.yaml << EOF
name: ${AGW_NAME}
protocols:
  - MCP
googleManaged:
  governedAccessPath: AGENT_TO_ANYWHERE
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}
# show agent gateway details (verify deployment state)
gcloud network-services agent-gateways describe ${AGW_NAME} \
  --location=${REGION}

Con questo si conclude la parte relativa al gateway. Passiamo ora alla sezione Autorizzazione.

5. Autorizzazione

L'estensione di autorizzazione di Agent Gateway per Identity-Aware Proxy (IAP) è un tipo di Service Extension utilizzata per delegare le decisioni di autorizzazione per tutte le comunicazioni di Agent Platform.

  1. Flusso di delega:quando un agente tenta di richiamare un endpoint esterno o un server MCP, indirizza la richiesta ad Agent Gateway. Anziché valutare l'accesso localmente, il gateway utilizza l'estensione di autorizzazione per inviare un callout al servizio di valutazione IAP. IAP valuta l'identità dell'agente (basata su SPIFFE) in base alla policy IAM della risorsa di destinazione nel registry degli agenti. IAP restituisce una decisione ALLOW o DENY al gateway, che inoltra il traffico o lo blocca con un codice di stato HTTP 403 Forbidden.
  2. Modalità di applicazione forzata:in modalità DRY_RUN, IAP valuta le richieste e registra le decisioni in Cloud Logging senza bloccare il traffico. In modalità ENFORCE, qualsiasi richiesta da un agente non autorizzato o a una destinazione non registrata viene immediatamente bloccata.
  3. Livello di binding:l'estensione del servizio è connessa ad Agent Gateway utilizzando una policy di autorizzazione configurata con il profilo REQUEST_AUTHZ.

Estensione autorizzazione

Crea un'estensione di autorizzazione

# create authz extension config file (dry run mode)
cat > cfg/${AGW_NAME}-svc-ext-authz-iap-dryrun.yaml << EOF
name: ${AGW_NAME}-svc-ext-authz-iap-dryrun
service: iap.googleapis.com
failOpen: true
timeout: 1s
metadata:
  iamEnforcementMode: "DRY_RUN"
  iapPolicyVersion: "V1"
EOF
# import authz extension file (create extension)
gcloud service-extensions authz-extensions import ${AGW_NAME}-svc-ext-authz-iap-dryrun \
  --source=cfg/${AGW_NAME}-svc-ext-authz-iap-dryrun.yaml \
  --location=${REGION}
# show authz extension details (verify extension state)
gcloud service-extensions authz-extensions describe ${AGW_NAME}-svc-ext-authz-iap-dryrun \
  --location=${REGION}

Norme relative alle autorizzazioni

Una policy di autorizzazione associa il fornitore di sicurezza (IAP) alla risorsa gateway di destinazione e specifica il profilo di intercettazione (REQUEST_AUTHZ).

Crea policy di autorizzazione

# create authz policy config file (attach dry-run authz extension)
cat > cfg/${AGW_NAME}-authz-policy-profile-iap.yaml << EOF
name: ${AGW_NAME}-authz-policy-profile-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-dryrun"
EOF
# import authz policy config file (enable authz policy)
gcloud beta network-security authz-policies import ${AGW_NAME}-authz-policy-profile-iap \
  --source=cfg/${AGW_NAME}-authz-policy-profile-iap.yaml \
  --location=${REGION}
# show authz policy details (verify dry run mode)
gcloud beta network-security authz-policies describe ${AGW_NAME}-authz-policy-profile-iap \
  --location=${REGION}

Con questo si conclude la parte relativa all'autorizzazione. Passiamo ora alla sezione Codebase.

6. Codebase

Il codice dell'agente e lo script di registrazione dell'endpoint utilizzati per questo codelab vengono gestiti in un repository GitHub di Google Cloud remoto. I seguenti passaggi cloneranno il repository localmente, copieranno i file necessari nella struttura della directory di lavoro corrente e poi puliranno i file temporanei.

Viene creato un bucket di gestione temporanea dell'archiviazione per consentire ad Agent Runtime di caricare, compilare ed eseguire il deployment del codice dell'applicazione dell'agente pacchettizzato e dei relativi artefatti di dipendenza.

Recuperare artefatti remoti

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

Crea bucket di staging

# create storage bucket for agent deployment artifacts
gcloud storage buckets create gs://${STAGING_BUCKET} --location=${REGION}
# verify staging bucket url
gcloud storage buckets list --format="value(storage_url)"

Con questo si conclude la parte del codebase. Passiamo ora alla sezione Registro.

7. Registro

Agent Registry è un inventario centralizzato di tutti gli agenti, i server MCP e gli endpoint (API) nell'ecosistema dell'AI. È anche un catalogo che può essere utilizzato per elencare, cercare e scoprire altri strumenti e servizi registrati da utilizzare per le applicazioni di AI. La modalità di uscita (agent-to-anywhere) di Agent Gateway utilizza il modello dei dati del registry come framework di governance per applicare il controllo dell'accesso in uscita. Le concessioni di ruoli IAM per gli agenti chiamanti dell'entità vengono controllate in base al criterio associato alla risorsa del registro.

Per eseguire il bootstrap dell'ambiente e supportare gli agenti utilizzando vari servizi e API di Google, viene utilizzato uno script per registrare rapidamente un insieme comune di endpoint API utilizzando nomi host e località di endpoints/googleapis.txt.

Registra endpoint

# run python script to register google api endpoints
python3 endpoints/register_endpoints.py \
  --multi-region=${MREGION} \
  --region=${REGION} \
  --mtls-endpoints=include

Verificare gli endpoint

# list registry regional endpoints (verify registration)
gcloud agent-registry endpoints list --location=${REGION} \
  --format="table(displayName, name.basename():label=ENDPOINT_ID, interfaces[0].url:label=URL)"

Con questo si conclude la parte relativa al registro. Passiamo ora alla sezione Data Commons.

8. Data Commons

Data Commons è un'iniziativa di Google per organizzare i set di dati pubblici e renderli disponibili e accessibili a chiunque. È un servizio senza costi e accessibile tramite una chiave API dopo aver creato un account.

Crea chiave API

Dopo aver creato un account, segui questi passaggi per ottenere una chiave API:

  • Accedi al portale API di Data Commons.
  • Fai clic sul pulsante "Le mie app" nell'angolo in alto a destra.
  • Fai clic sul pulsante "+ NUOVA APP" nell'angolo in alto a destra sotto il tuo nome utente.
  • Assegna un nome alla tua app (ad es. "Codelab Agent MCP")
  • Fai clic sul pulsante "ATTIVA" per l'API Data Commons api.datacommons.org
  • Fai clic sul pulsante "SALVA" nell'angolo in basso a destra.

Vengono create una chiave API e una chiave segreta. Fai clic sull'icona "Copia" accanto al valore della chiave per "Copia chiave API". Incolla il valore nel comando del terminale per impostare la variabile di ambiente DC_API_KEY.

# set api key env var
 export DC_API_KEY="YOUR_API_KEY_HERE"

Crea server MCP toolspec

Quando registri manualmente un server MCP, devi includere un file di specifica dello strumento. Il caricamento di un file toolspec.json elenca tutti gli strumenti resi disponibili dall'endpoint e consente ad altri utenti di scoprirli.

Lo script test_mcp.py, incluso nel codebase agent-datacommons/, genera un file toolspec.json connettendosi al server MCP di destinazione (tramite SSE o HTTP) e chiama list_tools() per recuperare tutti gli strumenti disponibili esposti dal server.

# generate toolspec for registry ingestion
uv --directory agent-datacommons run python3 test_mcp.py --toolspec=include --token="${DC_API_KEY}"

Un'occhiata all'output toolspec generato mostra gli attributi MCP che Agent Gateway può utilizzare per la valutazione e l'applicazione delle policy in uscita.

# show toolspec mcp attributes
jq '.tools[] | {name, isReadOnly, isDestructive, isIdempotent, isOpenWorld}' agent-datacommons/toolspec.json

Registra server MCP

# register mcp server
gcloud agent-registry services create ${MCP_RESOURCE_NAME} \
  --location=${REGION} \
  --display-name="${MCP_DISPLAY_NAME}" \
  --description="mcp server for data commons" \
  --mcp-server-spec-type=tool-spec \
  --mcp-server-spec-content=agent-datacommons/toolspec.json \
  --interfaces=url=${MCP_URL},protocolBinding=JSONRPC
# list registry regional mcp servers
gcloud agent-registry mcp-servers list --location=${REGION} --format="table(displayName, interfaces.url)"
# show mcp server registry details
gcloud agent-registry services describe ${MCP_RESOURCE_NAME} --location=${REGION}
# fetch mcp server registry id
export MCP_REGISTRY_ID=$(gcloud agent-registry services describe ${MCP_RESOURCE_NAME} \
  --location=${REGION} \
  --format="value(registryResource.basename())")
echo ${MCP_REGISTRY_ID}

Con questo si conclude la parte di Data Commons. Passiamo ora alla sezione Runtime.

9. Runtime

L'agente agent-datacommons ADK di cui è stato eseguito il deployment in Agent Runtime è configurato con le seguenti impostazioni nello script di deployment per l'integrazione con Agent Platform:

  • "identity_type": types.IdentityType.AGENT_IDENTITY per eseguire il provisioning di un'identità principale univoca basata su SPIFFE per l'agente
  • "agent_gateway_config": { "agent_to_anywhere_config": {"agent_gateway": } } per indirizzare tutto il traffico in uscita avviato dall'agente all'Agent Gateway per la valutazione e l'applicazione delle norme

Esegui il deployment dell'agente

# deploy agent runtime workload
uv --directory agent-datacommons 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 data commons stats" \
  --enable-telemetry \
  --enable-agent-identity \
  --agent-gateway-egress=${AGW_URI} \
  --env-var="DC_API_KEY=${DC_API_KEY}"

Recupera i parametri vitali del deployment

# fetch agent runtime resource (reasoning engine) 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 \
  --location=${REGION} --filter="displayName=${RE_AGENT_NAME}" \
  --format="value(attributes.'agentregistry.googleapis.com/system/RuntimeIdentity'.principal)")
echo ${RE_AGENT_IDENTITY}
# fetch agent registry uid for agent
export RE_AGENT_REGISTRY_ID=$(gcloud agent-registry agents list \
  --location=${REGION} \
  --filter="displayName=${RE_AGENT_NAME}" \
  --format="value(uid)")
echo ${RE_AGENT_REGISTRY_ID}

Verifica la voce del registro

# show agent resource registry details
gcloud agent-registry agents describe ${RE_AGENT_REGISTRY_ID} --location=${REGION}

10. Norme

Le norme di autorizzazione per la governance degli agenti consentono il traffico da un agente AI tramite Agent Gateway e fino alla destinazione (ad es. un endpoint server MCP di terze parti per un'applicazione SaaS). Una volta che il traffico raggiunge la destinazione, le autorizzazioni regolari a livello di servizio o applicazione autorizzano l'accesso ai dati.

Le concessioni di ruoli IAM per l'uscita del gateway dell'agente consentono policy di accesso che consentono all'identità principale dell'agente di accedere alle risorse di destinazione registrate tramite il gateway dell'agente. Le policy vengono applicate a livello di Agent Gateway e convalidate utilizzando le policy IAM di Identity-Aware Proxy (IAP).

Concedi ruoli IAM dell'agente per l'uscita del gateway dell'agente

Agent Gateway controlla le richieste in entrata per convalidare che l'identità dell'agente chiamante disponga dell'autorizzazione iap.webServiceVersions.egressViaIAP (concessa dal ruolo roles/iap.egressor) sulla risorsa di destinazione.

La concessione di roles/iap.egressor all'identità dell'agente o al set di entità di Agent Runtime sulla risorsa di destinazione selezionata consente questo traffico in uscita. In questo codelab, il ruolo viene applicato all'entità agente, che concede l'autorizzazione all'identità dell'agente Agent Runtime specifica.

I criteri IAM sono associati alle risorse di destinazione come definito nel modello dei dati del registro agenti. La risorsa iap_web/agentRegistry rappresenta un livello "a livello di registro" nella gerarchia IAM. Dove agentRegistry funge da genitore per le singole risorse secondarie per agents, mcpServers e endpoints. In questo codelab, la policy IAM è associata ai livelli mcpServer ed endpoint, il che applica l'autorizzazione alle risorse secondarie specifiche.

Informazioni sul filtro MCP condizionale

Il server MCP di Data Commons ha due strumenti:

  • search_indicators: per domande su quali dati sono disponibili, sulla ricerca di variabili o sulla comprensione della copertura dei dati
  • get_observations: per le query per recuperare punti dati o serie temporali specifici

Esistono alcune operazioni MCP standard da tenere presenti quando configuri criteri di governance condizionali sui server MCP. Prima che un cliente MCP possa effettuare una tools/call per search_indicators o get_observations, deve prima inviare richieste di handshake e rilevamento del protocollo:

  • initialize
  • notifications/initialized
  • tools/list

Per dimostrare il filtro dei criteri condizionali, i criteri verranno configurati per queste condizioni:

Tabella. Valutazione delle norme per le richieste MCP

Richiesta / Metodo

Valore mcp.toolName

Valutazione CEL

Risultato

initialize

""

"" in ['search_indicators', '']

✅ CONSENTITO (200)

tools/list

""

"" in ['search_indicators', '']

✅ CONSENTITO (200)

search_indicators

"search_indicators"

"search_indicators" in [...]

✅ CONSENTITO (200)

get_observations

"get_observations"

"get_observations" in [...]

❌ DENIED (403)

Per consentire gli handshake del protocollo e la chiamata allo strumento search_indicators, la regola dei criteri condizionali include un'autorizzazione per "search_indicators" o "" (stringa vuota).

Configura il criterio IAM del server MCP IAP del registry

# show iap iam policy for mcp server
gcloud beta iap web get-iam-policy \
  --region=${REGION} \
  --resource-type=agent-registry \
  --mcp-server=${MCP_REGISTRY_ID}

NOTA: etag: deve restituire il valore predefinito ACAB poiché non sono ancora state definite norme.

# fetch active etag on policy for mcp server
export IAP_ETAG=$(gcloud beta iap web get-iam-policy \
  --resource-type=agent-registry --region=${REGION} \
  --mcp-server=${MCP_REGISTRY_ID} --format="value(etag)")
echo ${IAP_ETAG}
# create policy config file
cat > cfg/iap-policy-dc-agent-to-dc-mcp-tool-1.json << EOF
{
  "bindings": [
    {
      "role": "roles/iap.egressor",
      "members": [
        "${RE_AGENT_IDENTITY}"
      ],
      "condition": {
        "title": "allow ${RE_AGENT_NAME} to use search_indicators tool for ${MCP_DISPLAY_NAME}",
        "expression": "api.getAttribute('iap.googleapis.com/mcp.toolName', '') in ['search_indicators', '']"
      }
    }
  ],
  "etag": "${IAP_ETAG}",
  "version": 3
}
EOF
# import policy file (bind iam policy)
gcloud beta iap web set-iam-policy cfg/iap-policy-dc-agent-to-dc-mcp-tool-1.json \
  --resource-type=agent-registry \
  --mcp-server=${MCP_REGISTRY_ID} \
  --region=${REGION}
# verify iap iam policy for mcp server
gcloud beta iap web get-iam-policy \
  --region=${REGION} \
  --resource-type=agent-registry \
  --mcp-server=${MCP_REGISTRY_ID}

Con questo si conclude la parte relativa alle norme. Passiamo ora alla sezione Audit.

11. Controlla

L'estensione di autorizzazione dell'Agent Gateway funziona in modalità DRY_RUN. Le richieste in uscita vengono osservate e registrate, ma non bloccate.

Testare le query dell'agente

Apri una finestra del browser nell'interfaccia utente della console Google Cloud e vai a:

  • Agent Platform → Agenti → Deployment → agent-datacommons
  • Seleziona la scheda Playground.

In alternativa, esegui l'echo di questo comando del terminale e fai clic sul link per passare all'area giochi dell'agente:

# playground
echo "https://console.cloud.google.com/agent-platform/runtimes/locations/${REGION}/agent-engines/${RE_ENGINE_ID}/playground?project=${PROJ_ID}"

Invia alcune query di test…

  • What data do you have on water quality in Zimbabwe?
  • Compare the life expectancy, economic inequality, and GDP growth for BRICS nations

Verifica che le query restituiscano risposte valide.

Analizzare gli audit log

Visualizza i log e ispeziona le valutazioni delle policy dry run.

# list unique urls with http status and iap authorization result
gcloud logging read \
  "resource.type=\"networkservices.googleapis.com/Gateway\" \
  AND httpRequest.requestUrl:*" \
  --project=${PROJ_ID} \
  --limit=200 \
  --format="value(httpRequest.status, jsonPayload.authzPolicyInfo.result, httpRequest.requestUrl)" | sort -u
200     ALLOWED https://api.datacommons.org/mcp
200     ALLOWED https://cloudresourcemanager.googleapis.com:443/google.cloud.resourcemanager.v3.Projects/GetProject
200     ALLOWED https://telemetry.googleapis.com/v1/traces
200     ALLOWED https://${REGION}-aiplatform.googleapis.com/v1beta1/projects/${PROJ_ID}/locations/${REGION}/publishers/google/models/gemini-2.5-flash:generateContent
200     ALLOWED https://${REGION}-aiplatform.googleapis.com/v1beta1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}/sessions/${RE_SESSION_ID}
200     ALLOWED https://${REGION}-aiplatform.googleapis.com/v1beta1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}/sessions/${RE_SESSION_ID}:appendEvent
200     ALLOWED https://${REGION}-aiplatform.googleapis.com/v1beta1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}/sessions/${RE_SESSION_ID}/events
202     ALLOWED https://api.datacommons.org/mcp

Aggiorna il criterio IAM degli endpoint IAP del registro

Concedi le autorizzazioni di uscita dell'agente per l'endpoint di telemetria

# set var for endpoint display name
export ENDPOINT_1_DISPLAY_NAME="telemetry.googleapis.com"
echo ${ENDPOINT_1_DISPLAY_NAME}
# fetch endpoint registry id
export ENDPOINT_1_REGISTRY_ID=$(gcloud agent-registry services list \
  --location=${REGION} \
  --filter="displayName=${ENDPOINT_1_DISPLAY_NAME}" \
  --format="value(registryResource.basename())")
echo ${ENDPOINT_1_REGISTRY_ID}
# create policy config file
cat > cfg/iap-policy-re-agent-to-ep-1.json << EOF
{
  "bindings": [
    {
      "role": "roles/iap.egressor",
      "members": [
        "${RE_AGENT_IDENTITY}"
      ]
    }
  ]
}
EOF
# import policy file (bind iam policy)
gcloud -q beta iap web set-iam-policy cfg/iap-policy-re-agent-to-ep-1.json \
  --resource-type=agent-registry \
  --endpoint=${ENDPOINT_1_REGISTRY_ID} \
  --region=${REGION}
# verify iap iam policy for telemetry endpoint
gcloud beta iap web get-iam-policy \
  --region=${REGION} \
  --resource-type=agent-registry \
  --endpoint=${ENDPOINT_1_REGISTRY_ID}

Concedi le autorizzazioni di uscita dell'agente per l'endpoint aiplatform

# set var for endpoint display name
export ENDPOINT_2_DISPLAY_NAME="${REGION}-aiplatform.googleapis.com"
echo ${ENDPOINT_2_DISPLAY_NAME}
# fetch endpoint registry id
export ENDPOINT_2_REGISTRY_ID=$(gcloud agent-registry services list \
  --location=${REGION} \
  --filter="displayName=${ENDPOINT_2_DISPLAY_NAME}" \
  --format="value(registryResource.basename())")
echo ${ENDPOINT_2_REGISTRY_ID}
# create policy config file
cat > cfg/iap-policy-re-agent-to-ep-2.json << EOF
{
  "bindings": [
    {
      "role": "roles/iap.egressor",
      "members": [
        "${RE_AGENT_IDENTITY}"
      ]
    }
  ]
}
EOF
# import policy file (bind iam policy)
gcloud -q beta iap web set-iam-policy cfg/iap-policy-re-agent-to-ep-2.json \
  --resource-type=agent-registry \
  --endpoint=${ENDPOINT_2_REGISTRY_ID} \
  --region=${REGION}
# verify iap iam policy for aiplatform endpoint
gcloud beta iap web get-iam-policy \
  --region=${REGION} \
  --resource-type=agent-registry \
  --endpoint=${ENDPOINT_2_REGISTRY_ID}

Concedi le autorizzazioni di uscita dell'agente per l'endpoint cloudresourcemanager

# set var for endpoint display name
export ENDPOINT_3_DISPLAY_NAME="cloudresourcemanager.googleapis.com"
echo ${ENDPOINT_3_DISPLAY_NAME}
# fetch endpoint registry id
export ENDPOINT_3_REGISTRY_ID=$(gcloud agent-registry services list \
  --location=${REGION} \
  --filter="displayName=${ENDPOINT_3_DISPLAY_NAME}" \
  --format="value(registryResource.basename())")
echo ${ENDPOINT_3_REGISTRY_ID}
# create policy config file
cat > cfg/iap-policy-re-agent-to-ep-3.json << EOF
{
  "bindings": [
    {
      "role": "roles/iap.egressor",
      "members": [
        "${RE_AGENT_IDENTITY}"
      ]
    }
  ]
}
EOF
# import policy file (bind iam policy)
gcloud -q beta iap web set-iam-policy cfg/iap-policy-re-agent-to-ep-3.json \
  --resource-type=agent-registry \
  --endpoint=${ENDPOINT_3_REGISTRY_ID} \
  --region=${REGION}
# verify iap iam policy for cloudresourcemanager endpoint
gcloud beta iap web get-iam-policy \
  --region=${REGION} \
  --resource-type=agent-registry \
  --endpoint=${ENDPOINT_3_REGISTRY_ID}

Con questo si conclude la parte relativa al controllo. Passiamo ora alla sezione Applica.

12. Applica

L'agente è riuscito a effettuare richieste tramite il gateway in modalità DRY_RUN. Esegui la transizione dell'estensione di autorizzazione IAP dell'Agent Gateway alla modalità ENFORCE aggiornando la policy di autorizzazione.

Aggiornamento dell'estensione autorizzazione

# create authz extension config file (enforced mode)
cat > cfg/${AGW_NAME}-svc-ext-authz-iap-enforced.yaml << EOF
name: ${AGW_NAME}-svc-ext-authz-iap-enforced
service: iap.googleapis.com
failOpen: false
timeout: 1s
metadata:
  iapPolicyVersion: "V1"
EOF
# import authz extension file (create extension)
gcloud service-extensions authz-extensions import ${AGW_NAME}-svc-ext-authz-iap-enforced \
  --source=cfg/${AGW_NAME}-svc-ext-authz-iap-enforced.yaml \
  --location=${REGION}
# list authz extensions (imported configs)
gcloud service-extensions authz-extensions list --location=${REGION}

Aggiorna policy di autorizzazione

# re-write authz policy config file (pointing to enforced authz extension)
cat > cfg/${AGW_NAME}-authz-policy-profile-iap.yaml << EOF
name: ${AGW_NAME}-authz-policy-profile-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-enforced"
EOF
# import authz policy config file (enable new authz policy)
gcloud beta network-security authz-policies import ${AGW_NAME}-authz-policy-profile-iap \
  --source=cfg/${AGW_NAME}-authz-policy-profile-iap.yaml \
  --location=${REGION}
# show authz policy details (verify enforced mode)
gcloud beta network-security authz-policies describe ${AGW_NAME}-authz-policy-profile-iap \
  --location=${REGION}

Verifica l'autorizzazione condizionale

Torna all'area giochi dell'agente nell'interfaccia utente della console.

Invia una query di test aggiuntiva (prova a richiamare lo strumento consentitosearch_indicators)...

  • What data topics do you have for Peru?

Osserva che le richieste dell'agente al modello di base Gemini (${REGION}-aiplatform.googleapis.com/...), all'API Telemetry (telemetry.googleapis.com/...) e all'endpoint del server MCP Data Commons (api.datacommons.org/mcp) vengono trasmesse con codici di stato HTTP 200 OK.

# show gateway logs for http requests
gcloud logging read \
  "resource.type=\"networkservices.googleapis.com/Gateway\" \
  AND httpRequest.requestUrl:*" \
  --project=${PROJ_ID} \
  --limit=10 \
  --format="table(
    timestamp.date(tz=LOCAL):label=TIMESTAMP,
    httpRequest.requestMethod:label=METHOD,
    httpRequest.status:label=STATUS,
    jsonPayload.authzPolicyInfo.result:label=IAP_AUTHZ,
    jsonPayload.agentGatewayInfo.mcpInfo.method:label=MCP_METHOD,
    httpRequest.requestUrl:label=URL)"

Controlla che non siano presenti richieste bloccate. Cerca eventuali tentativi di uscita negati con codici di stato HTTP 403 Forbidden nei log di controllo del gateway.

# show gateway logs for authz denies
gcloud logging read \
  "resource.type=\"networkservices.googleapis.com/Gateway\" \
  AND (jsonPayload.authzPolicyInfo.result=\"DENIED\" OR httpRequest.status=403)" \
  --project=${PROJ_ID} \
  --limit=10 \
  --format="table(
    timestamp.date(tz=LOCAL):label=TIMESTAMP,
    httpRequest.requestMethod:label=METHOD,
    httpRequest.status:label=STATUS,
    jsonPayload.enforcedGatewaySecurityPolicy.serverNameIndication:label=SNI,
    jsonPayload.authzPolicyInfo.result:label=AUTHZ_RESULT,
    jsonPayload.authzPolicyInfo.policies[0].name.basename():label=DENYING_POLICY
  )"
# show gateway logs for mcp requests with method and tool name
gcloud logging read \
  "resource.type=\"networkservices.googleapis.com/Gateway\" \
  AND jsonPayload.agentGatewayInfo.mcpInfo.method:*" \
  --project=${PROJ_ID} \
  --limit=10 \
  --format="table(
    timestamp.date(tz=LOCAL):label=TIMESTAMP,
    httpRequest.status:label=STATUS,
    jsonPayload.authzPolicyInfo.result:label=IAP_AUTHZ,
    jsonPayload.agentGatewayInfo.mcpInfo.method:label=MCP_METHOD,
    jsonPayload.agentGatewayInfo.mcpInfo.parameter:label=TOOL_NAME,
    httpRequest.requestUrl:label=URL
  )"

Verifica del rifiuto condizionale

Invia una query di test aggiuntiva (prova a richiamare lo strumento negatoget_observations)...

  • What are the diabetes levels in Peru compared to Slovakia?

L'agente esaminerà prima search_indicators, poi tenterà di utilizzare get_observations, ma non riuscirà e la risposta dell'agente rimarrà incompleta.

# show gateway logs for mcp requests with method and tool name
gcloud logging read \
  "resource.type=\"networkservices.googleapis.com/Gateway\" \
  AND jsonPayload.agentGatewayInfo.mcpInfo.method:*" \
  --project=${PROJ_ID} \
  --limit=10 \
  --format="table(
    timestamp.date(tz=LOCAL):label=TIMESTAMP,
    httpRequest.status:label=STATUS,
    jsonPayload.authzPolicyInfo.result:label=IAP_AUTHZ,
    jsonPayload.agentGatewayInfo.mcpInfo.method:label=MCP_METHOD,
    jsonPayload.agentGatewayInfo.mcpInfo.parameter:label=TOOL_NAME,
    httpRequest.requestUrl:label=URL
  )"
TIMESTAMP            STATUS  IAP_AUTHZ  MCP_METHOD                 TOOL_NAME          URL
YYYY-MM-DDTHH:MM:SS  403     DENIED     tools/call                 get_observations   https://api.datacommons.org/mcp
YYYY-MM-DDTHH:MM:SS          ALLOWED    tools/call                 get_observations   https://api.datacommons.org/mcp
YYYY-MM-DDTHH:MM:SS  403     DENIED     tools/call                 get_observations   https://api.datacommons.org/mcp
YYYY-MM-DDTHH:MM:SS  200     ALLOWED    tools/call                 search_indicators  https://api.datacommons.org/mcp
YYYY-MM-DDTHH:MM:SS  200     ALLOWED    tools/list                                    https://api.datacommons.org/mcp
YYYY-MM-DDTHH:MM:SS  202     ALLOWED    notifications/initialized                     https://api.datacommons.org/mcp

In questo modo viene convalidato che la policy di governance funzioni come previsto.

Tieni presente che la seconda riga che indica uno stato vuoto e ALLOWED è un evento di log di interruzione della connessione secondaria emesso da Agent Gateway quando chiude il socket dopo l'invio della risposta 403 (poiché gli eventi di chiusura della connessione non hanno codici di stato della risposta, httpRequest.status è vuoto).

Con questo si conclude la parte relativa all'applicazione... passiamo ora alla sezione Pulizia.

13. Esegui la pulizia

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

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

# next
# clear policy on mcp server
export IAP_ETAG=$(gcloud beta iap web get-iam-policy --resource-type=agent-registry --mcp-server=${MCP_REGISTRY_ID} --region=${REGION} --format="value(etag)")
cat > cfg/iap-policy-empty.json << EOF
{
  "bindings": [],
  "etag": "${IAP_ETAG}"
}
EOF

gcloud -q beta iap web set-iam-policy cfg/iap-policy-empty.json \
  --resource-type=agent-registry \
  --mcp-server=${MCP_REGISTRY_ID} \
  --region=${REGION}

# next
# clear policy on endpoint 1
export IAP_ETAG=$(gcloud beta iap web get-iam-policy --resource-type=agent-registry --endpoint=${ENDPOINT_1_REGISTRY_ID} --region=${REGION} --format="value(etag)")
cat > cfg/iap-policy-empty.json << EOF
{
  "bindings": [],
  "etag": "${IAP_ETAG}"
}
EOF

gcloud -q beta iap web set-iam-policy cfg/iap-policy-empty.json \
  --resource-type=agent-registry \
  --endpoint=${ENDPOINT_1_REGISTRY_ID} \
  --region=${REGION}

# next
# clear policy on endpoint 2
export IAP_ETAG=$(gcloud beta iap web get-iam-policy --resource-type=agent-registry --endpoint=${ENDPOINT_2_REGISTRY_ID} --region=${REGION} --format="value(etag)")
cat > cfg/iap-policy-empty.json << EOF
{
  "bindings": [],
  "etag": "${IAP_ETAG}"
}
EOF

gcloud -q beta iap web set-iam-policy cfg/iap-policy-empty.json \
  --resource-type=agent-registry \
  --endpoint=${ENDPOINT_2_REGISTRY_ID} \
  --region=${REGION}

# next
# clear policy on endpoint 3
export IAP_ETAG=$(gcloud beta iap web get-iam-policy --resource-type=agent-registry --endpoint=${ENDPOINT_3_REGISTRY_ID} --region=${REGION} --format="value(etag)")
cat > cfg/iap-policy-empty.json << EOF
{
  "bindings": [],
  "etag": "${IAP_ETAG}"
}
EOF

gcloud -q beta iap web set-iam-policy cfg/iap-policy-empty.json \
  --resource-type=agent-registry \
  --endpoint=${ENDPOINT_3_REGISTRY_ID} \
  --region=${REGION}

# next
# remove manual registry entry
gcloud -q agent-registry services delete ${MCP_RESOURCE_NAME} --location=${REGION}
# delete gateway resources
gcloud -q beta network-security authz-policies delete ${AGW_NAME}-authz-policy-profile-iap --location=${REGION}

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

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

gcloud -q network-services agent-gateways delete ${AGW_NAME} --location=${REGION}

# next
# clean up local working directories and generated configs
rm -rf cfg agent-datacommons endpoints

# end

Con questo si conclude la parte di pulizia. Passiamo ora alla conclusione.

14. Conclusione

Complimenti! Hai eseguito il deployment e gestito correttamente le comunicazioni in uscita per un agente che accede agli strumenti utilizzando Agent Gateway.

cosmopup

Cosmopup pensa che i codelab siano il massimo!

Quali sono i passaggi successivi?

Non esitare a inviare commenti, domande o correzioni utilizzando questo modulo di feedback.

Grazie.