1. Introducción
En este codelab, se explora la administración de entrada de Agent Gateway para los agentes de IA alojados en Agent Runtime.
Agent Gateway, que opera en modo de entrada (cliente a agente), admite el control de las comunicaciones entre los clientes (usuarios finales humanos, agentes de escritorio, IDE de codificación, agentes pares, etcétera) y los agentes alojados en Agent Runtime. Este modo se usa para proteger a los agentes de ataques de inyección de instrucciones entrantes o contenido dañino enviado por los clientes. Todo el tráfico entrante se procesa con extensiones de autorización y Model Armor para proteger el punto de entrada de la red para todas las interacciones del agente.
Qué compilarás
- Agent Gateway en modo de entrada (de cliente a agente)
- Extensión de autorización de Model Armor
- Agente de Agent Runtime ADK con identidad del agente
- Datos de archivos de Cloud Storage consultados por el agente a través de MCP
- Plantillas de Model Armor para analizar las instrucciones y respuestas de LLM
- Plantillas de Sensitive Data Protection para desidentificar datos
Fig. 1: Arquitectura del codelab
Qué aprenderá
- Cómo implementar Agent Gateway para filtrar el tráfico de entrada a un agente
- Cómo configurar la delegación y las extensiones de autorización de Model Armor
- Cómo crear e implementar plantillas personalizadas de Model Armor
- Cómo crear e implementar plantillas personalizadas de Sensitive Data Protection
- Cómo probar y validar las políticas de detección de LLM
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 (
bashozsh) con Google Cloud CLI (componentegcloud) instalado - Herramientas de línea de comandos:
git,curl,jq(procesador JSON), Python 3 yuv(administrador de paquetes de Python)
2. Conceptos
Dirección del tráfico y roles de puerta de enlace
Agent Gateway funciona como un proxy de red compatible con agentes, pero su rol operativo cambia según la dirección del tráfico:
- Modo de agente a cualquier lugar (salida): Funciona como un proxy de salida. Cuando un agente llama a herramientas de bases de datos externas, servidores de MCP de terceros o APIs, la puerta de enlace de salida administra el descubrimiento de servicios, el enrutamiento, el protocolo TLS mutuo (
mTLS), la inserción dinámica de credenciales de OAuth y el control de acceso a los extremos. - Modo de cliente a agente (entrada): Funciona como una puerta de enlace de seguridad de frontend. Su objetivo principal es proteger la entrada al tiempo de ejecución del agente interceptando y limpiando las instrucciones entrantes en lenguaje natural antes de que lleguen al código del agente o a los modelos de IA.
Ruta de acceso de entrada a Agent Runtime
Las solicitudes del cliente dirigidas a un agente alojado en Agent Runtime se destinan al endpoint de API de aiplatform.googleapis.com.
POST https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}:query
Este flujo de comunicación entrante al endpoint de API representa la ruta de entrada de cliente a agente.
Para proteger esta ruta de entrada administrada por Google, Agent Gateway se integra directamente con el Google Front End (GFE) en la capa de infraestructura de entrega de la API. Cuando se implementa un agente administrado en Agent Runtime, Google vincula de forma nativa la política de autorización de la puerta de enlace de entrada a las solicitudes entrantes del cliente en el perímetro de la red.
Fig. 2: Gobernanza de entrada con Agent Gateway a Agent Runtime
Dado que la inspección se realiza en el nivel de frontend antes de que las solicitudes ingresen en el entorno de ejecución del agente, esta arquitectura no introduce ninguna sobrecarga de red adicional ni latencia de salto interna. La infraestructura de frontend controla el ajuste de escala de forma automática, lo que elimina la necesidad de administrar rangos de IP internos, balanceadores de cargas o rutas de DNS personalizadas.
Limpieza intercalada de amenazas con Model Armor
La evaluación de las credenciales del llamador y la aplicación del control de acceso de IAM (roles/aiplatform.user) se controlan de forma nativa en el nivel de hosting de la API de aiplatform. La puerta de enlace de entrada en sí no realiza la autorización de identidad, sino que se enfoca en la seguridad del contenido con extensiones de autorización configuradas con un perfil de CONTENT_AUTHZ. La puerta de enlace actúa como un punto de aplicación de políticas intercalado, ya que intercepta las instrucciones en lenguaje natural en tránsito antes de que lleguen al bucle de razonamiento del agente de IA o al LLM subyacente.
Cuando un mensaje entrante del usuario llega al servicio de frontend, la puerta de enlace inicia una llamada ext_proc (procesamiento externo) al servicio de extensión de autorización regional de Model Armor, que transmite la llamada al plano de datos de Model Armor. Model Armor actúa como un firewall de lenguaje natural, ya que evalúa el texto en función de plantillas activas para detectar riesgos de seguridad:
- Intentos de inyección de instrucciones indirecta y jailbreak
- URLs maliciosas, lenguaje tóxico o contenido inseguro
- Filtración de datos sensibles y de información de identificación personal (
PII)
Si la plantilla incluye filtros de Sensitive Data Protection (SDP), Model Armor realiza una llamada gRPC adicional al servicio de Cloud SDP. Cloud SDP inspecciona la carga útil con la plantilla especificada, realiza cualquier desidentificación o ocultamiento solicitado y devuelve el resultado saneado a la cadena para que se reenvíe de forma segura.
Si se detecta un incumplimiento de política o una coincidencia de datos sensibles sin ocultar, la puerta de enlace bloquea o oculta la carga útil en el borde antes de ingresar al tiempo de ejecución. Como resultado, la aplicación del agente de IA en ejecución permanece protegida y nunca procesa cargas útiles maliciosas o sin editar.
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 |
| Habilita los servicios de la API de Google Cloud |
Redes y puerta de enlace |
| Aprovisiona Agent Gateway |
Service Extensions |
| Configura las extensiones de enrutamiento |
Seguridad de red |
| Implementa políticas de autorización |
Protección de datos sensibles |
| Administra las plantillas de inspección y desidentificación de SDP |
Model Armor |
| Crea y administra plantillas de seguridad |
Agent Platform |
| Implementa cargas de trabajo de Agent Runtime |
Cloud Storage |
| Administra los buckets de datos de clientes y de implementación |
Administración de IAM |
| Vincula permisos a nivel del proyecto para la identidad del agente |
Registros y auditoría |
| Cómo inspeccionar registros y registros de auditoría |
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:
- Cloud Shell en
shell.cloud.google.com - Una terminal local con la CLI de
gcloudinstalada
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"
echo ${SLUG}
echo ${REGION}
# create project vars (automatic)
export PROJ_ID=$(gcloud config list --format="value(core.project)")
export PROJ_NO=$(gcloud projects describe ${PROJ_ID} --format="value(projectNumber)")
export ORG_ID=$(gcloud projects get-ancestors ${PROJ_ID} --format="value(id)" | tail -n 1)
export USER_IDENTITY=$(gcloud config get-value account)
echo ${PROJ_ID}
echo ${PROJ_NO}
echo ${ORG_ID}
echo ${USER_IDENTITY}
# create resource vars (automatic)
export AGW_NAME="agw-${SLUG}-${REGION}-cta"
export AGW_URI="projects/${PROJ_ID}/locations/${REGION}/agentGateways/${AGW_NAME}"
export RE_AGENT_NAME="agent-crm"
export RE_AGENT_ID_SET="principalSet://agents.global.org-${ORG_ID}.system.id.goog/attribute.platformContainer/aiplatform/projects/${PROJ_NO}"
export STAGING_BUCKET="agent-staging-${PROJ_NO}"
export DATA_BUCKET="customer-data-${PROJ_NO}"
export MCP_URL="https://storage.mtls.googleapis.com/storage/mcp"
echo ${AGW_NAME}
echo ${AGW_URI}
echo ${RE_AGENT_NAME}
echo ${RE_AGENT_ID_SET}
echo ${STAGING_BUCKET}
echo ${DATA_BUCKET}
echo ${MCP_URL}
# create local dir for config files
mkdir -p cfg
Actualizar gcloud cli (recomendado)
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 \
dlp.googleapis.com
Aquí concluye la parte de configuración… a continuación, se abordará la sección Puerta de enlace.
4. Puerta de enlace
Implementa un Agent Gateway administrado por Google que opere en modo cliente a agente (CLIENT_TO_AGENT). A diferencia de las puertas de enlace de salida que requieren asociaciones del Registro de agentes para enrutar las llamadas salientes, la puerta de enlace de entrada se vincula directamente en el nivel de frontend para servir como punto de aplicación intercalado para las instrucciones entrantes dirigidas a Agent Runtime.
Si bien las políticas de salida suelen comenzar en modo DRY_RUN en la capa de puerta de enlace, la administración de contenido de entrada (CONTENT_AUTHZ) se implementa directamente en modo de aplicación forzosa. En cambio, el registro de solo auditoría o el bloqueo activo detallados se controlan de forma ascendente dentro de las plantillas individuales de Model Armor.
Crear puerta de enlace
# create agent gateway config file
cat > cfg/${AGW_NAME}.yaml <<EOF
name: ${AGW_NAME}
protocols:
- MCP
googleManaged:
governedAccessPath: CLIENT_TO_AGENT
EOF
# import agent gateway config file (create gateway)
gcloud network-services agent-gateways import ${AGW_NAME} \
--source="cfg/${AGW_NAME}.yaml" \
--location=${REGION}
Verifica la puerta de enlace
# list agent gateways (in region)
gcloud network-services agent-gateways list --location=${REGION}
# show agent gateway details (verify deployment state)
gcloud network-services agent-gateways describe ${AGW_NAME} --location=${REGION}
Aquí concluye la sección de la puerta de enlace. A continuación, veremos la sección de Model Armor.
5. Model Armor
Plantillas de SDP
Crea una plantilla de inspección y desidentificación de Sensitive Data Protection (SDP) para usarla en la plantilla de respuesta de Model Armor. Esta configuración marca los números de seguridad social de EE.UU. (NSS) para su ocultamiento.
Crea una plantilla de inspección
La plantilla de inspección identifica la información sensible (US_SOCIAL_SECURITY_NUMBER) en los datos.
# create inspect template
curl -fsS -X POST "https://dlp.googleapis.com/v2/projects/${PROJ_ID}/locations/${REGION}/inspectTemplates" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" -H "x-goog-user-project: ${PROJ_ID}" \
-d @- << EOF
{
"templateId": "agw-ssn-inspect-template",
"inspectTemplate": {
"displayName": "ssn inspect template",
"inspectConfig": {
"infoTypes": [
{ "name": "US_SOCIAL_SECURITY_NUMBER" }
],
"minLikelihood": "POSSIBLE"
}
}
}
EOF
Crea una plantilla de desidentificación
La plantilla de desidentificación especifica la transformación que se aplicará a los números de seguridad social que encuentre la plantilla de inspección. En este caso, la transformación consiste en reemplazar el NSS por el infotipo.
# create de-identify template
curl -fsS -X POST "https://dlp.googleapis.com/v2/projects/${PROJ_ID}/locations/${REGION}/deidentifyTemplates" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" -H "x-goog-user-project: ${PROJ_ID}" \
-d @- << EOF
{
"templateId": "agw-ssn-redaction-template",
"deidentifyTemplate": {
"displayName": "SSN Redaction Template",
"deidentifyConfig": {
"infoTypeTransformations": {
"transformations": [{
"primitiveTransformation": { "replaceWithInfoTypeConfig": {} }
}]
}
}
}
}
EOF
Verifica las plantillas de SDP
# get (describe) inspect template
curl -fsS -X GET "https://dlp.googleapis.com/v2/projects/${PROJ_ID}/locations/${REGION}/inspectTemplates" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" -H "x-goog-user-project: ${PROJ_ID}" | jq
# get (describe) de-identify template
curl -fsS -X GET "https://dlp.googleapis.com/v2/projects/${PROJ_ID}/locations/${REGION}/deidentifyTemplates" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" -H "x-goog-user-project: ${PROJ_ID}" | jq
Plantillas de Model Armor
El endpoint predeterminado de la API de Model Armor es global (modelarmor.googleapis.com). Sin embargo, los recursos de Model Armor para plantillas y motores de evaluación se localizan en regiones geográficas específicas. El proxy de extremo regional (REP) de Google Cloud, o extremo de API regional, para Model Armor es https://modelarmor.${LOCATION}.rep.googleapis.com/.
De forma predeterminada, cuando se ejecuta gcloud model-armor ..., la CLI intenta enviar solicitudes a la API al extremo global estándar (https://modelarmor.googleapis.com/). Se usa una anulación del extremo de la API para redireccionar todas las solicitudes HTTP del SDK o la CLI de Model Armor directamente al nivel de la API regional rep.googleapis.com en el que se crean, almacenan y consultan esos modelos vinculados a la ubicación.
Cómo establecer la anulación de la API
# set api endpoint override per location
gcloud config set api_endpoint_overrides/modelarmor "https://modelarmor.${REGION}.rep.googleapis.com/"
Verifica la anulación de la API
# view api overrides on active gcloud config
gcloud config list api_endpoint_overrides/
Crea una plantilla de filtro de solicitudes
Crea una plantilla de filtro de solicitudes para bloquear la incitación al odio o a la violencia, el hostigamiento, el contenido sexual explícito y los ataques de inyección de URI. Se habilitará el registro para capturar información detallada sobre los eventos relacionados con la aplicación de políticas. También se configuran códigos y mensajes de error personalizados para cuando se bloquea una solicitud.
# create model armor template (request)
gcloud beta model-armor templates create ${AGW_NAME}-modar-req-template \
--project=${PROJ_ID} \
--location=${REGION} \
--rai-settings-filters='[
{ "filterType": "HATE_SPEECH", "confidenceLevel": "MEDIUM_AND_ABOVE" },
{ "filterType": "HARASSMENT", "confidenceLevel": "MEDIUM_AND_ABOVE" },
{ "filterType": "SEXUALLY_EXPLICIT", "confidenceLevel": "MEDIUM_AND_ABOVE" }
]' \
--pi-and-jailbreak-filter-settings-enforcement=enabled \
--pi-and-jailbreak-filter-settings-confidence-level=medium-and-above \
--template-metadata-enforcement-type=INSPECT_AND_BLOCK \
--malicious-uri-filter-settings-enforcement=enabled \
--template-metadata-custom-llm-response-safety-error-code=798 \
--template-metadata-custom-llm-response-safety-error-message="ahoy! model response blocked by content filter :(" \
--template-metadata-custom-prompt-safety-error-code=799 \
--template-metadata-custom-prompt-safety-error-message="ahoy! the request was blocked by ye content filter... so rephrase the prompt and try again!" \
--template-metadata-ignore-partial-invocation-failures \
--template-metadata-log-operations \
--template-metadata-log-sanitize-operations
Crea una plantilla de filtro de respuestas
Crea una plantilla de filtro de respuesta para bloquear el mismo contenido que la plantilla de filtro de solicitud. DLP está configurado en la etapa de respuesta para anonimizar los números de seguridad social de los mensajes que regresan al cliente desde el agente.
# create model armor template (response)
gcloud beta model-armor templates create ${AGW_NAME}-modar-resp-template \
--project=${PROJ_ID} \
--location=${REGION} \
--rai-settings-filters='[
{ "filterType": "HATE_SPEECH", "confidenceLevel": "MEDIUM_AND_ABOVE" },
{ "filterType": "HARASSMENT", "confidenceLevel": "MEDIUM_AND_ABOVE" },
{ "filterType": "SEXUALLY_EXPLICIT", "confidenceLevel": "MEDIUM_AND_ABOVE" }
]' \
--malicious-uri-filter-settings-enforcement=enabled \
--advanced-config-inspect-template=projects/${PROJ_ID}/locations/${REGION}/inspectTemplates/agw-ssn-inspect-template \
--advanced-config-deidentify-template=projects/${PROJ_ID}/locations/${REGION}/deidentifyTemplates/agw-ssn-redaction-template \
--template-metadata-enforcement-type=INSPECT_AND_BLOCK \
--template-metadata-custom-llm-response-safety-error-code=798 \
--template-metadata-custom-llm-response-safety-error-message="ahoy! model response blocked by content filter :(" \
--template-metadata-custom-prompt-safety-error-code=799 \
--template-metadata-custom-prompt-safety-error-message="ahoy! the request was blocked by ye content filter... so rephrase the prompt and try again!" \
--template-metadata-ignore-partial-invocation-failures \
--template-metadata-log-operations \
--template-metadata-log-sanitize-operations
Verifica plantillas de Model Armor
# list model armor templates
gcloud model-armor templates list --location=${REGION}
# show request filter template details
gcloud model-armor templates describe ${AGW_NAME}-modar-req-template --location=${REGION}
# show response filter template details
gcloud model-armor templates describe ${AGW_NAME}-modar-resp-template --location=${REGION}
Permisos de IAM
Model Armor realiza llamadas a la API para invocar el servicio de Sensitive Data Protection (SDP). Otorga permisos de IAM a la identidad del servicio de Model Armor para usar las plantillas de inspección y desidentificación de SDP.
Vincula la política de IAM para Sensitive Data Protection
# grant dlp (sdp) user role to the model armor service identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="serviceAccount:service-${PROJ_NO}@gcp-sa-modelarmor.iam.gserviceaccount.com" \
--role="roles/dlp.user"
Verifica los permisos de IAM
# show iam policy for all dlp (sdp) roles on project
gcloud projects get-iam-policy ${PROJ_ID} \
--flatten="bindings[].members" \
--filter="bindings.role:roles/dlp" \
--format="table(bindings.role:label=ROLE, bindings.members:label=PRINCIPAL_IDENTITY)"
Aquí concluye la sección de Model Armor. A continuación, veremos la sección de Autorización.
6. Autorización
Permisos de IAM
Para inspeccionar el tráfico intercalado con Model Armor, el agente de servicio de Service Extensions (DEP) requiere vinculaciones de IAM explícitas (incluso entre recursos dentro del mismo proyecto):
roles/modelarmor.calloutUseryroles/serviceusage.serviceUsageConsumer: Se otorgan en el proyecto de la puerta de enlace para permitir los textos destacados de inspección intercalados.roles/modelarmor.user: Se otorga en el proyecto de plantilla para permitir el acceso y la evaluación de las plantillas de Model Armor.
Vincula la política de IAM para Model Armor
# grant model armor callout user role to dep (service extension) service agent
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="serviceAccount:service-${PROJ_NO}@gcp-sa-dep.iam.gserviceaccount.com" \
--role="roles/modelarmor.calloutUser"
# grant service usage consumer role to dep (service extension) service agent
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="serviceAccount:service-${PROJ_NO}@gcp-sa-dep.iam.gserviceaccount.com" \
--role="roles/serviceusage.serviceUsageConsumer"
# grant model armor user role to dep (service extension) service agent
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="serviceAccount:service-${PROJ_NO}@gcp-sa-dep.iam.gserviceaccount.com" \
--role="roles/modelarmor.user"
Verifica los permisos de IAM
# show iam policy on project for dep (service extension) service agent
gcloud projects get-iam-policy ${PROJ_ID} \
--flatten="bindings[].members" \
--filter="bindings.members:serviceAccount:service-${PROJ_NO}@gcp-sa-dep.iam.gserviceaccount.com" \
--format="table(bindings.members:label=PRINCIPAL_IDENTITY, bindings.role:label=ROLE)"
Extensión de autorización
La configuración de la extensión de autorización para Agent Gateway define los parámetros de configuración de integración que se aplicarán al tráfico de cargas útiles entrantes y salientes. La configuración define el servicio de procesamiento externo (service) que hace referencia a la API regional de Model Armor y se vincula a las plantillas de solicitud y respuesta específicas con el campo de metadatos model_armor_settings.
Crea una extensión de autorización
# create authz extension config file (enforced mode)
cat > cfg/${AGW_NAME}-svc-ext-authz-modar.yaml <<EOF
name: ${AGW_NAME}-svc-ext-authz-modar
service: modelarmor.${REGION}.rep.googleapis.com
metadata:
model_armor_settings: '[
{
"request_template_id": "projects/${PROJ_ID}/locations/${REGION}/templates/${AGW_NAME}-modar-req-template",
"response_template_id": "projects/${PROJ_ID}/locations/${REGION}/templates/${AGW_NAME}-modar-resp-template"
}
]'
failOpen: true
timeout: 5s
EOF
Importa la extensión de autorización
# import authz extension file
gcloud service-extensions authz-extensions import ${AGW_NAME}-svc-ext-authz-modar \
--source=cfg/${AGW_NAME}-svc-ext-authz-modar.yaml \
--location=${REGION}
Verifica la extensión de autorización
# list authz extensions
gcloud service-extensions authz-extensions list --location=${REGION}
# show authz extension details
gcloud service-extensions authz-extensions describe ${AGW_NAME}-svc-ext-authz-modar \
--location=${REGION}
Política de autorización
Las políticas de autorización usan perfiles de políticas para determinar el tipo de evaluación que se realiza. Si bien los perfiles basados en solicitudes (REQUEST_AUTHZ) evalúan los encabezados HTTP, esta configuración usa un perfil de autorización basado en el contenido (CONTENT_AUTHZ) para vincular la extensión de Model Armor a la puerta de enlace para una inspección profunda de la carga útil.
Crea una política de autorización
# create authz policy config file (attach dry-run authz extension)
cat > cfg/${AGW_NAME}-authz-policy-modar.yaml <<EOF
name: ${AGW_NAME}-authz-policy-modar
target:
resources:
- "projects/${PROJ_ID}/locations/${REGION}/agentGateways/${AGW_NAME}"
policyProfile: CONTENT_AUTHZ
action: CUSTOM
customProvider:
authzExtension:
resources:
- "projects/${PROJ_ID}/locations/${REGION}/authzExtensions/${AGW_NAME}-svc-ext-authz-modar"
EOF
Importa 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-modar \
--source=cfg/${AGW_NAME}-authz-policy-modar.yaml \
--location=${REGION}
Verifica la política de autorización
# list authz policies
gcloud beta network-security authz-policies list --location=${REGION}
# show authz policy details
gcloud beta network-security authz-policies describe ${AGW_NAME}-authz-policy-modar \
--location=${REGION}
Con esto, concluye la parte de autorización… a continuación, veremos la sección Codebase.
7. Base de código
El código del agente y los datos de archivo 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.
Recupera artefactos remotos
# clone remote repository to temp local dir
git clone https://github.com/GoogleCloudPlatform/cloud-networking-solutions.git ./temp_agw_cuj_arun_ingress_modar
# copy agent runtime and endpoint definitions to working project dir
cp -r temp_agw_cuj_arun_ingress_modar/codelabs/agw-cuj-arun-ingress-modar/agent-crm ./agent-crm
# remove temporary directory
rm -rf temp_agw_cuj_arun_ingress_modar
Agent Runtime usa un bucket de almacenamiento para la etapa de pruebas para subir, compilar e implementar el código de la aplicación del agente empaquetado y sus artefactos de dependencia.
Crea un bucket de almacenamiento para la etapa de pruebas
# create storage bucket
gcloud storage buckets create gs://${STAGING_BUCKET} --location=${REGION}
Verifica el bucket de almacenamiento
# list storage buckets
gcloud storage buckets list --format="value(storage_url)"
Aquí concluye la sección sobre la base de código. A continuación, se abordará la sección Datos del cliente de GCS.
Datos del cliente
Crea un bucket de Cloud Storage para almacenar datos del cliente. El agente leerá directamente con la biblioteca cliente estándar de Google Cloud que llama al extremo del MCP de Cloud Storage.
Crea un bucket de almacenamiento para los datos del cliente
# create storage bucket
gcloud storage buckets create gs://${DATA_BUCKET} --location=${REGION}
Verifica el bucket de almacenamiento
# list storage buckets
gcloud storage buckets list --format="value(storage_url)"
Subir datos de clientes
# copy local data to bucket
gcloud storage cp -r ./agent-crm/data/* gs://${DATA_BUCKET}/
Verifica los datos del cliente
# list bucket objects
gcloud storage ls gs://${DATA_BUCKET}/ --long
Aquí concluye la sección sobre los datos del cliente de GCS. A continuación, se abordará la sección del agente de ADK.
8. Agente de ADK
El agente del ADK de agent-crm 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_IDENTITYpara aprovisionar una identidad principal única basada en SPIFFE para el agente"client_to_agent_config": {"agent_gateway": "${AGW_URI}"}para dirigir todo el tráfico entrante del agente a la ruta de aplicación y evaluación de políticas de Agent Gateway
También se le pasa al agente la URL del servidor MCP de mTLS para el servidor MCP de Cloud Storage y el nombre del bucket de datos para invocar la herramienta de MCP de GCS a través de una conexión segura.
Implementa el agente
# deploy agent
uv --directory agent-crm run python3 deploy_agent.py \
--project=${PROJ_ID} \
--region=${REGION} \
--src-dir=./agent \
--staging-bucket=${STAGING_BUCKET} \
--display-name="${RE_AGENT_NAME}" \
--description="agent for customer data" \
--mcp-server-url="${MCP_URL}" \
--data-bucket=${DATA_BUCKET} \
--enable-telemetry \
--enable-agent-identity \
--agent-gateway-ingress=${AGW_URI} \
--allow-token-sharing
Verifica la implementación
Recupera los signos vitales de la implementación
# fetch agent runtime (reasoning engine) resource id
export RE_ENGINE_ID=$(curl -s -X GET "https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
| jq -r --arg name "${RE_AGENT_NAME}" '.reasoningEngines[] | select(.displayName==$name) | .name | split("/") | last')
echo ${RE_ENGINE_ID}
# fetch agent runtime (reasoning engine) agent identity
export RE_AGENT_IDENTITY=$(gcloud agent-registry agents list \
--project=${PROJ_ID} --location=${REGION} --filter="displayName=${RE_AGENT_NAME}" \
--format="value(attributes.'agentregistry.googleapis.com/system/RuntimeIdentity'.principal)")
echo ${RE_AGENT_IDENTITY}
Verifica la configuración de la puerta de enlace
# show agent runtime config details (gateway config)
curl -s -X GET "https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
| jq '{displayName: .displayName, name: .name, effectiveIdentity: .spec.effectiveIdentity, agentGatewayConfig: .spec.deploymentSpec.agentGatewayConfig}'
Permisos de IAM
Vincula políticas de IAM para la identidad del agente
# grant mcp tool user role to agent set (all agent runtime agents in project)
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="${RE_AGENT_ID_SET}" \
--role="roles/mcp.toolUser"
# grant storage object viewer role to agent identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="${RE_AGENT_IDENTITY}" \
--role="roles/storage.objectViewer"
# grant aiplatform user role to agent identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="${RE_AGENT_IDENTITY}" \
--role="roles/aiplatform.user"
# grant cloudtrace agent role to agent identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="${RE_AGENT_IDENTITY}" \
--role="roles/cloudtrace.agent"
# grant cloud monitoring metric writer role to agent identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="${RE_AGENT_IDENTITY}" \
--role="roles/monitoring.metricWriter"
# grant cloud logging log writer role to agent identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="${RE_AGENT_IDENTITY}" \
--role="roles/logging.logWriter"
# grant telemetry writer role to agent identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="${RE_AGENT_IDENTITY}" \
--role="roles/telemetry.writer"
# grant service usage consumer role to agent identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="${RE_AGENT_IDENTITY}" \
--role="roles/serviceusage.serviceUsageConsumer"
# grant browser role to agent identity
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="${RE_AGENT_IDENTITY}" \
--role="roles/browser"
Verifica los permisos de IAM
# show agent identity roles on project
gcloud projects get-iam-policy ${PROJ_ID} \
--flatten="bindings[].members" \
--filter="bindings.members:${RE_AGENT_IDENTITY}" \
--format="table(bindings.members.sub('^.*locations/', 'principal://agents.[...]/locations/'):label=PRINCIPAL_IDENTITY, bindings.role:label=ROLE)"
# show agent set roles on project
gcloud projects get-iam-policy ${PROJ_ID} \
--flatten="bindings[].members" \
--filter="bindings.members:${RE_AGENT_ID_SET}" \
--format="table(bindings.members.sub('^.*platformContainer/', 'principalSet://agents.[...]/'):label=PRINCIPAL_IDENTITY, bindings.role:label=ROLE)"
Aquí concluye la sección del agente del ADK… a continuación, se muestra la sección Prueba.
9. Prueba
Envía consultas desde la CLI
Prueba una instrucción segura
# post query to agent streamQuery
curl --no-buffer -s -X POST "https://${REGION}-aiplatform.googleapis.com/v1beta1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}:streamQuery" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" -H "X-Goog-User-Project: ${PROJ_ID}" \
-d @- <<EOF | jq -r --unbuffered 'if type == "array" then .[] else . end | select(.content.parts != null) | .content.parts[].text // empty'
{
"input": {
"message": "what are the names of our west customers?",
"user_id": "test-user"
}
}
EOF
Deberías ver una respuesta como la siguiente… "Nuestros clientes del oeste son Bob Johnson y Alice Brown".
Prueba un activador de ocultamiento
# post query to agent streamQuery
curl --no-buffer -s -X POST "https://${REGION}-aiplatform.googleapis.com/v1beta1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}:streamQuery" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" -H "X-Goog-User-Project: ${PROJ_ID}" \
-d @- <<EOF | jq -r --unbuffered 'if type == "array" then .[] else . end | select(.content.parts != null) | .content.parts[].text // empty'
{
"input": {
"message": "what are ssn's for bob johnson and alice brown?",
"user_id": "test-user"
}
}
EOF
Probar otra instrucción segura
# post query to agent streamQuery
curl --no-buffer -s -X POST "https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}:streamQuery" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" -H "X-Goog-User-Project: ${PROJ_ID}" \
-d @- <<EOF | jq -r --unbuffered 'if type == "array" then .[] else . end | select(.content.parts != null) | .content.parts[].text // empty'
{
"input": {
"message": "what are bob johnson's and alice brown's email addresses?",
"user_id": "test-user"
}
}
EOF
Registros de auditoría
Visualiza los registros de seguimiento
Cuando la telemetría está habilitada, Agent Runtime transmite eventos estructurados que representan las búsquedas de los usuarios, los parámetros de las herramientas, los flujos de ejecución y los resultados de la elección del modelo.
# show agent runtime (reasoning engine) telemetry and trace logs
gcloud logging read \
"logName:\"projects/${PROJ_ID}/logs/aiplatform.googleapis.com%2Freasoning_engine_stdout\" AND labels.managed-by=\"reasoning-engine\"" \
--project=${PROJ_ID} \
--limit=15 \
--format="table(
timestamp.date(format=\"%I:%M:%S %p\", tz=LOCAL):label=TIME,
trace.basename().sub('^(.{8}).*$', '\\1'):label=TRACE_ID,
labels.\"event.name\".scope(-1):label=EVENT,
jsonPayload.content.role:label=ROLE,
jsonPayload.content.parts[0].text:label=TEXT_CONTENT,
jsonPayload.content.parts[0].function_call.name:label=TOOL_CALL
)"
TRACE_ID agrupa la búsqueda del usuario, las llamadas a herramientas intermedias y las decisiones del modelo en una sola línea de tiempo:
TIME TRACE_ID EVENT ROLE TEXT_CONTENT TOOL_CALL
HH:MM:SS PM 3070a1fd gen_ai.choice model Bob Johnson's SSN is 219-45-7895.
Alice Brown's SSN is 219-45-7896.
HH:MM:SS PM 3070a1fd gen_ai.user.message user
HH:MM:SS PM 3070a1fd gen_ai.user.message model read_customer_file
HH:MM:SS PM 3070a1fd gen_ai.user.message user
HH:MM:SS PM 3070a1fd gen_ai.user.message model read_customer_file
HH:MM:SS PM 3070a1fd gen_ai.user.message user
HH:MM:SS PM 3070a1fd gen_ai.user.message model list_customer_files
HH:MM:SS PM 3070a1fd gen_ai.user.message user what are ssn's for bob johnson and alice brown?
HH:MM:SS PM 3070a1fd gen_ai.system.message
HH:MM:SS PM 3070a1fd gen_ai.choice model read_customer_file
Consulta los registros de limpieza de Model Armor
Estos registros muestran la amenaza bidireccional intercalada en tiempo real y el saneamiento que realiza Model Armor a medida que el tráfico fluye a través de Agent Gateway.
# show model armor logs
gcloud logging read \
"logName:\"projects/${PROJ_ID}/logs/modelarmor.googleapis.com%2Fsanitize_operations\"" \
--project=${PROJ_ID} \
--limit=50 \
--format="table(
timestamp.date(format=\"%I:%M:%S %p\", tz=LOCAL):label=TIME,
jsonPayload.sanitizationResult.sanitizationVerdict:label=VERDICT,
jsonPayload.sanitizationInput.byteItem.byteData.decode(base64).decode(utf-8).sub('\n', ' \\\\\\\\n ').trailoff(123):label=INPUT_DATA
)"
Observa la entrada de registro de la solicitud bloqueada y saneada.
TIME VERDICT INPUT_DATA
HH:MM:SS PM MODEL_ARMOR_SANITIZATION_VERDICT_ALLOW Bob Johnson's email address is bob.j@example.com. \n Alice Brown's email address is alice.b...
HH:MM:SS PM MODEL_ARMOR_SANITIZATION_VERDICT_ALLOW what are bob johnson's and alice brown's email addresses?
HH:MM:SS PM MODEL_ARMOR_SANITIZATION_VERDICT_BLOCK 6��
HH:MM:SS PM MODEL_ARMOR_SANITIZATION_VERDICT_ALLOW what are ssn's for bob johnson and alice brown?
HH:MM:SS PM MODEL_ARMOR_SANITIZATION_VERDICT_ALLOW Our west customers are: Bob Johnson and Alice Brown.
HH:MM:SS PM MODEL_ARMOR_SANITIZATION_VERDICT_ALLOW what are the names of our west customers?
Aquí concluye la sección de prueba. A continuación, se encuentra la sección de limpieza.
10. Limpieza
# remove agent iam bindings
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_IDENTITY}" --role="roles/storage.objectViewer"
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_IDENTITY}" --role="roles/aiplatform.user"
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_IDENTITY}" --role="roles/cloudtrace.agent"
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_IDENTITY}" --role="roles/monitoring.metricWriter"
# next
# remove more agent and agent set iam bindings
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_IDENTITY}" --role="roles/logging.logWriter"
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_IDENTITY}" --role="roles/telemetry.writer"
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_IDENTITY}" --role="roles/serviceusage.serviceUsageConsumer"
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_IDENTITY}" --role="roles/browser"
# next
# remove rest of iam bindings
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="${RE_AGENT_ID_SET}" --role="roles/mcp.toolUser"
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} --member="serviceAccount:service-${PROJ_NO}@gcp-sa-modelarmor.iam.gserviceaccount.com" --role="roles/dlp.user"
# next
# delete agent runtime (reasoning engine) agent
curl -s -X DELETE "https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}?force=true" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json"
# next
# delete storage
gcloud -q storage rm --recursive gs://${STAGING_BUCKET}
gcloud -q storage rm --recursive gs://${DATA_BUCKET}
# next
# delete authz resources
gcloud -q beta network-security authz-policies delete ${AGW_NAME}-authz-policy-modar --location=${REGION}
gcloud -q beta service-extensions authz-extensions delete ${AGW_NAME}-svc-ext-authz-modar --location=${REGION} --async
# next
# remove dep (service extensions) service agent iam bindings
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} \
--member="serviceAccount:service-${PROJ_NO}@gcp-sa-dep.iam.gserviceaccount.com" \
--role="roles/modelarmor.calloutUser"
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} \
--member="serviceAccount:service-${PROJ_NO}@gcp-sa-dep.iam.gserviceaccount.com" \
--role="roles/serviceusage.serviceUsageConsumer"
gcloud -q projects remove-iam-policy-binding ${PROJ_ID} \
--member="serviceAccount:service-${PROJ_NO}@gcp-sa-dep.iam.gserviceaccount.com" \
--role="roles/modelarmor.user"
# next
# delete model armor templates
gcloud -q model-armor templates delete ${AGW_NAME}-modar-resp-template --location=${REGION}
gcloud -q model-armor templates delete ${AGW_NAME}-modar-req-template --location=${REGION}
# unset model armor api endpoint override
gcloud config unset api_endpoint_overrides/modelarmor
# next
# delete sdp (dlp) templates
curl -fsS -X DELETE "https://dlp.googleapis.com/v2/projects/${PROJ_ID}/locations/${REGION}/deidentifyTemplates/agw-ssn-redaction-template" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "x-goog-user-project: ${PROJ_ID}"
curl -fsS -X DELETE "https://dlp.googleapis.com/v2/projects/${PROJ_ID}/locations/${REGION}/inspectTemplates/agw-ssn-inspect-template" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "x-goog-user-project: ${PROJ_ID}"
# next
# delete agent gateway ingress
gcloud -q network-services agent-gateways delete ${AGW_NAME} --location=${REGION} --async
# end
Aquí concluye la sección de limpieza. A continuación, se encuentra la sección de Conclusión.
11. Conclusión
¡Felicitaciones! Implementaste correctamente Agent Gateway y controlaste el tráfico entrante a un agente de IA.

Cosmopup cree que los codelabs son geniales.
¿Qué sigue?
- Consulta la documentación de Gemini Enterprise Agent Platform para obtener información sobre funciones avanzadas y tutoriales.
- Configura barreras de seguridad de Model Armor en Agent Gateway para mayor seguridad potenciada por IA
- Explora las políticas de administración semántica para aplicar reglas comerciales y de cumplimiento a las búsquedas en lenguaje natural
Si tienes comentarios, preguntas o correcciones, usa este formulario de comentarios.
¡Gracias!