Salida de Agent Gateway desde Agent Runtime a la red de VPC

1. Introducción

En este codelab, se explora la gobernanza de salida de Agent Gateway para los agentes de IA que acceden a extremos remotos a través de una red de VPC privada. La puerta de enlace del agente que opera en modo de salida (del agente a cualquier lugar) admite la conectividad privada a una red de VPC a través de interfaces de Private Service Connect (PSC). En este caso, Agent Runtime usa Agent Gateway para acceder a un servidor MCP HTTP remoto con capacidad de transmisión alojado en Cloud Run a través de un extremo de Private Service Connect (PSC) para las APIs de Google en la red de VPC.

Las apps de IA, desde chatbots independientes hasta sistemas autónomos con flujos de trabajo multiagente, pueden invocar herramientas externas de forma dinámica. Proporcionar a los agentes acceso controlado para consultar bases de datos, recuperar contenido web y ejecutar acciones es fundamental para que sean seguros y productivos. Sin embargo, en los entornos empresariales, proteger la ejecución de herramientas de agentes es un desafío. Si un agente tiene acceso directo a la red, los ataques de inyección de instrucciones o las alucinaciones del modelo pueden hacer que el agente filtre datos sensibles o ejecute comandos destructivos.

Para administrar agentes autónomos a gran escala, Agent Gateway proporciona un punto de aplicación centralizado de confianza cero integrado directamente en la arquitectura de Agent Platform. En lugar de depender de implementaciones personalizadas exclusivas para cada aplicación o código de agente, Agent Gateway proporciona enrutamiento de red, administración de agentes y seguridad en el tiempo de ejecución que se aplican a nivel de la plataforma.

Cuando Agent Gateway opera en modo de salida (agent-to-anywhere), reenvía todas las solicitudes salientes de los agentes configurados para usar la puerta de enlace. Cada solicitud de carga de trabajo del agente se autentica con la identidad del agente única y se autoriza con las políticas de Identity-Aware Proxy (IAP). Las llamadas a la herramienta del MCP se decodifican y se inspeccionan de forma dinámica para aplicar las políticas. Los administradores de seguridad pueden aplicar de forma centralizada permisos detallados para garantizar que los agentes solo puedan invocar extremos y métodos aprobados.

Qué compilarás

  • Agent Gateway en modo de salida (del agente a cualquier lugar)
  • Extensión de autorización de Identity-Aware Proxy (IAP)
  • Agente de Agent Runtime ADK con identidad del agente
  • Servidor MCP HTTP transmitible de Cloud Run
  • Agent Registry con la API de Google y extremos de MCP personalizados
  • Políticas de autorización con control de acceso de IAM
  • Recursos de red de VPC, zona de Cloud DNS y extremo de PSC para las APIs de Google
  • Adjunto de red de PSC para la salida de Agent Gateway
  • Reglas de la política de firewall de Cloud Next Generation Firewall (NGFW)

figure1

Fig. 1: Arquitectura del codelab

Qué aprenderá

  • Cómo implementar Agent Gateway en una secuencia de configuración estructurada
  • Cómo configurar Agent Gateway con conectividad de red de VPC privada
  • Cómo realizar la transición de las políticas de autorización del modo de ejecución de prueba al modo aplicado
  • Cómo registrar extremos de la API de Google y servidores MCP en Agent Registry
  • Cómo auditar los registros de Agent Gateway para validar la administración de la salida
  • Cómo validar el tráfico de salida de Agent Gateway con los registros de Cloud NGFW

Requisitos

  • Un proyecto de Google Cloud con la facturación habilitada.
  • Permisos de IAM para aprovisionar servicios de redes, conjuntos de datos de BigQuery y recursos de Agent Platform
  • Un shell compatible con POSIX (bash o zsh) con Google Cloud CLI (componentes gcloud y bq) instalado
  • Herramientas de línea de comandos: git, curl, jq (procesador JSON), Python 3 y uv (administrador de paquetes de Python)

2. Conceptos

Secuencia de implementación

Este codelab sigue una secuencia de configuración estructurada para que los agentes tengan acceso a los recursos necesarios en la inicialización y se pueda confirmar la conectividad antes de aplicar políticas de acceso obligatorias.

En este codelab, se usa la siguiente secuencia de implementación:

  1. Comienza en el modo DRY_RUN: Asegúrate de que las solicitudes del agente lleguen correctamente a la puerta de enlace y la atraviesen (modo solo de auditoría).
  2. Registra todos los servicios: Registra todos los componentes de agentes en el registro de agentes y confirma el acceso a las herramientas de los agentes. Usa Cloud Logging y el panel de observabilidad de Agent Gateway para ver las consultas al registro de agentes.
  3. Crea políticas de autorización: Crea y aplica políticas de autorización para permitir el tráfico de salida de los agentes a los servidores y extremos de MCP.
  4. Cambia al modo ENFORCED: Actualiza la política de extensión de autorización para aplicar políticas y bloquear el tráfico de salida no autorizado.

figure2

Fig. 2: Secuencia de implementación

Topología de enrutamiento de salida

La salida de Agent Gateway (agente a cualquier lugar) actúa como un proxy saliente centralizado de confianza cero para las cargas de trabajo de agentes. Cuando un agente realiza una solicitud a una herramienta o API externa, Agent Gateway intercepta la solicitud saliente y la evalúa en función de las políticas de gobernanza antes de enrutarla a su destino. En una arquitectura de Agent Platform de Google Cloud, Agent Gateway proporciona conectividad del plano de datos a lo siguiente:

  • Redes privadas (VPC): Tráfico saliente dirigido a APIs internas de la empresa, microservicios, bases de datos alojadas en VPC privadas y redes locales o entre nubes a las que se puede acceder a través de conectividad híbrida.
  • Redes externas (Internet): Tráfico saliente que se dirige a servicios web de terceros, APIs de SaaS o extremos públicos.
  • Servicios de IA y Agent Platform: Tráfico saliente que segmenta las APIs administradas de Google Cloud, los modelos básicos, los extremos de MCP de Google (como BigQuery) y los servicios de administración de la plataforma (políticas de Agent Registry y de IAP).

