排查 Agent Gateway 连接问题

本指南可帮助您调试和排查 Gemini Enterprise Agent Platform 的连接问题,尤其是在您使用 Agent Gateway、智能体身份、Identity and Access Management (IAM) 政策以及 Service Extensions 的委托授权时。

使用 Agent Platform 问题排查技能进行问题排查

如需使用 AI 编码助理以交互方式诊断连接、授权和启动问题,您可以从 Google Cloud 代理技能代码库中安装 agent-platform-troubleshooting 技能。

此技能为 AI 智能体提供了特定领域的诊断手册、日志过滤器和解决方案步骤,涵盖整个智能体平台堆栈,包括:

  • Agent Gateway 出站流量拒绝:诊断网关拦截的 403 Forbidden 错误,并验证 IAP 授权决策。
  • Agent Runtime 启动失败:识别缺失的角色(例如 roles/browser 或 resourcemanager.projects.get)和引导异常。
  • Agent Registry 目标位置问题:验证服务条目、端点接口和整合的 Google API 配置。
  • IAM 访问权限政策:验证 Unified Access Policy (UAP) 绑定、条件表达式和 Principal Access Boundary (PAB) 范围。
  • 容器信任:诊断自定义容器 (BYOC) 或私有证书授权机构 (CA) 的 TLS 证书和握手错误。

如需在智能体环境中安装技能,请运行以下命令:

npx skills add https://github.com/google/skills --skill agent-platform-troubleshooting

出站请求流程

Agent Platform 对所有出站流量采用默认拒绝政策。如需让代理连接到外部资源,您必须在每个网络和身份层明确允许访问。启用 Agent Gateway 后,网关会拦截来自智能体的所有请求,并应用配置的政策。

请求必须满足以下所有条件才能成功:

  • IAM 访问权限政策:必须直接或通过主账号集向分配给代理的代理身份授予对目标资源的 iap.resources.egressViaIAP 权限。如需了解详情,请参阅创建 IAM 代理政策。了解如何排查 IAP 政策问题。
  • 智能体注册表:建议在智能体注册表中注册目标,以强制执行精细的、针对每个资源的访问权限政策和工具级控制。如果代理尝试访问未注册的目标,您必须通过为未注册的端点配置政策,向代理身份授予 iap.resources.egressViaIAP 权限。
  • Agent Gateway:网关必须与明确以其为目标的授权政策相关联。默认情况下,网关会使用 IAP 和 Model Armor 来保护请求。
  • 使用 Service Extensions 进行委托授权:您可以使用 Service Extensions 将授权决策委托给自定义授权引擎。根据配置的授权政策,其中一个或多个授权引擎将允许或拒绝请求。

常见问题

在排查 Agent Gateway 问题时,请查看这些常见问题及其解决方案。

Agent Runtime 启动期间出错

