1. 简介
本 Codelab 探讨了 Agent Gateway 出站流量治理,以供 AI 智能体访问远程 Google Cloud Model Context Protocol (MCP) 服务器。
从独立聊天机器人到具有多智能体工作流的自主系统,AI 应用可以动态调用外部工具。为代理提供受控的数据库查询、网页内容提取和操作执行权限,对于确保代理的安全性和高效性至关重要。不过,在企业环境中,确保代理工具执行的安全性是一项挑战。如果代理具有直接网络访问权限,提示注入攻击或模型幻觉可能会导致代理泄露敏感数据或运行破坏性命令。
为了大规模管理自主智能体,Agent Gateway 提供了一个集中式零信任强制执行点,直接集成到 Agent Platform 架构中。Agent Gateway 不依赖于每个应用或代理代码特有的自定义实现,而是在平台级强制执行网络路由、代理治理和运行时安全性。
当 Agent Gateway 以出站流量(代理到任何位置)模式运行时,它会代理配置为使用该网关的代理的所有出站请求。每个代理工作负载请求都使用唯一的代理身份进行身份验证,并使用 Identity-Aware Proxy (IAP) 政策进行授权。系统会动态解码和检查 MCP 工具调用,以强制执行政策。安全管理员可以集中强制执行精细的权限,以确保代理只能调用经过批准的端点和方法。
构建内容
- 出站流量(代理到任意目的地)模式下的 Agent Gateway
- Identity-Aware Proxy (IAP) 授权扩展程序
- 具有代理身份的 Agent Runtime ADK 代理
- 包含 Google API 和 MCP 端点的代理注册表
- 使用 IAM 访问权限控制的授权政策
- 要使用 MCP 查询的 BigQuery 数据集
图 1. Codelab 架构
学习内容
- 如何在结构化配置序列中部署 Agent Gateway
- 如何将授权政策从试运行模式过渡到强制执行模式
- 如何在代理注册表中注册 Google API 端点和 MCP 服务器
- 如何审核 Agent Gateway 日志以验证出站流量治理
所需条件
- 启用了结算功能的 Google Cloud 项目
- 用于预配网络服务、BigQuery 数据集和 Agent Platform 资源的 IAM 权限
- 安装了 Google Cloud CLI(
gcloud和bq组件)的 POSIX 兼容 shell(bash或zsh) - 命令行工具:
git、curl、jq(JSON 处理器)、Python 3 和uv(Python 软件包管理器)
2. 概念
部署序列
在部署具有治理控制功能的 Agent Gateway 时,请务必遵循结构化的配置顺序,以便代理在初始化时能够访问必要的资源,并成功发送网络请求。
此 Codelab 使用以下部署顺序:
- 以试运行模式启动:如果代理运行时配置为在网关完全预配之前将出站调用路由到网关,则工作负载将无法初始化。首先以
DRY_RUN模式配置网关授权扩展程序,可确保当代理流量到达网关时,不会丢弃任何请求。 - 注册所有服务:使用代理网关的所有代理、MCP 服务器和端点都必须在代理注册表中注册。对于任何未注册的来源或目的地,系统都会拒绝请求。部署在 Agent Runtime 和 Google MCP 服务器上的代理会自动注册。任何 Google API 端点或自定义 MCP 服务器都必须手动注册。
- 强制执行授权政策:授权政策用于通过向代理身份主账号授予
roles/iap.egressor角色并将其绑定到目标注册表资源,来允许已注册的代理访问代理组件。使用试运行模式评估代理行为,然后定义政策以允许所选的出站流量通过网关。政策到位后,切换到ENFORCED模式,以使网关能够主动强制执行治理政策。
图 2. 部署序列
出站流量路由拓扑
网关通常管理流向后端服务的入站流量(入口)。Agent Gateway 以出口(智能体到任意位置)模式运行,充当智能体工作负载的集中式零信任出站代理。
当 AI 应用或智能体工作负载尝试调用外部工具或 API 时,Agent Gateway 会拦截出站请求,并根据治理政策对其进行评估,然后再将其路由到目标位置:
- 专用网络 (VPC):出站流量的目标是内部企业 API、微服务、托管在专用 VPC 中的数据库,以及可通过混合连接访问的本地或跨云网络。
- 外部网络(互联网):以第三方 Web 服务、SaaS API 或公共端点为目标的出站流量。
- AI 服务和 Agent Platform:出站流量,目标是受管理的 Google Cloud API、基础模型、Google MCP 端点(例如 BigQuery)和平台治理服务(Agent Registry 和 IAP 政策)。
图 3. Agent Gateway 出站流量路由拓扑
此 Codelab 的重点是智能体运行时上自定义智能体的出站流量,该流量以 BigQuery 的远程 Google MCP 服务器端点为目标。
3. 设置
所需 IAM 角色
您必须拥有以下角色,才能在此 Codelab 中创建资源:
类别 | 所需 IAM 角色 (ID) | 说明 |
API 管理 |
| 启用 Google Cloud API 服务 |
网络和网关 |
| 配置 Agent Gateway |
Service Extensions |
| 配置路由扩展程序 |
网络安全 |
| 部署授权政策 |
Agent Registry |
| 目录允许的主机 |
Vertex AI 和代理 |
| 部署 Agent Runtime 工作负载 |
出站流量政策 |
| 应用 |
BigQuery |
| 设置架构和测试数据集 |
Cloud Storage |
| 管理部署过渡存储分区 |
日志和审核 |
| 检查轨迹和审核日志 |
或者,您也可以使用广泛的基本角色(例如 roles/admin)或旧版角色 roles/owner。
访问您的项目
本 Codelab 使用单个 Google Cloud 项目。配置步骤使用 gcloud CLI 和 Linux shell 命令。
首先,访问 Google Cloud 云项目命令行:
- Cloud Shell 位于
shell.cloud.google.com,或者 - 安装了
gcloudCLI 的本地终端
设置项目 ID
gcloud config set project SET_YOUR_PROJECT_ID_HERE
验证会话
# login to gcloud cli
gcloud auth login
# login for gcloud api
gcloud auth application-default login
设置 shell 环境变量
# set custom var for slug (eg, "foo") and region preference
export SLUG="foo"
export REGION="us-central1"
export MREGION="us"
echo ${SLUG}
echo ${REGION}
echo ${MREGION}
# create project vars (automatic)
export PROJ_ID=$(gcloud config list --format="value(core.project)")
export PROJ_NO=$(gcloud projects describe ${PROJ_ID} --format="value(projectNumber)")
export ORG_ID=$(gcloud projects get-ancestors ${PROJ_ID} --format="value(id)" | tail -n 1)
echo ${PROJ_ID}
echo ${PROJ_NO}
echo ${ORG_ID}
# create resource vars (automatic)
export AGW_NAME="agw-${SLUG}-${REGION}-ata"
export AGW_URI="projects/${PROJ_ID}/locations/${REGION}/agentGateways/${AGW_NAME}"
export RE_AGENT_NAME="agent-dj"
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}"
echo ${AGW_NAME}
echo ${AGW_URI}
echo ${RE_AGENT_NAME}
echo ${RE_AGENT_ID_SET}
echo ${STAGING_BUCKET}
# create local dir for config files
mkdir -p cfg
启用 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 \
discoveryengine.googleapis.com
设置部分到此结束…接下来请参阅网关部分。
4. 网关
在强制执行访问权限控制之前,请部署 Agent Gateway 并在 DRY_RUN 模式下配置其授权扩展程序。这样一来,出站工具调用便可成功完成,同时记录评估结果以供审核。
在此示例中,Agent Gateway 使用区域级注册表来支持区域级 Agent Runtime 资源。
创建网关
# create agent gateway config file (regional registry)
cat > cfg/${AGW_NAME}.yaml << EOF
name: ${AGW_NAME}
protocols:
- MCP
googleManaged:
governedAccessPath: AGENT_TO_ANYWHERE
registries:
- "//agentregistry.googleapis.com/projects/${PROJ_ID}/locations/${REGION}"
EOF
# import agent gateway config file (create gateway)
gcloud network-services agent-gateways import ${AGW_NAME} \
--source="cfg/${AGW_NAME}.yaml" \
--location=${REGION}
# show agent gateway details (verify deployment state)
gcloud network-services agent-gateways describe ${AGW_NAME} \
--location=${REGION}
网关部分到此结束…接下来进入授权部分。
5. 授权
Identity-Aware Proxy (IAP) 的 Agent Gateway 授权扩展程序是一种Service Extension,用于委托所有Agent Platform通信的授权决策。
- Agent Gateway 流程:当代理尝试调用外部端点或 MCP 服务器时,它会将请求路由到 Agent Gateway。网关不进行本地访问权限评估,而是使用授权扩展程序向 IAP 评估服务发送回调。IAP 会根据代理注册表中目标资源的 IAM 政策评估代理(基于 SPIFFE)身份。IAP 会向网关返回
ALLOW或DENY判定结果,网关会转发流量或使用 HTTP403 Forbidden状态代码阻止流量。 - 强制执行模式:在
DRY_RUN模式下,IAP 会评估请求并在 Cloud Logging 中记录决策,而不会阻止流量。在ENFORCE模式下,来自未经授权的代理或发送到未注册的目标的任何请求都会立即被屏蔽。 - 绑定层:服务扩展程序使用配置了
REQUEST_AUTHZ配置文件的授权政策连接到 Agent Gateway。
授权扩展程序
创建授权扩展服务
# create authz extension config file (dry run mode)
cat > cfg/${AGW_NAME}-svc-ext-authz-iap-dryrun.yaml << EOF
name: ${AGW_NAME}-svc-ext-authz-iap-dryrun
service: iap.googleapis.com
failOpen: true
timeout: 1s
metadata:
iamEnforcementMode: "DRY_RUN"
iapPolicyVersion: "V1"
EOF
# import authz extension file (create extension)
gcloud service-extensions authz-extensions import ${AGW_NAME}-svc-ext-authz-iap-dryrun \
--source=cfg/${AGW_NAME}-svc-ext-authz-iap-dryrun.yaml \
--location=${REGION}
# show authz extension details (verify extension state)
gcloud service-extensions authz-extensions describe ${AGW_NAME}-svc-ext-authz-iap-dryrun \
--location=${REGION}
授权政策
授权政策将安全提供方 (IAP) 绑定到目标网关资源,并指定拦截配置文件 (REQUEST_AUTHZ)。
创建授权政策
# create authz policy config file (attach dry-run authz extension)
cat > cfg/${AGW_NAME}-authz-policy-profile-iap.yaml << EOF
name: ${AGW_NAME}-authz-policy-profile-iap
target:
resources:
- "projects/${PROJ_ID}/locations/${REGION}/agentGateways/${AGW_NAME}"
policyProfile: REQUEST_AUTHZ
action: CUSTOM
customProvider:
authzExtension:
resources:
- "projects/${PROJ_ID}/locations/${REGION}/authzExtensions/${AGW_NAME}-svc-ext-authz-iap-dryrun"
EOF
# import authz policy config file (enable authz policy)
gcloud beta network-security authz-policies import ${AGW_NAME}-authz-policy-profile-iap \
--source=cfg/${AGW_NAME}-authz-policy-profile-iap.yaml \
--location=${REGION}
# show authz policy details (verify dry run mode)
gcloud beta network-security authz-policies describe ${AGW_NAME}-authz-policy-profile-iap \
--location=${REGION}
授权部分到此结束…接下来进入代码库部分。
6. 代码库
此代码实验室中使用的代理代码、BigQuery 数据集和注册脚本都保存在远程 Google Cloud GitHub 代码库中。以下步骤会将代码库克隆到本地,将必要的文件复制到当前工作目录结构,然后清理不需要的临时文件。
系统会为 Agent Runtime 创建一个存储暂存桶,以便上传、构建和部署打包的代理应用代码及其依赖项制品。
提取远程制品
# clone remote repository to temp local dir
git clone https://github.com/GoogleCloudPlatform/cloud-networking-solutions.git ./temp_agw_cuj_arun_egress_gmcp
# copy agent runtime and endpoint definitions to working project dir
cp -r temp_agw_cuj_arun_egress_gmcp/codelabs/agw-cuj-arun-egress-gmcp/agent-dj ./agent-dj
cp -r temp_agw_cuj_arun_egress_gmcp/codelabs/agw-cuj-arun-egress-gmcp/endpoints ./endpoints
# remove temporary directory
rm -rf temp_agw_cuj_arun_egress_gmcp
创建 BigQuery 数据集
# create bq dataset schema and load data
bq --project_id=${PROJ_ID} query \
--use_legacy_sql=false < agent-dj/setup.sql
创建临时存储分区
# 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)"
代码库部分到此结束…接下来是注册表部分。
7. 注册表
Agent Registry 是 AI 生态系统中所有代理、MCP 服务器和端点 (API) 的集中式清单。它还是一个目录,可用于列出、搜索和发现其他已注册的工具和服务,以供 AI 应用使用。代理网关出站 (agent-to-anywhere) 模式使用注册表数据模型作为治理框架来强制执行出站访问权限控制。系统会根据绑定到注册表资源的政策来检查主账号调用代理的 IAM 角色授予情况。
为了引导环境并支持使用各种 Google API 和服务的代理,系统使用脚本通过 endpoints/googleapis.txt 中的主机名和位置快速注册一组常见的 API 端点。
注册端点
# run python script to register google api endpoints
python3 endpoints/register_endpoints.py \
--multi-region=${MREGION} \
--region=${REGION} \
--mtls-endpoints=include
验证端点
# list regional endpoints (verify registration)
gcloud agent-registry endpoints list --location=${REGION} \
--format="table(displayName, name.basename():label=ENDPOINT_ID, interfaces[0].url:label=URL)"
注册表部分到此结束...接下来是运行时部分。
8. 运行时
部署到 Agent Runtime 的 agent-dj ADK 代理在部署脚本中配置了以下设置,以便与 Agent Platform 集成:
"identity_type": types.IdentityType.AGENT_IDENTITY为代理预配基于 SPIFFE 的唯一主账号身份"agent_gateway_config": { "agent_to_anywhere_config": {"agent_gateway": } }将所有出站的智能体发起的流量定向到 Agent Gateway,以进行政策评估和执行
部署代理
# deploy agent runtime workload
uv --directory agent-dj 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 dj contact info" \
--enable-telemetry \
--enable-agent-identity \
--agent-gateway-egress=${AGW_URI} \
--allow-token-sharing
提取部署生命体征
# 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 AGENT_UID=$(gcloud agent-registry agents list \
--location=${REGION} \
--filter="displayName=${RE_AGENT_NAME}" \
--format="value(uid)")
echo ${AGENT_UID}
验证注册表条目
# show agent resource registry details
gcloud agent-registry agents describe ${AGENT_UID} --location=${REGION}
agentId: urn:agent:projects-${PROJ_NO}:projects:${PROJ_NO}:locations:${REGION}:aiplatform:reasoningEngines:${RE_ENGINE_ID}
attributes:
agentregistry.googleapis.com/system/Framework:
framework: google-adk
agentregistry.googleapis.com/system/RuntimeIdentity:
principal: principal://agents.global.org-${PROJ_NO}.system.id.goog/resources/aiplatform/projects/${PROJ_NO}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}
agentregistry.googleapis.com/system/RuntimeReference:
uri: //aiplatform.googleapis.com/projects/${PROJ_NO}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}
createTime: 'YYYY-MM-DDTHH:MM:SS.ssssssZ'
description: agent for dj contact info
displayName: agent-dj
name: projects/${PROJ_ID}/locations/${REGION}/agents/agentregistry-${RE_AGENT_ID}
protocols:
- interfaces:
- protocolBinding: HTTP_JSON
url: https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}:query
- protocolBinding: HTTP_JSON
url: https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}:streamQuery
type: CUSTOM
uid: agentregistry-00000000-0000-0000-1234-4567abcd1234
updateTime: 'YYYY-MM-DDTHH:MM:SS.ssssssZ'
验证网关配置
# verify agent gateway routing specification
curl -s -X GET "https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
| jq '{displayName: .displayName, name: .name, effectiveIdentity: .spec.effectiveIdentity, agentGatewayConfig: .spec.deploymentSpec.agentGatewayConfig}'
为资源授予代理 IAM 角色
针对资源的 IAM 角色授予功能可让代理主账号身份访问 BigQuery、MCP 工具(适用于 Google API)和其他必需的 AI 平台服务。这些政策通过 IAM 在资源级层强制执行。
# grant bigquery query execution role
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="${RE_AGENT_IDENTITY}" \
--role="roles/bigquery.user"
# grant bigquery data viewer role
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="${RE_AGENT_IDENTITY}" \
--role="roles/bigquery.dataViewer"
# grant mcp tool execution role
gcloud projects add-iam-policy-binding ${PROJ_ID} \
--member="${RE_AGENT_IDENTITY}" \
--role="roles/mcp.toolUser"
# 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"
验证资源的代理 IAM 角色
# verify active role bindings for agent identity
gcloud projects get-iam-policy ${PROJ_ID} \
--flatten="bindings[].members" \
--filter="bindings.members:${RE_AGENT_IDENTITY}" \
--format="value(bindings.role)"
运行时部分到此结束,接下来进入政策部分。
9. 政策
代理治理授权政策允许流量从 AI 智能体通过 Agent Gateway 到达目的地(例如,BigQuery 的 Google Cloud MCP 服务器端点)。当流量到达目标位置后,常规 IAM 权限会授权数据访问权限(已在上一部分中启用)。
针对 Agent Gateway 出站流量的 IAM 角色授予可启用访问政策,允许代理主账号身份通过 Agent Gateway 访问已注册的目标资源。政策在 Agent Gateway 级别强制执行,并使用 Identity-Aware Proxy (IAP) IAM 政策进行验证。
为代理网关出站流量授予代理 IAM 角色
Agent Gateway 会检查传入的请求,以验证调用代理身份是否对目标资源具有 iap.webServiceVersions.egressViaIAP 权限(由角色 roles/iap.egressor 授予)。
向所选目标资源上的代理身份或 Agent Runtime 正文集授予 roles/iap.egressor 权限,即可允许此出站流量。在此 Codelab 中,该角色应用于主账号集,从而向项目中的所有 Agent Runtime 代理身份授予权限。
IAM 政策会绑定到代理注册表数据模型中定义的目标资源。iap_web/agentRegistry 资源表示 IAM 层次结构中的“注册表级”级别。其中,agentRegistry 是 agents、mcpServers 和 endpoints 的各个子资源的父级。在此 Codelab 中,IAM 政策绑定到注册表级层,该级层会将权限应用于所有子资源。
配置 IAP 区域注册表的 IAM 政策
# show iap iam policy for regional registry
gcloud beta iap web get-iam-policy --resource-type=agent-registry --region=${REGION}
# retrieve active etag on policy for regional registry
export IAP_ETAG=$(gcloud beta iap web get-iam-policy --resource-type=agent-registry --region=${REGION} --format="value(etag)")
echo ${IAP_ETAG}
# create policy config file
cat > cfg/iap-policy-re-agent-set-to-registry-${REGION}.json << EOF
{
"bindings": [
{
"role": "roles/iap.egressor",
"members": [
"${RE_AGENT_ID_SET}"
]
}
],
"etag": "${IAP_ETAG}"
}
EOF
# import policy file (bind iam policy)
gcloud beta iap web set-iam-policy cfg/iap-policy-re-agent-set-to-registry-${REGION}.json \
--resource-type=agent-registry \
--region=${REGION}
# verify iap iam policy for regional registry
gcloud beta iap web get-iam-policy --resource-type=agent-registry --region=${REGION}
政策部分到此结束…接下来是审核部分。
10. 审核
Agent Gateway 授权扩展程序以 DRY_RUN 模式运行。系统会观察并记录出站请求,但不会阻止这些请求。
测试代理查询
打开浏览器窗口,进入 Google Cloud 控制台界面,然后依次前往:
- Agent Platform → 代理 → 部署 →
agent-dj - 选择实验标签页
或者,您也可以回显此终端命令,然后点击链接跳转到代理游乐场:
# playground
echo "https://console.cloud.google.com/agent-platform/runtimes/locations/${REGION}/agent-engines/${RE_ENGINE_ID}/playground?project=${PROJ_ID}"
提交一些测试查询。
How many DJs do we have on file?What is the phone number of DJ Cosmopup?
验证查询是否返回有效响应(例如“There are 12 DJs on file”)。
分析审核日志
查看日志并检查试运行政策评估。
# query gateway logs for dry run
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
)"
TIMESTAMP METHOD STATUS IAP_AUTHZ MCP_METHOD URL
YYYY-MM-DDTHH:MM:SS POST 200 ALLOWED https://telemetry.googleapis.com/v1/traces
YYYY-MM-DDTHH:MM:SS POST 200 ALLOWED https://${REGION}-aiplatform.googleapis.com/v1beta1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}/sessions/${RE_SESSION_ID}:appendEvent
YYYY-MM-DDTHH:MM:SS POST 200 ALLOWED https://${REGION}-aiplatform.googleapis.com/v1beta1/projects/${PROJ_ID}/locations/${REGION}/publishers/google/models/gemini-2.5-flash:generateContent
YYYY-MM-DDTHH:MM:SS POST 200 ALLOWED https://${REGION}-aiplatform.googleapis.com/v1beta1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}/sessions/${RE_SESSION_ID}:appendEvent
YYYY-MM-DDTHH:MM:SS POST 200 ALLOWED tools/call https://bigquery.googleapis.com/mcp
YYYY-MM-DDTHH:MM:SS POST 200 ALLOWED https://${REGION}-aiplatform.googleapis.com/v1beta1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}/sessions/${RE_SESSION_ID}:appendEvent
YYYY-MM-DDTHH:MM:SS POST 200 ALLOWED https://${REGION}-aiplatform.googleapis.com/v1beta1/projects/${PROJ_ID}/locations/${REGION}/publishers/google/models/gemini-2.5-flash:generateContent
YYYY-MM-DDTHH:MM:SS POST 200 ALLOWED tools/call https://bigquery.googleapis.com/mcp
YYYY-MM-DDTHH:MM:SS POST 200 ALLOWED https://${REGION}-aiplatform.googleapis.com/v1beta1/projects/${PROJ_ID}/locations/${REGION}/publishers/google/models/gemini-2.5-flash:generateContent
YYYY-MM-DDTHH:MM:SS POST 200 ALLOWED tools/call https://bigquery.googleapis.com/mcp
审核部分到此结束…接下来进入强制执行部分。
11. 强制执行
代理能够以 DRY_RUN 模式通过网关成功发出请求。通过更新授权政策,将代理网关 IAP 授权扩展程序过渡到 ENFORCE 模式。
更新授权扩展程序
# create authz extension config file (enforced mode)
cat > cfg/${AGW_NAME}-svc-ext-authz-iap-enforced.yaml << EOF
name: ${AGW_NAME}-svc-ext-authz-iap-enforced
service: iap.googleapis.com
failOpen: false
timeout: 1s
metadata:
iapPolicyVersion: "V1"
EOF
# import authz extension file (create extension)
gcloud service-extensions authz-extensions import ${AGW_NAME}-svc-ext-authz-iap-enforced \
--source=cfg/${AGW_NAME}-svc-ext-authz-iap-enforced.yaml \
--location=${REGION}
# list authz extensions (imported configs)
gcloud service-extensions authz-extensions list --location=${REGION}
更新授权政策
# re-write authz policy config file (pointing to enforced authz extension)
cat > cfg/${AGW_NAME}-authz-policy-profile-iap.yaml << EOF
name: ${AGW_NAME}-authz-policy-profile-iap
target:
resources:
- "projects/${PROJ_ID}/locations/${REGION}/agentGateways/${AGW_NAME}"
policyProfile: REQUEST_AUTHZ
action: CUSTOM
customProvider:
authzExtension:
resources:
- "projects/${PROJ_ID}/locations/${REGION}/authzExtensions/${AGW_NAME}-svc-ext-authz-iap-enforced"
EOF
# import authz policy config file (enable new authz policy)
gcloud beta network-security authz-policies import ${AGW_NAME}-authz-policy-profile-iap \
--source=cfg/${AGW_NAME}-authz-policy-profile-iap.yaml \
--location=${REGION}
# show authz policy details (verify enforced mode)
gcloud beta network-security authz-policies describe ${AGW_NAME}-authz-policy-profile-iap \
--location=${REGION}
验证强制执行情况
返回控制台界面中的代理 Playground。
提交其他测试查询...
What DJ Fishfry's credit card number?
观察到传递给 Gemini 基础模型 (${REGION}-aiplatform.googleapis.com/...) 和 MCP 服务器端点 (bigquery.googleapis.com/mcp) 的代理请求带有 HTTP 200 OK 状态代码。
# show gateway logs for http requests
gcloud logging read \
"resource.type=\"networkservices.googleapis.com/Gateway\" \
AND httpRequest.requestUrl:*" \
--project=${PROJ_ID} \
--limit=10 \
--format="table(
timestamp.date(tz=LOCAL):label=TIMESTAMP,
httpRequest.requestMethod:label=METHOD,
httpRequest.status:label=STATUS,
jsonPayload.authzPolicyInfo.result:label=IAP_AUTHZ,
jsonPayload.agentGatewayInfo.mcpInfo.method:label=MCP_METHOD,
httpRequest.requestUrl:label=URL)"
检查是否有请求被屏蔽。在网关审核日志中查找任何被拒绝的出站流量尝试,这些尝试具有 HTTP 403 Forbidden 状态代码。
# 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
)"
“强制执行”部分到此结束,接下来进入清理部分。
12. 清理
# delete agent
curl -s -X DELETE "https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJ_ID}/locations/${REGION}/reasoningEngines/${RE_ENGINE_ID}?force=true" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)"
# next
# remove agent resource iam bindings
for ROLE in \
"roles/bigquery.user" \
"roles/bigquery.dataViewer" \
"roles/mcp.toolUser" \
"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 storage bucket
gcloud -q storage rm --recursive gs://${STAGING_BUCKET}
# delete bigquery dataset and contents
bq rm -r -f -d ${PROJ_ID}:dj_ds
# next
# reset/clear iap regional registry iam policy
export IAP_ETAG=$(gcloud beta iap web get-iam-policy --resource-type=agent-registry --region=${REGION} --format="value(etag)")
cat > cfg/iap-policy-empty.json << EOF
{
"bindings": [],
"etag": "${IAP_ETAG}"
}
EOF
gcloud beta iap web set-iam-policy cfg/iap-policy-empty.json \
--resource-type=agent-registry \
--region=${REGION}
# next
# delete gateway resources
gcloud -q beta network-security authz-policies delete ${AGW_NAME}-authz-policy-profile-iap --location=${REGION}
gcloud -q beta service-extensions authz-extensions delete ${AGW_NAME}-svc-ext-authz-iap-dryrun --location=${REGION}
gcloud -q network-services agent-gateways delete ${AGW_NAME} --location=${REGION}
# next
# clean up local working directories and generated configs
rm -rf cfg agent-dj endpoints
# end
清理部分到此结束…接下来是总结!
13. 总结
恭喜!您已成功部署并管控了智能体使用 Agent Gateway 访问工具的出站通信!

Cosmopup thinks Codelabs are tops!
接下来会发生什么?
- 如需了解高级功能和教程,请参阅 Gemini Enterprise Agent Platform 文档
- 在 Agent Gateway 上配置 Model Armor 保护措施,以进一步提升 AI 安全性
- 探索语义治理政策,以针对自然语言查询强制执行业务规则和合规性要求
欢迎随时使用此反馈表单提供任何意见、提出问题或做出更正
谢谢!