figure3

Fig. 3: Topología de enrutamiento de salida de Agent Gateway

El objetivo de este codelab es el tráfico saliente de un agente personalizado en Agent Runtime que se dirige a un extremo de PSC para las APIs de Google implementado en una red de VPC. Esta arquitectura permite el acceso privado al servidor de MCP alojado en Cloud Run a través de la conexión de red de PSC para la salida de Agent Gateway.

Conectividad VPC

La salida de Agent Gateway (agent-to-anywhere) puede conectarse a una red de VPC especificando networkConfig: egress: networkAttachment: [URI] en el archivo de configuración YAML de implementación. Este parámetro de configuración establece reglas de enrutamiento en Agent Gateway para enviar tráfico que se resuelve en direcciones IP privadas a través de la vinculación de red de PSC en la red de VPC.

figure4

Fig. 4: Conectividad de VPC de la puerta de enlace de agente

Agent Gateway puede resolver nombres de host de DNS privados con el intercambio de tráfico de Cloud DNS en un proyecto y una red de VPC de destino especificados. Todas las zonas privadas que se indiquen en la configuración de dnsPeeringConfig: domains: [NAME] usarán registros de Cloud DNS en el proyecto de destino. Cualquier otra consulta de DNS usará el solucionador público predeterminado de Cloud DNS de VPC.

Aquí concluye la sección de conceptos. A continuación, se encuentra la sección de Configuración.

3. Configuración

Roles de IAM obligatorios

Se requieren los siguientes roles para crear los recursos en este codelab:

Categoría

Rol de IAM requerido (ID)

Descripción

Administración de API

roles/serviceusage.serviceUsageAdmin

Habilita los servicios de la API de Google Cloud

Redes y puerta de enlace

roles/networkservices.admin

Aprovisiona Agent Gateway

Service Extensions

roles/serviceextensions.admin

Configura las extensiones de enrutamiento

Seguridad de red

roles/networksecurity.admin

Implementa políticas de autorización

Agent Registry

roles/agentregistry.admin

Hosts permitidos del catálogo

Vertex AI y agentes

roles/aiplatform.admin

Implementa cargas de trabajo de Agent Runtime

Políticas de salida

roles/iap.admin

Aplica políticas de roles/iap.egressor

Cloud Storage

roles/storage.admin

Administra buckets de etapa de pruebas de implementación

Registros y auditoría

roles/logging.viewer

Cómo inspeccionar registros y registros de auditoría

Desarrollador de Cloud Run

roles/run.developer

Implementa servicios de Cloud Run

Lector de Artifact Registry

roles/artifactregistry.reader

Extrae imágenes de contenedor

Administrador de red de Compute

roles/compute.networkAdmin

Administra recursos de redes de VPC

Administrador de DNS

roles/dns.admin

Administra zonas y registros de Cloud DNS

Como alternativa, usa un rol básico amplio, como roles/admin, o un rol heredado, como roles/owner.

Accede a tu proyecto

En este codelab, se usa un solo proyecto de Google Cloud. En los pasos de configuración, se usan la CLI de gcloud y los comandos de shell de Linux.

Para comenzar, accede a la línea de comandos de tu proyecto de Google Cloud:

Establece tu ID del proyecto

gcloud config set project SET_YOUR_PROJECT_ID_HERE

Autentica la sesión

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

Establece variables de entorno de 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)
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}-ata"
export AGW_URI="projects/${PROJ_ID}/locations/${REGION}/agentGateways/${AGW_NAME}"
export RE_AGENT_NAME="agent-weather"
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_NAME="mcp-weather"
export MCP_DISPLAY_NAME="${MCP_NAME}-${PROJ_NO}.${REGION}.run.app"
export MCP_URL="https://${MCP_DISPLAY_NAME}/mcp"
echo ${AGW_NAME}
echo ${AGW_URI}
echo ${RE_AGENT_NAME}
echo ${RE_AGENT_ID_SET}
echo ${STAGING_BUCKET}
echo ${MCP_NAME}
echo ${MCP_DISPLAY_NAME}
echo ${MCP_URL}
# create local dir for config files
mkdir -p cfg

Si ejecutas una instalación autoadministrada del SDK de Google Cloud (es decir, fuera de Cloud Shell), actualiza los componentes a la versión más reciente.

# update gcloud cli
gcloud components update

Habilita los servicios de la 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
# enable google apis (all the rest)
gcloud services enable \
  run.googleapis.com \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com \
  dns.googleapis.com

Aquí concluye la parte de configuración… a continuación, la sección Red.

4. Red

La red de VPC se implementa con el modo personalizado para crear subredes regulares que admitan la vinculación de red de PSC para la salida de VPC directa de Agent Gateway y Cloud Run.

El extremo de PSC para las APIs de Google se implementa con una sola /32dirección IPv4 interna global para admitir el acceso interno privado a Cloud Run. Esta dirección IP no se asigna desde ninguna subred regional.

Crea redes

Crea una red de VPC global.

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

Crea subredes para la vinculación de red del PSC de la puerta de enlace del agente y la salida de VPC directa de Cloud Run.

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

# create subnet for cloud run dvpc egress
gcloud compute networks subnets create subnet-${REGION}-crun \
  --network=vnet-${SLUG} \
  --range=10.10.10.0/24 \
  --region=${REGION} \
  --enable-private-ip-google-access

