本指南可帮助您调试和排查 Gemini Enterprise Agent Platform 的连接问题,尤其是在您将 Agent Gateway、代理身份、Identity and Access Management (IAM) 政策和委托授权与 Service Extensions 搭配使用时。
出站请求流程
Agent Platform 针对所有出站流量采用默认拒绝政策。如需让代理连接到外部资源,您必须在每个网络和身份层明确允许访问。启用 Agent Gateway 后,该网关会拦截来自智能体的所有请求,并应用配置的政策。
请求必须满足以下所有条件,才能成功执行:
- 代理注册数据库:目的地必须注册为端点、Model Context Protocol (MCP) 服务器或代理。
- Agent Gateway:网关必须与明确以其为目标的授权政策相关联。默认情况下,网关使用 IAP 和 Model Armor 来保护请求。
- 使用 Service Extensions 进行委托授权:您可以使用 Service Extensions 将授权决策委托给自定义授权引擎。根据配置的授权政策,其中一个或多个授权引擎将允许或拒绝相应请求。
- IAM 允许政策:分配给代理的代理身份必须直接或通过主账号集持有注册的目标资源上的
roles/iap.egressor角色。如需了解详情,请参阅创建 IAM 代理政策。
常见问题
在排查 Agent Gateway 问题时,请查看以下常见问题及其解决方案。
Agent Runtime 启动期间的错误
如果您的 Agent Runtime 实例无法启动或部署,则可能意味着 IAP 正在阻止内部流量,或者您的代理缺少初始化所需的基本角色。
确认 IAP 未阻止对内部服务的调用
症状:启动期间出现
403 Forbidden错误。原因:Agent Gateway 对所有流量使用默认拒绝政策。因此,当 IAP 处于强制执行模式时,即使是内部服务(例如
aiplatform或logging),除非已注册且代理具有所需的 IAM 权限,否则 IAP 也会阻止对这些服务的调用。修复:暂时将 IAP 切换到试运行模式,以查看哪些连接失败,而不会阻止启动。确定目标服务主机名后,在代理注册表中注册这些主机名,并向代理授予
roles/iap.egressor角色。在启动期间可能需要注册的常见内部服务包括:
- Resource Manager:
https://cloudresourcemanager.mtls.googleapis.com和https://cloudresourcemanager.mtls.googleapis.com/ - Cloud Trace(如果已启用):
https://telemetry.mtls.googleapis.com/ - Cloud Logging(如果已启用):
https://logging.googleapis.com/
- Resource Manager:
确认代理身份具有所需的基本角色
症状:在
aiplatform.googleapis.com/reasoning_engine_stderr日志中,您会看到google.api_core.exceptions.Unknown: None或Failed to convert project number to project ID等错误。该错误出现在推理引擎启动期间。原因。代理身份缺少在初始化期间解析项目名称所需的
resourcemanager.projects.get权限。修复。确保代理身份(或其主账号集)具有读取自身运行时配置所需的权限。必须拥有以下角色:
roles/aiplatform.agentDefaultAccess:默认代理角色。roles/aiplatform.user:运行代理时必需提供。roles/agentregistry.viewer:查看已注册的资源时需要提供。roles/logging.logWriter和roles/monitoring.metricWriter:必须提供,以便实现可观测性。roles/browser:在 SDK 初始化期间运行resourcemanager.projects.get时需要此参数。
如需验证分配给代理身份的角色,请运行以下命令:
gcloud projects get-iam-policy PROJECT_ID \ --flatten="bindings[].members" \ --filter="bindings.members:AGENT_IDENTITY_PRINCIPAL"
替换以下内容:
PROJECT_ID:您的 Google Cloud 项目 ID。AGENT_IDENTITY_PRINCIPAL:代理身份正文。使用以下格式:principal://TRUST_DOMAIN/resources/SERVICE/RESOURCE_PATH
如需了解如何授予角色,请参阅将代理身份与代理运行时搭配使用。
403 Forbidden 个错误
如果您遇到 403 Forbidden 错误,请确认该错误是否与 Agent Gateway 出站流量相关。以下是出站流量错误消息示例:
{"code": 403, "message": "403 Forbidden. {'message': 'Egress request is not authorized.', 'status': 'Forbidden'}"}
在 Logging 中查询代理日志,以查找特定的失败调用:
resource.type="aiplatform.googleapis.com/ReasoningEngine" resource.labels.location="LOCATION" resource.labels.reasoning_engine_id="AGENT_ID" textPayload:"403"
替换以下内容:
LOCATION:代理的部署区域,例如us-central1。AGENT_ID:代理(推理引擎)的 ID。
在日志条目的 textPayload 中查找 Egress request is not authorized 消息。如果 403 错误包含不同的文本,则表示目标服务可能直接拒绝了调用,而不是 Agent Gateway。
您还可以使用内置的可观测性信息中心查看出站流量日志,包括 403 拒绝。
自签名或私有 CA 目标无法连接
- 症状:代理无法连接到提供自签名证书或私有 CA 颁发的证书的目标。
- 原因:Agent Gateway 不验证自签名证书链。
- 缓解措施:使用广受信任的 CA 证书,或使用没有 CA 证书的目标。
使用自定义容器 (BYOC) 部署的 Agent 无法连接到 Agent Gateway
- 症状:BYOC代理在通过 Agent Gateway 路由时无法建立连接。日志可能会显示 TLS 握手或证书验证错误。
- 原因:代理的自定义容器不信任代理网关的证书授权机构。
- 修复:确保您已将代理网关的根证书添加到容器的 CA 存储区。请参阅为 Agent Gateway 配置自定义容器 (BYOC) 代理。
调试工作流程
如果缺少出站请求流程部分中所述的任何条件,您的请求可能会被阻止。
查看 IAP 判定结果
如需将日志搜索范围缩小到 IAP 出站流量决策,请在 Logging 中运行以下查询:
protoPayload.serviceName="iap.googleapis.com" protoPayload.authorizationInfo.permission="iap.webServiceVersions.egressViaIAP" protoPayload.metadata.mcp_attributes.base_protocol_method="true"
如果您根本没有看到匹配的 IAP 日志条目,则可能是网关在 IAP 评估请求之前就拒绝了该请求。继续执行下一步。
如果您确实看到了匹配的日志条目,请查看以下字段:
protoPayload.authorizationInfo[].granted:指示请求是被允许 (true) 还是被拒绝 (false)。protoPayload.authenticationInfo.principalSubject:调用者的 SPIFFE ID 或principal://...身份。验证此信息是否与您的代理的身份信息一致。protoPayload.authorizationInfo[].resource:调用解析为的已注册目标资源。labels."iap.googleapis.com/audited_resource_name":如果此值为unregisteredResource,则表示目标主机名未注册。向代理注册表注册目标主机名,并确保代理具有此目标的roles/iap.egressor角色。- 强制模式:查看请求的强制模式。如需过滤出试运行请求,您可以向查询中添加
protoPayload.metadata.iamEnforcementMode="DRY_RUN"。在DRY_RUN模式下,IAP 会记录拒绝事件,但不会强制执行这些拒绝事件。因此,如果代理在试运行模式下因403错误而失败,则拒绝很可能来自网关的出站代理或目标资源。
查看 Agent Gateway 决策
如需查看 Agent Gateway 如何评估请求,请在 Logging 中查询网关日志。在此示例中,我们仅过滤 403 错误日志:
resource.type="networkservices.googleapis.com/Gateway" resource.labels.gateway_type="SECURE_WEB_GATEWAY" resource.labels.location="REGION" resource.labels.gateway_name="AGENT_GATEWAY_NAME" httpRequest.status=403 -httpRequest.requestMethod="CONNECT"
查看匹配的日志条目中的以下字段:
jsonPayload.authzPolicyInfo.policies.result:总体授权结果,ALLOWED或DENIED。httpRequest.requestUrl:记下代理尝试访问的确切目标网址。在下一步中,我们将检查目标资源所用的主机名是否已在代理注册表中注册。
验证目标位置是否已在代理注册表中注册
每个目标主机名以及代理尝试访问的任何主机名变体都必须在代理注册表中注册。这是因为 Google API(例如 aiplatform.googleapis.com)可以通过多个主机名进行解析,具体取决于 SDK 版本、区域客户端配置或 mTLS 使用情况。例如,us-central1-aiplatform.googleapis.com、us-central1-aiplatform.mtls.googleapis.com 或 aiplatform.googleapis.com。
不过,网关仅完全匹配主机名。因此,如果您注册了 aiplatform.googleapis.com,但代理调用了 us-central1-aiplatform.googleapis.com,网关会拒绝该请求。网关会将其视为未注册的资源。
运行以下示例脚本,根据资源类型列出注册表条目,并检查代理的调用所使用的特定主机名的条目:
HOSTNAME="HOSTNAME" PROJECT_ID="PROJECT_ID" LOCATION="REGION" echo "Checking Endpoints..." gcloud agent-registry endpoints list \ --project="$PROJECT_ID" \ --location="$LOCATION" | grep "$HOSTNAME" echo "Checking MCP Servers..." gcloud agent-registry mcp-servers list \ --project="$PROJECT_ID" \ --location="$LOCATION" | grep "$HOSTNAME" echo "Checking Agents..." gcloud agent-registry agents list \ --project="$PROJECT_ID" \ --location="$LOCATION" | grep "$HOSTNAME"
替换以下内容:
HOSTNAME:代理尝试访问的目标主机名,例如us-central1-aiplatform.mtls.googleapis.com。PROJECT_ID:您的 Google Cloud 项目 ID。REGION:Agent Registry 和 Agent Gateway 资源的位置,例如us-central1。
输出 1:主机名已注册
如果主机名存在于代理注册表条目中,您会看到类似于以下示例的输出:
Checking Endpoints... url: https://us-central1-aiplatform.mtls.googleapis.com Checking MCP Servers... Checking Agents...
继续执行下一步。
输出 2:注册表中不存在相应的主机名
如果注册表中不存在相应的主机名,您会看到类似于以下示例的输出:
Checking Endpoints... Checking MCP Servers... Checking Agents...
如需解决此问题,请注册缺少的 MCP 服务器或端点,然后向您的代理授予新注册表条目的 roles/iap.egressor 角色。
验证目标资源上的 IAM 绑定
确保代理身份或其主账号集在目标位置上具有 roles/iap.egressor 角色。Agent Gateway 专门查找 iap.webServiceVersions.egressViaIAP 权限,该权限仅由 roles/iap.egressor 角色授予。
您可以在两个范围内绑定角色:
- 注册表范围:对注册表中的每个代理、MCP 服务器和端点的访问权限。
- 按资源:缩小访问范围。针对特定资源的绑定会替换该特定资源的整个注册表绑定,而不是与之合并。
使用以下示例检查绑定:
如需检查是否存在注册级 IAM 政策绑定,请运行以下命令:
curl -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \ -d '{}' \ -X POST "https://iap.googleapis.com/v1/projects/PROJECT_NUMBER/locations/LOCATION/iap_web/agentRegistry:getIamPolicy" \ -H "Content-Type: application/json"如需检查是否存在按端点 IAM 政策绑定,请运行以下命令:
export HOSTNAME=HOSTNAME ENDPOINT_ID=$(gcloud agent-registry endpoints list \ --project="PROJECT_ID" \ --location="REGION" \ --filter="interfaces.url:$HOSTNAME" \ --format="value(name.basename())") echo "ENDPOINT_ID=$ENDPOINT_ID" curl -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \ -H "Content-Type: application/json" \ -d '{}' \ -X POST "https://iap.googleapis.com/v1/projects/PROJECT_NUMBER/locations/LOCATION/iap_web/agentRegistry/endpoints/${ENDPOINT_ID}:getIamPolicy"
将
HOSTNAME替换为代理尝试访问的目标的主机名,例如us-central1-aiplatform.mtls.googleapis.com。如需检查是否存在每个 MCP 服务器 的 IAM 政策绑定,请运行以下命令:
export MCP_SERVER=MCP_SERVER MCP_SERVER_ID=$(gcloud agent-registry mcp-servers list \ --project="PROJECT_ID" \ --location="REGION" \ --filter="interfaces.url:$MCP_SERVER" \ --format="value(name.basename())") echo "MCP_SERVER_ID=$MCP_SERVER_ID" curl -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \ -H "Content-Type: application/json" \ -d '{}' \ -X POST "https://iap.googleapis.com/v1/projects/PROJECT_NUMBER/locations/LOCATION/iap_web/agentRegistry/mcpServers/${MCP_SERVER_ID}:getIamPolicy"
将 MCP_SERVER 替换为 MCP 服务器的网址(例如
https://example-abc12345-uc.a.run.app/mcp)。
在返回的政策信息中,查找具有 roles/iap.egressor 角色的绑定,该角色与代理的身份或主账号集相匹配。如果返回的输出包含 "etag" 字段但没有绑定,则表示不存在任何 IAM 政策。
如果绑定存在但包含 condition,请验证通用表达式语言 (CEL) 表达式是否未排除代理。按代理所缺少的属性进行过滤的条件可能会在不知不觉中排除该代理。
如果端点或 MCP 服务器没有与您的代理 ID 或主账号匹配的绑定,请向您的代理授予资源的角色:
检查授权政策和扩展程序
在本部分中,我们将确保存在明确以与代理关联的 Agent Gateway 为目标的授权政策。
获取与网关关联的授权扩展的详细信息,并确认您使用的扩展已按预期配置。
gcloud service-extensions authz-extensions describe AUTHORIZATION_EXTENSION_NAME \ --location=LOCATION \ --project=PROJECT_ID
将 AUTHORIZATION_EXTENSION_NAME 替换为与网关关联的扩展程序的名称。如果您不知道扩展程序的名称,可以在 Google Cloud Google Cloud 控制台中前往网关的详情页面,然后记下“Service Extensions”下的扩展程序名称字段的值。
验证授权政策是否明确以网关资源为目标,并链接到同一授权扩展服务。您可以在 Google Cloud Google Cloud 控制台中前往网关的详情页面,并记下“服务扩展”下的政策名称字段的值。
如果没有政策以网关为目标,或者网关到政策的映射不正确,则不会执行授权扩展程序。
检查主账号访问边界政策
主账号访问权限边界政策优先于 IAM 允许政策。这意味着,即使您已正确配置所有 IAM 绑定,如果存在将目标资源排除在代理范围之外的有效主账号访问权限边界政策,请求也会失败。
如需列出组织范围的政策,请运行以下命令:
gcloud iam principal-access-boundary-policies list \ --organization="ORGANIZATION_ID" \ --location=global
如需查找绑定到代理的主账号集的政策,请运行以下命令:
gcloud iam policy-bindings search-target-policy-bindings \ --project="PROJECT_ID" \ --target="PRINCIPAL_SET"
替换以下内容:
ORGANIZATION_ID:您的 Google Cloud 组织 ID。PROJECT_ID:您的 Google Cloud 项目 ID。PRINCIPAL_SET:代理身份的主账号集。
如果存在绑定,请检查 details.rules[].resources[] 字段,以验证目的地是否在代理的范围内。
测试正文与正文集绑定
如果权限的运作不一致或意外失败,问题可能与代理的群组身份(即正文集)的配置有关。基于正文的权限集可能会因以下原因而失败:
- 同步延迟:向集合中添加身份后,IAM 可能需要几分钟时间才能更新并识别新成员。
- 缺少属性:如果主账号集的成员资格需要某些属性,则代理的身份必须包含这些确切的属性(例如部门或团队标签)。如果身份缺少这些属性,代理可能会被静默地从群组中排除。
如需测试群组成员资格是否是问题所在,请通过在受影响的资源上添加直接 principal:// 绑定,直接向特定代理授予权限。如果代理成功通过直接绑定进行连接,则根本原因很可能是正文集存在属性不匹配或同步延迟问题。
如需解决此问题,请验证并更正代理的身份属性,或使用直接 principal:// 绑定。
后续步骤
Codelab:使用 Agent Platform 管理代理工作负载
了解如何在 Gemini Enterprise Agent Platform 上使用 Agent Gateway 来监管智能体工作负载。