如果您的 Agent Runtime 实例无法启动或部署,则可能意味着 IAP 正在阻止内部流量,或者您的智能体缺少初始化所需的基本角色。

  1. 确认 IAP 未阻止对内部服务的调用

    症状:启动期间出现 403 Forbidden 错误。

    原因:Agent Gateway 会对所有流量使用默认拒绝政策。因此,当 IAP 处于实施模式时,它会阻止对内部服务(例如 aiplatform 或 logging)的调用,除非这些服务已注册且代理具有所需的 IAM 权限。

    修复:暂时将 IAP 切换到试运行模式,以查看哪些连接失败,而不会阻止启动,或者查询 Cloud Logging 以确定确切的被屏蔽主机名。确定目标服务主机名后,在 Agent Registry 中注册这些主机名,并向智能体授予 iap.resources.egressViaIAP 权限。

    如需使用 Cloud Logging 查找特定被屏蔽的主机名,请在 Logs Explorer 中运行以下查询:

    resource.type="networkservices.googleapis.com/Gateway"
    resource.labels.gateway_type="SECURE_WEB_GATEWAY"
    httpRequest.status=403
    

    检查结果中的 httpRequest.requestUrl 或 jsonPayload.authzPolicyInfo 字段,找到目标主机名。

    可能需要在启动期间注册的常见内部服务包括:

    • Agent Platform(推理引擎和会话):https://REGION-aiplatform.mtls.googleapis.com
    • Resource Manager:https://cloudresourcemanager.mtls.googleapis.com 和 https://cloudresourcemanager.mtls.googleapis.com/
    • Google Cloud Observability(如果已启用):https://telemetry.mtls.googleapis.com/
    • Cloud Logging(如果已启用):https://logging.googleapis.com/
    • Cloud Monitoring:https://monitoring.googleapis.com/ 和 https://monitoring.mtls.googleapis.com/
    • Cloud Trace:https://cloudtrace.googleapis.com/ 和 https://cloudtrace.mtls.googleapis.com/
    • Secret Manager:https://secretmanager.googleapis.com/ 和 https://secretmanager.mtls.googleapis.com/
  2. 确认代理身份具有所需的基本角色

    症状:在 aiplatform.googleapis.com/reasoning_engine_stderr 日志中,您会看到 google.api_core.exceptions.Unknown: None 或 Failed to convert project number to project ID 等错误。在 Reasoning Engine 启动期间,系统会显示该错误。

    原因。代理身份缺少在初始化期间解析项目名称所需的 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

    如需了解如何授予角色,请参阅将代理身份与 Agent Runtime 搭配使用。

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 或自签名证书的目标需要进行额外配置。
  • 缓解措施:如需使用私有 CA 或自签名证书连接到目标,您必须在代理连接模板中使用 tlsConfig 设置来配置自定义 TLS 信任锚。如果您的代理还连接到 Google Cloud API (*.googleapis.com) 或其他公共 HTTPS 端点,请确保在 tlsConfig 中将 additionalRoots 设置为 PUBLICLY_TRUSTED_ROOTS。如果您更新 tlsConfig 设置,则必须绑定新的连接模板(或解除绑定并重新绑定模板),因为 Agent Gateway 不会自动在附加的模板上获取就地 tlsConfig 更改。

使用自定义容器 (BYOC) 部署的代理无法连接到 Agent Gateway

  • 症状:BYOC 智能体在通过 Agent Gateway 路由时无法建立连接。日志可能会显示 TLS 握手或证书验证错误。
  • 原因:智能体的自定义容器不信任 Agent Gateway 的证书授权机构。
  • 解决方法:确保您已将 Agent Gateway 的根证书添加到容器的 CA 存储区。请参阅为 Agent Gateway 配置自定义容器 (BYOC) 代理。

政策绑定失败或模拟治理拒绝

  • 症状:政策绑定配置失败,在绑定政策时系统会以交互方式提示您输入 etag,或者请求失败并显示虚假的治理拒绝错误(例如“未注册的目标已正确拒绝”)。
  • 原因:您的项目中停用了 Identity-Aware Proxy API (iap.googleapis.com)。
  • 解决方法:启用 IAP API。

使用员工身份联合管理 Agent Gateway 时失败

如果您在Google Cloud 控制台中管理 Agent Gateway,或者在使用员工身份联合 (WIF) 进行身份验证时使用 gcloud CLI,则可能会遇到此问题。

控制台会显示一般加载或创建错误,例如:

  • “加载时出错…”
  • “服务器无法完成您的请求”
  • 未能创建 Agent Gateway
  • “加载失败”

此外,gcloud 命令(例如 gcloud network-services agent-gateways import)可能会返回内部错误,例如 error 13: an internal error has occurred。

如需解决此问题,请使用通过 Cloud Identity 或 Google Workspace 管理且具有所需权限(例如 roles/networkservices.admin)的标准 Google 账号进行身份验证。

在预览版中,Agent Platform Governance 和 Gateway 服务对联合身份的支持有限。向联合主账号授予更广泛的 IAM 角色并不能解决此问题。

调试工作流

如果缺少出站流量请求流程部分中所述的任何条件,您的请求可能会被屏蔽。

查看 IAP 判定结果

如需将日志搜索范围缩小到 IAP 出站流量决策,请在 Logging 中运行以下查询:

protoPayload.serviceName="iap.googleapis.com"
protoPayload.authorizationInfo.permission="iap.resources.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,则表示目标主机名未注册。向 Agent Registry 注册目标主机名,并确保代理具有此目标的 iap.resources.egressViaIAP 权限。
  • 实施模式:查看请求的实施模式。如需过滤试运行请求,您可以将 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:记下代理尝试访问的确切目标网址。在下一步中,我们会检查目标资源使用的主机名是否已在代理注册表中注册。

验证目标注册和 IAM 访问权限政策覆盖范围

访问目标位置始终需要 IAM 允许政策,该政策会向代理身份授予 iap.resources.egressViaIAP 权限。建议在 Agent Registry 中注册目标,以强制执行精细的、针对每个资源的访问权限政策,并确保主机名匹配准确。对于未注册的目标,请验证未注册端点的政策是否向智能体身份授予了所需权限。

如果您依赖于针对每项资源的政策,则必须在 Agent Registry 中注册代理尝试访问的每个目标主机名以及该主机名的任何变体。这是因为 Google API(例如 aiplatform.googleapis.com)可以根据 SDK 版本、区域客户端配置或 mTLS 使用情况(例如 us-central1-aiplatform.googleapis.com 或 us-central1-aiplatform.mtls.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...

继续执行验证目标资源上的 IAM 绑定,以检查每资源或注册表级政策是否向代理身份授予了访问权限。

输出 2:主机名在注册表中不存在

如果注册表中不存在该主机名,您会看到类似于以下示例的输出:

Checking Endpoints...
Checking MCP Servers...
Checking Agents...

如果您打算使用按资源或注册表范围的政策,请先在 Agent Registry 中注册目标。如果您对未注册的端点使用政策,请继续执行验证目标资源上的 IAM 绑定。

验证目标资源上的 IAM 绑定

确保代理身份或其主账号集对目标位置具有 iap.resources.egressViaIAP 权限。

您可以在以下三个范围内配置政策绑定:

  • 注册表范围:访问注册表中注册的每个代理、MCP 服务器和端点。
  • 按资源:访问权限范围较窄。每个资源的绑定会替换该特定资源的注册表级绑定,而不是与其合并。
  • 针对未注册端点的政策:访问未在 Agent Registry 中注册的目标。

使用以下示例之一检查绑定:

  • 如需检查注册表级层 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)。

在返回的政策信息中,查找具有与代理的身份或主账号集匹配的 iap.resources.egressViaIAP 权限的绑定。如果返回的输出包含 "etag" 字段但没有绑定,则表示不存在 IAM 政策。

如果绑定存在但包含 condition,请验证通用表达式语言 (CEL) 表达式未排除代理。如果过滤条件所依据的属性是代理所不具备的,则可能会在不发出任何提示的情况下排除该代理。

如果目标目的地没有向您的代理身份或主账号集授予 iap.resources.egressViaIAP 权限的匹配政策绑定,请使用以下政策选项之一授予该权限:

检查授权政策和扩展程序

在本部分中,我们将确保存在明确针对与代理关联的 Agent Gateway 的授权政策。

  1. 获取与网关关联的授权扩展的详细信息,并确认您使用的扩展已按预期配置。

      gcloud service-extensions authz-extensions describe AUTHORIZATION_EXTENSION_NAME \
        --location=LOCATION \
        --project=PROJECT_ID
    

    将 AUTHORIZATION_EXTENSION_NAME 替换为与网关关联的扩展程序的名称。如果您不知道扩展程序的名称,可以前往Google Cloud Google Cloud 控制台中的网关详情页面,并记下“Service Extensions”下扩展程序名称字段的值。

  2. 验证授权政策是否明确以网关资源为目标,并链接到同一授权扩展。您可以前往 Google Cloud Google Cloud 控制台中的网关详情页面,并记下 Service Extensions 下的政策名称字段的值。

    如果没有政策定位到网关,或者网关到政策的映射不正确,则不会执行授权扩展。

检查 Principal Access Boundary Policy

主账号访问权限边界政策优先于 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

了解如何使用 Gemini Enterprise Agent Platform 上的 Agent Gateway 治理智能体工作负载。

指南

了解如何监控 Agent Gateway。