Crea reglas de firewall

Crea una política y una regla de firewall para permitir todo el tráfico de salida con el registro habilitado. Se usará para supervisar el tráfico que sale de Agent Gateway hacia la red de VPC.

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

Crea un adjunto de red de PSC

Crea un adjunto de red de PSC configurado para aceptar automáticamente nuevas conexiones de productores.

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

Verifica el adjunto de red de PSC

# show psc network attachment details
gcloud compute network-attachments describe psc-na-${REGION}-agw --region=${REGION}
# fetch psc na 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}

Crea un extremo de PSC

Crea una reserva de dirección IP para el extremo de PSC global. La dirección que se usa aquí no puede provenir de una subred existente ni superponerse con ella.

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

Crea un extremo de PSC para las APIs de Google con el paquete all-apis, que incluye Cloud Run (run.app).

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

Verifica el extremo de PSC

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

Crea una zona y registros de DNS

Crea una zona administrada de Cloud DNS privada para el dominio run.app.

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

Crea un registro DNS A comodín para *.run.app. que apunte a la dirección IP del extremo de PSC.

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

Crea una política de Cloud DNS para habilitar el registro de consultas de DNS.

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

Crea Cloud NAT

Crea un Cloud Router y Cloud NAT para admitir la salida de VPC directa de Cloud Run para que el servidor de MCP pueda acceder a los datos meteorológicos externos a través de la red de VPC.

# create router for nat
gcloud compute routers create cr-nat-${SLUG}-${REGION} \
  --network=vnet-${SLUG} \
  --asn=16550 \
  --region=${REGION}
# create nat gateway
gcloud compute routers nats create nat-${SLUG}-${REGION} \
  --router=cr-nat-${SLUG}-${REGION} \
  --region=${REGION} \
  --auto-allocate-nat-external-ips \
  --nat-all-subnet-ip-ranges

Con esto, concluye la parte de la red. A continuación, se abordará la sección Puerta de enlace.

5. Puerta de enlace

Antes de aplicar los controles de acceso, implementa Agent Gateway y configura la extensión de autorización en modo DRY_RUN. Esto permite que las llamadas a herramientas salientes se realicen correctamente y, al mismo tiempo, se registren los resultados de la evaluación para fines de auditoría.

Aquí, Agent Gateway usa un registro regional para admitir recursos de Agent Runtime regionales y especifica los campos networkConfig para la configuración del intercambio de tráfico de DNS y el adjunto de red del PSC de la red de VPC.

Crear puerta de enlace

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

Verifica la puerta de enlace

# show agent gateway details
gcloud network-services agent-gateways describe ${AGW_NAME} \
  --location=${REGION}
# show psc network attachment details
gcloud compute network-attachments describe psc-na-${REGION}-agw --region=${REGION}

Verifica que haya un extremo de conexión aceptado.

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

Aquí concluye la parte de la puerta de enlace… a continuación, se encuentra la sección Autorización.

6. Autorización

La extensión de autorización de Agent Gateway para Identity-Aware Proxy (IAP) es un tipo de extensión de servicio que se usa para delegar decisiones de autorización para todas las comunicaciones de Agent Platform.

  1. Flujo de delegación: Cuando un agente intenta invocar un extremo externo o un servidor de MCP, enruta la solicitud a Agent Gateway. En lugar de evaluar el acceso de forma local, la puerta de enlace usa la extensión de autorización para enviar una llamada al servicio de evaluación de IAP. IAP evalúa la identidad del agente (basada en SPIFFE) en función de la política de IAM del recurso de destino en el Registro de agentes. IAP devuelve una decisión ALLOW o DENY a la puerta de enlace, que reenvía el tráfico o lo bloquea con un código de estado HTTP 403 Forbidden.
  2. Modos de aplicación: En el modo DRY_RUN, IAP evalúa las solicitudes y registra las decisiones en Cloud Logging sin bloquear el tráfico. En el modo ENFORCE, se bloquea de inmediato cualquier solicitud de un agente no autorizado o a un destino no registrado.
  3. Capa de vinculación: La extensión de servicio se conecta a Agent Gateway a través de una política de autorización configurada con el perfil REQUEST_AUTHZ.

Extensión de autorización

Una extensión de autorización especifica el servicio del proveedor de seguridad con la configuración de conectividad y otros parámetros que definen cómo operará el servicio y se integrará con Agent Gateway.

Crea una extensión de autorización

# 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

Importa la extensión de autorización

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

Verifica la extensión de autorización

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

Política de autorización

Una política de autorización vincula el proveedor de seguridad (IAP) al recurso de puerta de enlace de destino y especifica el perfil de intercepción (REQUEST_AUTHZ).

Crea la política de autorización

# 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

Vincula la política de autorización

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

Verifica la política de autorización

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

Con esto, concluye la parte de autorización… a continuación, veremos la sección Codebase.

7. Base de código

El agente, el servidor de MCP y el código de registro de extremos que se usan para este codelab se mantienen en un repositorio remoto de GitHub de Google Cloud. En los siguientes pasos, se clonará el repositorio de forma local, se copiarán los archivos necesarios en la estructura del directorio de trabajo actual y, luego, se borrarán los archivos temporales.

Se crea un bucket de almacenamiento provisional para que Agent Runtime suba, compile y, luego, implemente el código de la aplicación del agente empaquetado y sus artefactos de dependencia.

Recupera artefactos remotos

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

Crea un bucket de etapa de pruebas

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

Aquí concluye la parte de la base de código. A continuación, se abordará la sección Registro.

8. Registro

Agent Registry es un inventario centralizado de todos los agentes, servidores MCP y extremos (APIs) en el ecosistema de IA. También es un catálogo que se puede usar para enumerar, buscar y descubrir otras herramientas y servicios registrados para su uso en aplicaciones de IA. Agent Gateway usa el modelo de datos del registro como framework de administración para aplicar el control de acceso de salida. Los permisos de rol de IAM para los agentes de llamada de la principal se verifican en función de la política vinculada al recurso del registro.

Para iniciar el entorno y admitir el agente con varios servicios y APIs de Google, crea un único servicio de extremo de registro que agrupe las interfaces de la API principal necesarias para este lab. Esto facilitará la administración de las políticas de gobernanza para los conjuntos comunes de herramientas que usarán la mayoría de los agentes.

Registra extremos

# create endpoint service (with multiple entries)
gcloud agent-registry services create core-gapi-services \
  --location=${REGION} \
  --display-name="gapi.core.services" \
  --description="core apis and services" \
  --endpoint-spec-type=no-spec \
  --interfaces=protocolBinding=JSONRPC,url=https://telemetry.googleapis.com \
  --interfaces=protocolBinding=JSONRPC,url=https://${REGION}-aiplatform.googleapis.com \
  --interfaces=protocolBinding=JSONRPC,url=https://cloudresourcemanager.googleapis.com \
  --interfaces=protocolBinding=JSONRPC,url=https://iamcredentials.googleapis.com

Verifica el registro del extremo

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

Aquí concluye la sección del registro. A continuación, se abordará la sección del servidor de MCP.

9. Servidor MCP

Otorga permisos de IAM para la implementación

Otorga permisos a la cuenta de servicio de Compute predeterminada para admitir la implementación de servicios de Cloud Run desde el código fuente.

# grant cloud run builder role to default compute sa
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="serviceAccount:${PROJ_NO}-compute@developer.gserviceaccount.com" \
  --role="roles/run.builder"

Verifica los permisos de IAM

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

Implementa el servidor de MCP

# deploy cloud run service
gcloud -q run deploy ${MCP_NAME} \
  --source=mcp-weather/server \
  --region=${REGION} \
  --no-allow-unauthenticated \
  --min-instances=1 \
  --network=vnet-${SLUG} \
  --subnet=subnet-${REGION}-crun \
  --vpc-egress=all-traffic \
  --startup-probe=httpGet.path=/warmup

Otorga permisos de IAM para la entrada

Vincula la política para el acceso del usuario

Otorga permisos a la cuenta de usuario (propia) para invocar el servidor de MCP alojado en Cloud Run. Esto es necesario para ejecutar la secuencia de comandos de generación de toolspec.

# grant run invoker role to user account on cloud run service level
gcloud run services add-iam-policy-binding ${MCP_NAME} \
  --region=${REGION} \
  --member="user:${USER_IDENTITY}" \
  --role="roles/run.invoker"

Verifica los permisos de IAM

# show iam policy on cloud run service for invoker role
gcloud run services get-iam-policy ${MCP_NAME} \
  --region=${REGION} \
  --flatten="bindings[].members" \
  --filter="bindings.role=roles/run.invoker" \
  --format="table(bindings.members:label=PRINCIPAL_IDENTITY, bindings.role:label=ROLE)"

Crea un SA personalizado para la invocación de MCP

Crea una cuenta de servicio personalizada para invocar el servidor de MCP alojado en Cloud Run. El agente usará esta cuenta de servicio para recuperar un token de ID de OIDC firmado por Google válido para acceder a Cloud Run.

# create custom sa for mcp server invocation
gcloud iam service-accounts create sa-${MCP_NAME}-invoker \
  --display-name="custom sa to invoke ${MCP_NAME}"
# set env var for service account identity
export MCP_INVOKER_SA="sa-${MCP_NAME}-invoker@${PROJ_ID}.iam.gserviceaccount.com"
echo ${MCP_INVOKER_SA}

Vincula la política para la cuenta de servicio

# grant run invoker role to custom sa on cloud run service level
gcloud run services add-iam-policy-binding ${MCP_NAME} \
  --role="roles/run.invoker" \
  --member="serviceAccount:${MCP_INVOKER_SA}" \
  --region=${REGION}

Verifica los permisos de IAM

# show iam policy on cloud run service for invoker role
gcloud run services get-iam-policy ${MCP_NAME} \
  --region=${REGION} \
  --flatten="bindings[].members" \
  --filter="bindings.role=roles/run.invoker" \
  --format="table(bindings.members:label=PRINCIPAL_IDENTITY, bindings.role:label=ROLE)"

Otorga permisos de IAM para la autenticación

Otorga roles de suplantación de identidad de la cuenta de servicio a la cuenta de servicio de Compute predeterminada. Esto permitirá que el agente, que se ejecuta con las credenciales predeterminadas de la aplicación (ADC), genere tokens de ID de OIDC firmados por Google en nombre de la cuenta de servicio del invocador personalizado para autenticar las llamadas a Cloud Run.

Política de vinculación para la autenticación

# grant oidc token creator role to default compute service account
gcloud iam service-accounts add-iam-policy-binding ${MCP_INVOKER_SA} \
  --role="roles/iam.serviceAccountOpenIdTokenCreator" \
  --member="serviceAccount:${PROJ_NO}-compute@developer.gserviceaccount.com"

# grant service account token creator role to default compute service account
gcloud iam service-accounts add-iam-policy-binding ${MCP_INVOKER_SA} \
  --role="roles/iam.serviceAccountTokenCreator" \
  --member="serviceAccount:${PROJ_NO}-compute@developer.gserviceaccount.com"

Verifica los permisos de IAM

# show iam policy for the custom service account
gcloud iam service-accounts get-iam-policy ${MCP_INVOKER_SA} \
  --flatten="bindings[].members" \
  --format="table(bindings.role:label=ROLE, bindings.members:label=PRINCIPAL_IDENTITY)"

Crear MCP toolspec

Cuando registras un servidor de MCP de forma manual, debes incluir un archivo de especificación de la herramienta. Un archivo toolspec.json enumera todas las herramientas que el servidor de MCP pone a disposición y permite que otros usuarios las descubran una vez que se registran.

La secuencia de comandos test_mcp.py, incluida en la base de código mcp-weather/, genera un archivo toolspec.json conectándose al servidor de MCP de destino (a través de SSE o HTTP) y llamando a list_tools() para recuperar todas las herramientas disponibles expuestas por el servidor.

# fetch oidc token for cloud run authentication
export OIDC_TOKEN=$(gcloud auth print-identity-token)
# generate toolspec for registry ingestion
uv --directory mcp-weather run test_mcp.py --toolspec=include --token="${OIDC_TOKEN}"

Un vistazo al resultado de toolspec generado muestra los atributos de MCP que Agent Gateway puede usar para la evaluación y la aplicación de la política de salida.

Verifica el MCP toolspec

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

Actualiza la entrada de Cloud Run

Cambia la configuración de entrada del servicio de Cloud Run para que solo acepte solicitudes entrantes de la red de VPC. Esto evita el acceso público directo al extremo del MCP y solo permite que los recursos internos accedan a él. El tráfico destinado al extremo de PSC para las APIs de Google en la red de VPC se considerará ingreso interno y se permitirá.

# update cloud run service config
gcloud run services update ${MCP_NAME} \
  --region=${REGION} \
  --ingress=internal

Verifica la entrada de Cloud Run

# show cloud run service details
gcloud run services describe ${MCP_NAME} --region=${REGION} | grep -iE 'ingress|egress'

Registra el servidor de MCP

Ahora que tienes el toolspec, registra el servidor de MCP en el Agent Registry regional.

# register mcp server
gcloud agent-registry services create ${MCP_NAME} \
  --location=${REGION} \
  --display-name="${MCP_DISPLAY_NAME}" \
  --description="mcp server for weather info" \
  --mcp-server-spec-type=tool-spec \
  --mcp-server-spec-content=mcp-weather/toolspec.json \
  --interfaces=url=${MCP_URL},protocolBinding=JSONRPC

Verifica el registro de MCP

# 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_NAME} --location=${REGION}
# fetch mcp server registry id
export MCP_REGISTRY_ID=$(gcloud agent-registry services describe ${MCP_NAME} \
  --location=${REGION} \
  --format="value(registryResource.basename())")
echo ${MCP_REGISTRY_ID}

Aquí concluye la sección del servidor de MCP. A continuación, se abordará la sección del agente del ADK.

10. Agente de ADK

El agente del ADK de agent-weather implementado en Agent Runtime se configura con los siguientes parámetros en la secuencia de comandos de implementación para integrarse con Agent Platform:

  • "identity_type": types.IdentityType.AGENT_IDENTITY para aprovisionar una identidad principal única basada en SPIFFE para el agente
  • "agent_gateway_config": { "agent_to_anywhere_config": {"agent_gateway": } } para dirigir todo el tráfico saliente iniciado por el agente a Agent Gateway para la evaluación y aplicación de políticas

El agente también está configurado para usar el servidor de MCP pasando la URL y la cuenta de servicio para recuperar el token de ID de OIDC.

Implementa el agente

# deploy agent runtime workload
uv --directory agent-weather 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 weather info" \
  --mcp-server-url="${MCP_URL}" \
  --mcp-invoker-sa="${MCP_INVOKER_SA}" \
  --enable-telemetry \
  --enable-agent-identity \
  --agent-gateway-egress=${AGW_URI} \
  --allow-token-sharing

Verifica la implementación

Recupera los signos vitales de la implementación

# 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 entrada del registro

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

Verifica la configuración de la puerta de enlace

# show agent 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}'

Otorga permisos de IAM para la autenticación

Cuando un agente está configurado para usar la identidad del agente, recibe un token (formato JWT-SVID) del servicio de token de seguridad (STS) federado que está firmado por sts.googleapis.com (el proveedor de identidad de SPIFFE).

Sin embargo, la verificación integrada del invocador de IAM de Cloud Run solo confía en los tokens de ID de OIDC estándar firmados por el emisor principal de OIDC de Google (accounts.google.com) y puede verificarlos.

Por lo tanto, se usa una cuenta de servicio personalizada para intercambiar el token STS federado (JWT-SVID) que obtuvo la identidad del agente por un token estándar de Google (OIDC) que se obtuvo con la suplantación de la cuenta de servicio en el tiempo de ejecución.

Crea las vinculaciones de roles necesarias para la cuenta de servicio personalizada.

Vincula la política para la autenticación (suplantación)

# grant service account token creator role to agent principal identity
gcloud iam service-accounts add-iam-policy-binding ${MCP_INVOKER_SA} \
  --role="roles/iam.serviceAccountTokenCreator" \
  --member="${RE_AGENT_IDENTITY}"

# grant service account openid token creator role to agent principal identity
gcloud iam service-accounts add-iam-policy-binding ${MCP_INVOKER_SA} \
  --role="roles/iam.serviceAccountOpenIdTokenCreator" \
  --member="${RE_AGENT_IDENTITY}"

Verifica los permisos de IAM

# show iam policy for custom service account
gcloud iam service-accounts get-iam-policy ${MCP_INVOKER_SA} \
  --flatten="bindings[].members" \
  --format="table(bindings.members.sub('^.*locations/', '.../locations/'):label=PRINCIPAL_IDENTITY, bindings.role:label=ROLE)"

Otorga permisos de IAM para el tiempo de ejecución

Otorgar permisos de IAM para el tiempo de ejecución permite que el agente acceda a los servicios de la plataforma de IA y a otras APIs y servicios principales de Google con su identidad principal del agente basada en SPIFFE. Estas políticas se aplican con IAM a nivel del recurso.

Crea las vinculaciones de roles necesarias para la identidad del agente.

Vincula políticas para el acceso del agente

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

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

# grant agent registry viewer role
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="${RE_AGENT_IDENTITY}" \
  --role="roles/agentregistry.viewer"
# grant cloud logging writer role
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="${RE_AGENT_IDENTITY}" \
  --role="roles/logging.logWriter"

# grant cloud monitoring writer role
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="${RE_AGENT_IDENTITY}" \
  --role="roles/monitoring.metricWriter"

# grant browser role for resource manager lookup
gcloud projects add-iam-policy-binding ${PROJ_ID} \
  --member="${RE_AGENT_IDENTITY}" \
  --role="roles/browser"

Verifica los permisos de IAM

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

Aquí concluye la sección del agente de ADK… a continuación, se muestra la sección Políticas.

11. Políticas

Las políticas de autorización de administración de agentes permiten que el tráfico se enrute desde un agente de IA a través de Agent Gateway y hasta el destino final del recurso (p. ej., un extremo privado del servidor de MCP para la recuperación de datos). Una vez que el tráfico llega al destino, los permisos normales a nivel de servicio o de aplicación autorizan el acceso a los datos.

Otorgar roles de IAM para el tráfico de salida de Agent Gateway habilita políticas de acceso que permiten que la identidad principal del agente acceda a los recursos de destino registrados a través de Agent Gateway. Las políticas se aplican a nivel de Agent Gateway y se validan con las políticas de IAM de Identity-Aware Proxy (IAP).

Otorga roles de IAM para la salida de Agent Gateway

Agent Gateway verifica las solicitudes entrantes para validar que la identidad del agente que llama tenga el permiso iap.webServiceVersions.egressViaIAP (otorgado por el rol roles/iap.egressor) en el recurso de destino.

Otorgar roles/iap.egressor a la identidad del agente o al conjunto de principales de Agent Runtime en el recurso de destino seleccionado permite este tráfico de salida. En este codelab, el rol se aplica a la principal agente, que otorga permiso a la identidad específica del agente de Agent Runtime.

Las políticas de IAM están vinculadas a los recursos de destino según se definen en el modelo de datos del Registro de agentes. El recurso iap_web/agentRegistry representa un nivel "en todo el registro" en la jerarquía de IAM. Aquí, agentRegistry actúa como el elemento superior de los recursos secundarios individuales de agents, mcpServers y endpoints. En este codelab, la política de IAM se vincula a los niveles mcpServer y endpoint, lo que aplica el permiso a los recursos secundarios específicos.

Configura la política del agente para el servidor de MCP

Crea una política para el agente en el servidor de MCP

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

NOTA: etag: debería devolver el valor predeterminado ACAB, ya que aún no se definieron políticas.

# create policy config file
cat > cfg/iap-policy-agent-to-mcp.json << EOF
{
  "bindings": [
    {
      "role": "roles/iap.egressor",
      "members": [
        "${RE_AGENT_IDENTITY}"
      ]
    }
  ],
  "etag": "${IAP_ETAG}"
}
EOF

Vincula la política del agente al servidor de MCP

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

Verifica los permisos de IAM

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

Aquí concluye la sección de políticas. A continuación, se abordará la sección de Auditoría.

12. Auditoría

La extensión de autorización de Agent Gateway funciona en modo DRY_RUN. Se observan y registran las solicitudes salientes, pero no se bloquean. Analizar los registros antes de cambiar al modo ENFORCED confirmará qué políticas deben configurarse para permitir el tráfico previsto.

Prueba las preguntas del agente

Abre una ventana del navegador en la IU de la consola de Google Cloud y navega a la siguiente ubicación:

  • Agent Platform → Agents → Deployments → agent-weather
  • Selecciona la pestaña Playground.

O bien, haz eco de este comando de terminal y haz clic en el vínculo para ir al playground del agente:

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

Envía algunas búsquedas de prueba…

  • What is the weather like in London?
  • How warm is it in New York?

Verifica que las búsquedas devuelvan respuestas válidas.

Analiza los registros de auditoría

Consulta los registros y, luego, inspecciona las evaluaciones de políticas de prueba de validación.

# show gateway logs for endpoints and authz status (duplicates removed)
gcloud logging read \
  "resource.type=\"networkservices.googleapis.com/Gateway\" \
  AND httpRequest.requestUrl:*" \
  --project=${PROJ_ID} \
  --limit=50 \
  --freshness=24h \
  --format="table( \
    timestamp.date(tz=LOCAL):label=TIMESTAMP, \
    httpRequest.status:label=STATUS, \
    jsonPayload.authzPolicyInfo.result:label=AUTHZ, \
    httpRequest.requestUrl.sub('(https?://[^/:]+).*', '\1'):label=ENDPOINT \
  )" | awk 'NR==1 {print; next} ! seen[$2,$3,$4]++'
TIMESTAMP            STATUS  AUTHZ    ENDPOINT
YYYY-MM-DDTHH:MM:SS  200     ALLOWED  https://cloudresourcemanager.googleapis.com
YYYY-MM-DDTHH:MM:SS  200     ALLOWED  https://${REGION}-aiplatform.googleapis.com
YYYY-MM-DDTHH:MM:SS  200     ALLOWED  https://iamcredentials.googleapis.com
YYYY-MM-DDTHH:MM:SS  200     ALLOWED  https://mcp-weather-${PROJ_NO}.${REGION}.run.app
YYYY-MM-DDTHH:MM:SS  200     ALLOWED  https://telemetry.googleapis.com
YYYY-MM-DDTHH:MM:SS  202     ALLOWED  https://mcp-weather-${PROJ_NO}.${REGION}.run.app

Configura la política de agentes para extremos

Debido a que las APIs de Google principales para agent-weather se registraron en un servicio de extremo colectivo en el registro (gapi.core.services), solo se necesita una política para otorgar permisos de salida del agente para el acceso al extremo.

Crea una política para la comunicación del agente con el extremo

# set var for endpoint display name
export ENDPOINT_DISPLAY_NAME="gapi.core.services"
echo ${ENDPOINT_DISPLAY_NAME}
# fetch endpoint registry id
export ENDPOINT_REGISTRY_ID=$(gcloud agent-registry services list \
  --location=${REGION} \
  --filter="displayName=${ENDPOINT_DISPLAY_NAME}" \
  --format="value(registryResource.basename())")
echo ${ENDPOINT_REGISTRY_ID}
# create policy config file
cat > cfg/iap-policy-agent-to-ep.json << EOF
{
  "bindings": [
    {
      "role": "roles/iap.egressor",
      "members": [
        "${RE_AGENT_IDENTITY}"
      ]
    }
  ]
}
EOF

Vincula la política del agente al extremo

# import policy file (bind iam policy)
gcloud -q beta iap web set-iam-policy cfg/iap-policy-agent-to-ep.json \
  --resource-type=agent-registry \
  --endpoint=${ENDPOINT_REGISTRY_ID} \
  --region=${REGION}

Verifica los permisos de IAM

# show iap iam policy on endpoint for agent
gcloud beta iap web get-iam-policy \
  --region=${REGION} \
  --resource-type=agent-registry \
  --endpoint=${ENDPOINT_REGISTRY_ID}

Aquí concluye la parte de la auditoría. A continuación, se abordará la sección Aplicar.

13. Aplicar

El agente pudo realizar solicitudes exitosas a través de la puerta de enlace en modo DRY_RUN. Se analizaron los registros de acceso y los extremos para crear un conjunto de políticas de administración que permitieran el tráfico de salida necesario del agente. Ahora, actualiza la política de autorización para hacer la transición de la extensión de autorización del IAP de Agent Gateway al modo ENFORCE.

Actualiza la extensión de autorización

Crea una extensión de autorización

# 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

Importa la extensión de autorización

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

Verifica la extensión de autorización

# list authz extensions (imported configs)
gcloud service-extensions authz-extensions list --location=${REGION}

Actualiza la política de autorización

Crea la política de autorización

# 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

Vincula la política de autorización

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

Verifica la política de autorización

# show authz policy details (verify enforced mode)
gcloud beta network-security authz-policies describe ${AGW_NAME}-authz-policy-profile-iap \
  --location=${REGION}

Verifica la aplicación

Regresa al Playground del agente en la IU de la consola.

  • Haz clic en el botón "+ Nueva sesión" para crear una nueva sesión de chat.

Envía una consulta de prueba adicional…

  • What is the current temperature in Los Angeles?

Observa que las solicitudes del agente al modelo fundamental de Gemini (${REGION}-aiplatform.googleapis.com/...) y al extremo del servidor de MCP (mcp-weather-${PROJ_NO}.${REGION}.run.app/mcp) se pasan con códigos de estado HTTP 200 OK.

Analiza los registros de la puerta de enlace

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

Comprueba que no se bloquee ninguna solicitud. Busca cualquier intento de salida rechazado con códigos de estado HTTP 403 Forbidden en los registros de auditoría de la puerta de enlace.

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

Consulta los registros de MCP de Agent Gateway y observa cómo se inspecciona la carga útil de la aplicación de MCP (JSON-RPC) para exponer los metadatos del protocolo, incluidas las herramientas que se ejecutan.

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

Analiza los registros de firewall

Visualiza los registros de la prioridad 1001 de la regla de política de firewall de red.

# show firewall logs for rule 1001
gcloud logging read \
  "jsonPayload.rule_details.priority=1001" \
  --project=${PROJ_ID} \
  --limit=10 \
  --format="table(
    timestamp.date(tz=LOCAL):label=TIMESTAMP,
    jsonPayload.disposition:label=ACTION,
    jsonPayload.connection.src_ip:label=SRC_IP,
    jsonPayload.connection.dest_ip:label=DEST_IP,
    jsonPayload.connection.dest_port:label=DEST_PORT,
    jsonPayload.vpc.subnetwork_name:label=SUBNET
  )"

Observa la vista a nivel de la red de las diferentes rutas de tráfico:

  • Puerta de enlace del agente que se comunica con los recursos internos de la red de VPC a través de subnet-${REGION}-agw
  • El servidor de MCP alojado en Cloud Run que realiza llamadas a APIs externas de clima con subnet-${REGION}-crun
TIMESTAMP            ACTION   SRC_IP        DEST_IP        DEST_PORT  SUBNET
YYYY-MM-DDTHH:MM:SS  ALLOWED  10.10.10.16   188.40.99.226  443        subnet-${REGION}-crun
YYYY-MM-DDTHH:MM:SS  ALLOWED  10.10.10.16   202.61.206.6   443        subnet-${REGION}-crun
YYYY-MM-DDTHH:MM:SS  ALLOWED  10.10.10.16   188.40.99.226  443        subnet-${REGION}-crun
YYYY-MM-DDTHH:MM:SS  ALLOWED  10.10.10.16   202.61.206.6   443        subnet-${REGION}-crun
YYYY-MM-DDTHH:MM:SS  ALLOWED  10.10.10.16   202.61.206.6   443        subnet-${REGION}-crun
YYYY-MM-DDTHH:MM:SS  ALLOWED  10.10.10.16   202.61.206.6   443        subnet-${REGION}-crun
YYYY-MM-DDTHH:MM:SS  ALLOWED  192.168.10.2  240.0.0.10     443        subnet-${REGION}-agw
YYYY-MM-DDTHH:MM:SS  ALLOWED  192.168.10.2  240.0.0.10     443        subnet-${REGION}-agw
YYYY-MM-DDTHH:MM:SS  ALLOWED  192.168.10.2  240.0.0.10     443        subnet-${REGION}-agw

Analiza los registros de DNS

Consulta los registros de consultas de DNS para las solicitudes resueltas por la zona de DNS privada (priv-zone-run).

gcloud logging read \
  "resource.type=\"dns_query\" AND resource.labels.target_name=\"priv-zone-run\"" \
  --project=${PROJ_ID} \
  --limit=10 \
  --format="table(
    timestamp.date(tz=LOCAL):label=TIMESTAMP,
    jsonPayload.queryName:label=QUERY_NAME,
    jsonPayload.queryType:label=TYPE,
    jsonPayload.rdata:label=RESPONSE_RDATA,
    jsonPayload.sourceNetwork:label=NETWORK,
    resource.labels.source_type:label=SRC_TYPE
  )"

Ten en cuenta que las búsquedas de DNS para el servicio de Cloud Run (mcp-weather...run.app) se originan en la red de VPC a través del intercambio de tráfico de DNS y se resuelven correctamente en el extremo interno de PSC para las APIs de Google (240.0.0.10).

TIMESTAMP            QUERY_NAME                                     TYPE  RESPONSE_RDATA                                                     NETWORK   SRC_TYPE
YYYY-MM-DDTHH:MM:SS  mcp-weather-${PROJ_NO}.${REGION}.run.app.  A     mcp-weather-${PROJ_NO}.${REGION}.run.app. 300     IN      a       240.0.0.10  vnet-${SLUG}  peering-zone
YYYY-MM-DDTHH:MM:SS  mcp-weather-${PROJ_NO}.${REGION}.run.app.  A     mcp-weather-${PROJ_NO}.${REGION}.run.app. 300     IN      a       240.0.0.10  vnet-${SLUG}  peering-zone
YYYY-MM-DDTHH:MM:SS  mcp-weather-${PROJ_NO}.${REGION}.run.app.  A     mcp-weather-${PROJ_NO}.${REGION}.run.app. 300     IN      a       240.0.0.10  vnet-${SLUG}  peering-zone
YYYY-MM-DDTHH:MM:SS  mcp-weather-${PROJ_NO}.${REGION}.run.app.  A     mcp-weather-${PROJ_NO}.${REGION}.run.app. 300     IN      a       240.0.0.10  vnet-${SLUG}  peering-zone

Aquí concluye la parte de aplicación… a continuación, veremos la sección Limpieza.

14. Limpieza

# delete agent runtime
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 agent resources
gcloud -q storage rm --recursive gs://${STAGING_BUCKET}

for ROLE in \
  "roles/aiplatform.user" \
  "roles/aiplatform.agentDefaultAccess" \
  "roles/agentregistry.viewer" \
  "roles/logging.logWriter" \
  "roles/monitoring.metricWriter" \
  "roles/browser"; do
  gcloud -q projects remove-iam-policy-binding ${PROJ_ID} \
    --member="${RE_AGENT_IDENTITY}" \
    --role="${ROLE}"
done

# next
# delete mcp (cloud run) resources
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} \
  --member="serviceAccount:${PROJ_NO}-compute@developer.gserviceaccount.com" \
  --role="roles/run.builder"

gcloud -q run services delete ${MCP_NAME} --region=${REGION}

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

gcloud -q iam service-accounts delete sa-${MCP_NAME}-invoker@${PROJ_ID}.iam.gserviceaccount.com

gcloud -q agent-registry services delete ${MCP_NAME} --location=${REGION}

# next
# delete gateway resources (policy binding must be deleted synchronously first)
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} --async

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

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

# next
# remove policies
export IAP_ETAG=$(gcloud beta iap web get-iam-policy --resource-type=agent-registry --endpoint=${ENDPOINT_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_REGISTRY_ID} \
  --region=${REGION}

# next
# delete dns resources
gcloud -q dns record-sets delete *.run.app --type=A --zone=priv-zone-run

gcloud -q dns managed-zones delete priv-zone-run

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

gcloud -q dns policies delete dns-policy-${SLUG}

# next
# delete router (includes nat) and psc resources
gcloud -q compute routers delete cr-nat-${SLUG}-${REGION} --region=${REGION}

gcloud -q compute forwarding-rules delete psc2gapis --global

gcloud -q compute addresses delete ip-psc2gapis --global

# next
# delete firewall resources
gcloud -q compute network-firewall-policies associations delete --name=fw-policy-bind-${SLUG} --firewall-policy=fw-policy-${SLUG} --global-firewall-policy

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

gcloud -q compute network-firewall-policies delete fw-policy-${SLUG} --global

# next
# delete network resources
gcloud -q compute networks subnets delete subnet-${REGION}-agw --region=${REGION}

gcloud -q compute networks subnets delete subnet-${REGION}-crun --region=${REGION}

gcloud -q compute network-attachments delete psc-na-${REGION}-agw --region=${REGION}

gcloud -q compute networks delete vnet-${SLUG}

# next
# clean up local working directories and generated configs
rm -rf cfg agent-weather mcp-weather

# end

Aquí concluye la sección de limpieza. A continuación, veremos la Conclusión.

15. Conclusión

¡Felicitaciones! Implementaste correctamente Agent Gateway y controlaste el tráfico saliente de los agentes de IA.

cosmopup

¡Cosmopup cree que los codelabs son lo mejor de lo mejor!

¿Qué sigue?

Si tienes comentarios, preguntas o correcciones, usa este formulario de comentarios.

¡Gracias!