01 / THE SIGNAL

我们发现了什么

你的 AI 代理刚拿到"护照":Google Cloud 上的代理身份与无人谈起的重新部署陷阱。## 为什么你的代理需要自己的身份 大多数团队让所有 AI 代理共用同一个服务账号。

  • 来源:DEV Community(发现于 2026-10-16)
  • 证据等级:D · 发现产品或需求信号,暂未获得可核验的商业证据。
  • 商业模式:待核验
  • 主题:AI Agent
  • 初筛评分:18.3/100 · 收录 1 次
#工作流自动化#待验证#产品发现
02 / SOURCE & EVIDENCE

证据,比故事更重要。

发现产品或需求信号,暂未获得可核验的商业证据。

规则清洗与初筛,未经人工商业核验。原文语境、实际客户和付费情况仍需自行验证。

引用与数字披露

来源类型(原作者自述/第三方测算/媒体转引)需采集端标注,本版尚未落字段。

短句引用
作者
未标注
抓取日期
来源类型
未标注
数字口径
币种
未标注
口径
未标注
披露主体
未标注
披露日期
未标注

中文辅助译文(节选·触顶截断)

为什么你的智能体需要自己的身份

大多数团队让所有 AI 智能体共用同一个服务账号。这种方式一直可行,直到某个智能体做了不该做的事,而审计日志只显示"是服务账号做的"。你无法分辨是哪个智能体所为,也无法在不破坏其他智能体的情况下单独停用某个智能体。

Google Cloud 现在推出了名为 Agent Identity 的解决方案,它是 Gemini Enterprise Agent Platform(Vertex AI 的新名称)的一部分。每个智能体都会获得自己的可验证身份,因此你可以像对待人员一样,按智能体粒度授予、拒绝和审计访问权限。

在这篇文章中,我将介绍它的工作原理、如何使用它部署 ADK 智能体,以及我认为每位 SRE 在将其接入 CI/CD 流水线之前都应该知道的一个生产陷阱:每次重新部署都会给你的智能体一个全新的身份,而它原有的权限并不会随之迁移。

Agent Identity 究竟是什么

可以把它当作每个智能体的护照。当你将智能体部署到 Agent Runtime 并启用此功能时,Google Cloud 会基于开源的 SPIFFE 标准为其分配一个唯一身份,外加一张由 Google 创建并管理的 X.509 证书。

在 IAM 中,该身份会显示为一个主体(principal),你可以为其绑定角色:

principal://agents.global.org-ORGANIZATION_ID.system.id.goog/resources/aiplatform/projects/PROJECT_NUMBER/locations/LOCATION/reasoningEngines/AGENT_ENGINE_ID

一些值得了解的细节:

  • 启用 Agent Platform API 时,信任域会自动为你创建。如果有组织,则位于组织级(agents.global.org-...);如果没有,则位于项目级(agents.global.proj-...)。
  • 该身份与智能体的资源 ID 绑定,而非与构建它所用的框架绑定。ADK、LangGraph 等各种框架的工作方式完全相同。
  • 开箱即用,智能体会获得两个默认角色 —— roles/aiplatform.agentContextEditor 和 roles/aiplatform.agentDefaultAccess,以便它能够访问自己的日志、指标、模型、会话和记忆。
  • 作为 SRE,我最喜欢的一点是:令牌通过 Google 管理的基于 mTLS 证书绑定的 Context-Aware Access 策略锁定到运行时。即使有人窃取了令牌并试图在智能体运行时之外使用它,也会以 401 失败。被盗凭证无法被重放。

一个易踩的坑:在 IAM 绑定中必须使用 principal:// 格式,而不是原始的 spiffe:// 字符串。使用 SPIFFE 字符串会返回 INVALID_ARGUMENT 错误。

实战:部署一个拥有自身身份的 ADK 智能体

你有三种方式可以启用它。选择最适合你工作流的那种。

选项 1:Python SDK。 定义一个普通的 ADK 智能体,将其包装,然后在部署时传入 identity_type:

from google.adk.agents import Agent
import agentplatform
from agentplatform import types
from agentplatform.frameworks import AdkApp

agent = Agent(
model="gemini-2.5-flash",
name="minimal_agent",
instruction="You are a helpful assistant.",
)

client = agentplatform.Client(
project=PROJECT_ID,
location=LOCATION,
http_options=dict(api_version="v1beta1"),
)

remote_app = client.runtimes.create(
agent=AdkApp(agent=agent),
config={
"display_name": "running-agent-with-identity",
"identity_type": types.IdentityType.AGENT_IDENTITY,
"requirements": ["google-cloud-agentplatform[adk,runtimes]"],
"staging_bucket": f"gs://{BUCKET_NAME}",
},
)

print(remote_app.api_resource.spec.effective_identity)

请注意 v1beta1 API 版本。Agent Identity 需要它。

选项 2:adk deploy 命令。 在部署之前,将一个小型配置文件放到你的智能体目录中:

echo '{ "identity_type": "AGENT_IDENTITY" }' > .agent_engine_config.json

选项 3:Agents CLI。 适合快速测试和原型开发:

agents-cli deploy --agent-identity

我推荐的一个技巧:你可以在不提供代码的情况下,仅使用 identity_type 创建 Agent Runtime 实例。这样可以先拿到身份,从而在智能体运行前完成 IAM 配置。之后再用 client.runtimes.update(...) 添加代码。

如果跳过身份标志,智能体会像以前一样继续使用服务账号,因此现有流水线不会中断。

双层最小权限

最有效的模式是将权限拆分为"共享底线"和"窄化上限"两层。

第 1 层:项目中每个智能体的基线。 使用 principalSet,这样一条绑定就能覆盖现在和未来的所有智能体。这里只放置常规的、低风险的角色:

AGENTS="principalSet://agents.global.org-ORGANIZATION_ID.system.id.goog/attribute.platformContainer/aiplatform/projects/PROJECT_NUMBER"

for ROLE in roles/serviceusage.serviceUsageConsumer roles/browser \
roles/aiplatform.expressUser roles/logging.logWriter \
roles/monitoring.metricWriter; do
gcloud projects add-iam-policy-binding PROJECT_ID \
--member="$AGENTS" --role="$ROLE"
done

第 2 层:按智能体进行的窄化授权。 任何敏感资源(例如包含客户数据的 BigQuery 数据集或 Cloud Storage 桶)只授予给特定智能体的 principal://:

gcloud storage buckets add-iam-policy-binding gs://orders-data \
--member="principal://agents.global.org-ORGANIZATION_ID.system.id.goog/resources/aiplatform/projects/PROJECT_NUMBER/locations/us-central1/reasoningEngines/AGENT_ENGINE_ID" \
--role="roles/storage.objectViewer"

多智能体加成(A2A)。 如果父智能体调用了在 Agent Registry 中注册的子智能体,则父智能体的身份需要两个角色:roles/agentregistry.viewer 用于查找子智能体,以及子智能体 reasoning engine 上的 roles/aiplatform.user 用于调用它。请将这些权限授予父智能体,而不是你自己的用户账号。这是一个容易犯的错误,表现为令人困惑的权限错误。

没人提起的重新部署陷阱

这是会"咬"到 SRE 和平台团队的部分。每当流水线删除并重建一个智能体时,该智能体会获得一个新的 reasoningEngines ID,这意味着一个全新的主体。 授予旧主体的权限不会随之迁移。

想象一下普通的一天:

  1. 你的智能体对 gs://orders-data 拥有读取权限,运行良好。
  2. 一次蓝绿部署、一个临时测试环境,或带 replace 参数的 terraform apply 重建了该智能体。
  3. 新智能体启动后通过健康检查,但在首次访问该桶时静默地收到 403 错误。

没有部署失败,没有告警,只是一个智能体突然"找不到"数据。这是一次静默中断。

反向的情况会更糟。删除智能体并不会移除指向它的 IAM 绑定。这些失效绑定会一直留在你的策略中,直到有人手动清理。随着时间推移,这会造成策略杂乱和审计难题。

如何修复

修复方案 1:将授权作为部署后步骤。 部署后立即读取新身份并为其绑定角色:

IDENTITY=$(gcloud ai reasoning-engines describe RESOURCE_ID \
--project=PROJECT_ID --location=LOCATION \
--format="value(spec.effectiveIdentity)")

gcloud storage buckets add-iam-policy-binding gs://orders-data \
--member="principal://${IDENTITY}" \
--role="roles/storage.objectViewer"

修复方案 2:让 Terraform 替你构建主体。 从已部署的资源派生主体,这样绑定总能随智能体一起重建:

resource "google_vertex_ai_reasoning_engine" "agent" {
provider = google-beta
project = var.project_id
region = var.region
display_name = "orders-agent"

spec {
agent_framework = "google-adk"
identity_type = "AGENT_IDENTITY"
# source_code_spec and deployment_spec here
}
}

locals {
agent_id = element(split("/", google_vertex_ai_reasoning_engine.agent.id), -1)
agent_principal = "principal://agents.global.org-${data.google_organization.org.org_id}.system.id.goog/resources/aiplatform/projects/${data.google_project.project.number}/locations/${var.region}/reasoningEngines/${local.agent_id}"
}

resource "google_storage_bucket_iam_member" "orders_reader" {
bucket = "orders-data"
role = "roles/storage.objectViewer"
member = local.agent_principal
}

由于绑定依赖于智能体资源,Terraform 会一并替换两者,销毁智能体也会同时移除其绑定。这同时也解决了孤立绑定的问题。

修复方案 3:借助基线层。 项目级 principalSet 绑定能够经受删除和重建,因此在重新部署后智能体仍能立即获得配额、日志和模型访问权限。仅对敏感数据保留按智能体的绑定。

修复方案 4:加入冒烟测试。 部署后,让流水线发送一个真实的请求来访问每个受保护的资源。此处的 403 会使流水线失败,而不是在用户面前才暴露出问题。

护栏:智能体绝不能做的事

允许策略规定了智能体可以做什么。对于自主行动的智能体,你还需要任何允许策略都无法覆盖的硬性限制。为此,Agent Identity 与两个 IAM 工具配合使用。

IAM 拒绝策略(Deny policies)。 在整个组织范围内阻止所有智能体身份的特定权限,无论后续授予了什么角色。适合用作拒绝策略的对象是破坏性操作,例如删除桶或创建 IAM 角色。官方文档中包含一个可直接套用的拒绝策略示例(链接见参考资料)。

Principal Access Boundary(PAB)。 它限制了智能体可以在哪些地方执行操作。例如,你可以规定组织内的智能体只能访问某个文件夹内的资源。即使有人不小心给智能体授予了该文件夹之外某个生产项目的角色,PAB 也会将其拦截。

我的经验法则是:允许策略用于日常工作,拒绝策略用于"绝对不允许",PAB 则是整个院子的围栏。如果需要更上层的网络边界,Agent Identity 还可以接入 VPC Service Controls。

审计:终于知道是哪个智能体做了什么

开启 Cloud Logging 后,每次访问都会显示智能体自身的身份,而不是共享的服务账号。有两种重要情况:

  • 当智能体自主行动时,日志仅显示智能体的身份。
  • 当智能体代表用户行动时,日志会同时显示智能体和用户。

第二种情况对合规审查而言意义重大。你可以毫无猜测地回答"是哪个智能体、为谁读取了这份数据?"。

要在一个地方查看所有智能体及其身份,请在控制台中打开 Agent Platform 的 Deployments 页面并查看 Identity 列,或者通过 API 读取 spec.effectiveIdentity。

限制与注意事项

在推广之前,请如实向团队说明以下几点:

  • 它需要 v1beta1 API 版本,因此请将其视为一个不断变化的目标,每次升级前都要查阅文档。
  • 无法向智能体身份授予旧的 Cloud Storage 桶角色(legacyBucketReader、legacyBucketWriter、legacyBucketOwner)。如果你的桶仍依赖这些角色,请制定清理计划。
  • 上文所述的重新部署陷阱是设计如此,并非 bug。你的流水线必须自行处理。
  • 已删除的智能体会留下孤立的 IAM 绑定,除非你的工具会主动移除它们。
  • 虽然可以为特殊的令牌共享场景关闭 Context-Aware Access 令牌绑定,但 Google 强烈不建议这样做,因为它重新打开了凭证被盗的大门。我不会那样做。
  • 身份控制的是智能体能够访问什么,而不是它决定做什么。提示注入仍可能诱骗智能体滥用其合法拥有的访问权限。请将其与 Model Armor 等内容安全控件搭配使用,并对风险操作保留人工介入。

总结:生产环境清单

Agent Identity 让智能体成为 IAM 中的一等公民。该功能本身很容易启用,真正的工作在于围绕它的流水线。以下是我会使用的清单:

  • [ ] 使用 identity_type = AGENT_IDENTITY 部署每个智能体
  • [ ] 将低风险的共享角色放到项目级 principalSet 上
  • [ ] 仅按智能体粒度授予敏感数据访问权限
  • [ ] Rebind per-agen

……(正文超出本站单页篇幅上限,此处截断;完整表述请见下方原文入口。)

译文由上游机器翻译生成,可能有误;判断请以英文原文为准。

英文原文(来源本站未改写)

Why your agents need their own identity

Most teams run every AI agent under one shared service account. That works until an agent does something it should not, and the audit log only says "the service account did it." You cannot tell which agent acted, and you cannot cut off one agent without breaking the rest.

Google Cloud now has a fix for this called Agent Identity, part of the Gemini Enterprise Agent Platform (the new name for Vertex AI). Each agent gets its own verifiable identity, so you can grant, deny and audit access per agent, just like you do for people.

In this post I walk through how it works, how to deploy an ADK agent with it, and one production trap I think every SRE should know about before they wire this into a CI/CD pipeline: every redeploy gives your agent a brand new identity, and its old permissions do not follow it.

What Agent Identity actually is

Think of it as a passport for each agent. When you deploy an agent to Agent Runtime with this feature turned on, Google Cloud gives it a unique identity based on the open SPIFFE standard, plus an X.509 certificate that Google creates and manages for you.

In IAM, that identity shows up as a principal you can bind roles to:

principal://agents.global.org-ORGANIZATION_ID.system.id.goog/resources/aiplatform/projects/PROJECT_NUMBER/locations/LOCATION/reasoningEngines/AGENT_ENGINE_ID

A few details worth knowing:

  • The trust domain is created for you when you enable the Agent Platform API.With an organization it lives at the org level (agents.global.org-...).Without one it lives at the project level (agents.global.proj-...).
  • The identity is tied to the agent's resource ID, not to the framework you built it with.

ADK, LangGraph and others all work the same way. - Out of the box the agent gets two default roles, roles/aiplatform.agentContextEditor and roles/aiplatform.agentDefaultAccess, so it can reach its own logs, metrics, model access, sessions and memory. - The part I like most as an SRE: tokens are locked to the runtime by a Google-managed Context-Aware Access policy using mTLS certificate binding.If someone steals the token and tries to use it from outside the agent's runtime, it fails with a 401.Stolen credentials cannot be replayed.

One gotcha: in IAM bindings you must use the principal:// format, not the raw spiffe:// string. Using the SPIFFE string returns an INVALID_ARGUMENT error.

Hands-on: deploy an ADK agent with its own identity

You have three ways to turn it on. Pick the one that fits how you work.

Option 1: Python SDK. Define a normal ADK agent, wrap it, and pass identity_type when you deploy:

from google.adk.agents import Agent
import agentplatform
from agentplatform import types
from agentplatform.frameworks import AdkApp

agent = Agent(
    model="gemini-2.5-flash",
    name="minimal_agent",
    instruction="You are a helpful assistant.",
)

client = agentplatform.Client(
    project=PROJECT_ID,
    location=LOCATION,
    http_options=dict(api_version="v1beta1"),
)

remote_app = client.runtimes.create(
    agent=AdkApp(agent=agent),
    config={
        "display_name": "running-agent-with-identity",
        "identity_type": types.IdentityType.AGENT_IDENTITY,
        "requirements": ["google-cloud-agentplatform[adk,runtimes]"],
        "staging_bucket": f"gs://{BUCKET_NAME}",
    },
)

print(remote_app.api_resource.spec.effective_identity)

Note the v1beta1 API version. Agent Identity needs it.

Option 2: adk deploy. Drop a small config file in your agent folder before deploying:

echo '{ "identity_type": "AGENT_IDENTITY" }' > .agent_engine_config.json

Option 3: Agents CLI. Good for quick tests and prototypes:

agents-cli deploy --agent-identity

A tip I recommend: you can create the Agent Runtime instance with only identity_type and no code. That gives you the identity first, so you can set up IAM before the agent ever runs. Then add the code later with client.runtimes.update(...).

If you skip the identity flag, the agent keeps using service accounts as before, so existing pipelines do not break.

Least privilege in two layers

The pattern that works best is to split permissions into a shared floor and a narrow ceiling.

Layer 1: a baseline for every agent in the project. Use a principalSet so one binding covers all agents, now and in the future. Put only boring, low-risk roles here:

AGENTS="principalSet://agents.global.org-ORGANIZATION_ID.system.id.goog/attribute.platformContainer/aiplatform/projects/PROJECT_NUMBER"

for ROLE in roles/serviceusage.serviceUsageConsumer roles/browser \
            roles/aiplatform.expressUser roles/logging.logWriter \
            roles/monitoring.metricWriter; do
  gcloud projects add-iam-policy-binding PROJECT_ID \
    --member="$AGENTS" --role="$ROLE"
done

Layer 2: narrow grants per agent. Anything sensitive, like a BigQuery dataset or a Cloud Storage bucket with customer data, goes to one specific agent's principal:// only:

gcloud storage buckets add-iam-policy-binding gs://orders-data \
  --member="principal://agents.global.org-ORGANIZATION_ID.system.id.goog/resources/aiplatform/projects/PROJECT_NUMBER/locations/us-central1/reasoningEngines/AGENT_ENGINE_ID" \
  --role="roles/storage.objectViewer"

Multi-agent bonus (A2A). If a parent agent calls a subagent registered in Agent Registry, the parent agent's identity needs two roles: roles/agentregistry.viewer to look the subagent up, and roles/aiplatform.user on the subagent's reasoning engine to call it. Grant these to the parent agent, not to your own user account. This is an easy mistake that shows up as confusing permission errors.

The redeploy trap nobody talks about

This is the part that will bite SRE and platform teams. Every time a pipeline deletes and recreates an agent, the agent gets a new reasoningEngines ID, which means a brand new principal. Permissions granted to the old principal do not carry over.

Picture a normal day:

  1. Your agent runs fine with read access to gs://orders-data.
  2. A blue-green deploy, an ephemeral test environment or a terraform apply with a replace recreates the agent.
  3. The new agent starts, passes its health check, and then quietly gets 403 errors the first time it touches the bucket.

No deploy failure, no alert, just an agent that suddenly "can't find" data. That is a silent outage.

It gets worse in the other direction. Deleting an agent does not remove the IAM bindings that point to it. Those dead bindings stay in your policies until someone cleans them up by hand. Over time that is policy clutter and an audit headache.

How to fix it

Fix 1: grant access as a post-deploy step. Read the new identity right after deploy and bind roles to it:

IDENTITY=$(gcloud ai reasoning-engines describe RESOURCE_ID \
  --project=PROJECT_ID --location=LOCATION \
  --format="value(spec.effectiveIdentity)")

gcloud storage buckets add-iam-policy-binding gs://orders-data \
  --member="principal://${IDENTITY}" \
  --role="roles/storage.objectViewer"

Fix 2: let Terraform build the principal for you. Derive it from the deployed resource so bindings are always recreated with the agent:

resource "google_vertex_ai_reasoning_engine" "agent" {
  provider     = google-beta
  project      = var.project_id
  region       = var.region
  display_name = "orders-agent"

  spec {
    agent_framework = "google-adk"
    identity_type   = "AGENT_IDENTITY"
    # source_code_spec and deployment_spec here
  }
}

locals {
  agent_id        = element(split("/", google_vertex_ai_reasoning_engine.agent.id), -1)
  agent_principal = "principal://agents.global.org-${data.google_organization.org.org_id}.system.id.goog/resources/aiplatform/projects/${data.google_project.project.number}/locations/${var.region}/reasoningEngines/${local.agent_id}"
}

resource "google_storage_bucket_iam_member" "orders_reader" {
  bucket = "orders-data"
  role   = "roles/storage.objectViewer"
  member = local.agent_principal
}

Because the binding depends on the agent resource, Terraform replaces both together, and destroying the agent removes its binding too. That also solves the orphaned binding problem.

Fix 3: lean on the baseline layer. Project-level principalSet bindings survive delete and recreate, so the agent still has quota, logging and model access right after a redeploy. Keep per-agent bindings only for sensitive data.

Fix 4: add a smoke test. After deploy, have the pipeline send one real request that touches each protected resource. A 403 here fails the pipeline instead of failing in front of users.

Guardrails: what agents must never do

Allow policies say what an agent can do. For agents that act on their own, you also want hard limits that no allow policy can override. Agent Identity works with two IAM tools for this.

IAM deny policies. Block specific permissions for all agent identities across the org, no matter what roles someone grants later. Good candidates are destructive actions like deleting buckets or creating IAM roles. The official docs include a ready deny policy example you can adapt (link in Sources).

Principal Access Boundary (PAB). This limits where an agent can operate at all. For example, you can say agents in your org may only touch resources inside one folder. Even if someone accidentally grants an agent a role on a production project outside that folder, PAB blocks it.

My rule of thumb: allow policies are for daily work, deny policies are for "never, ever", and PAB is the fence around the whole yard. Agent Identity also plugs into VPC Service Controls if you need a network-level perimeter on top.

Audit: finally knowing which agent did what

With Cloud Logging turned on, every access shows the agent's own identity instead of a shared service account. Two cases matter:

  • When the agent acts on its own, the log shows only the agent's identity.
  • When the agent acts on behalf of a user, the log shows both the agent and the user.

That second case is a big deal for compliance reviews. You can answer "which agent read this data, and for whom?" without guessing.

To see all your agents and their identities in one place, open the Agent Platform Deployments page in the console and look at the Identity column, or read spec.effectiveIdentity from the API.

Limitations and caveats

Be honest with your team about these before you roll it out:

  • It needs the v1beta1 API version, so treat it as a moving target and check the docs before each upgrade.
  • Agent identities cannot be granted the legacy Cloud Storage bucket roles (legacyBucketReader, legacyBucketWriter, legacyBucketOwner).If your buckets still depend on those, plan a cleanup.
  • The redeploy trap above is by design, not a bug.Your pipeline has to handle it.
  • Deleted agents leave orphaned IAM bindings unless your tooling removes them.
  • You can turn off the Context-Aware Access token binding for special token-sharing cases, but Google strongly discourages it because it reopens the door to credential theft.

I would not. - Identity controls what an agent can reach, not what it decides to do.A prompt injection can still trick an agent into misusing access it legitimately has.Pair this with content safety controls like Model Armor and keep a human in the loop for risky actions.

Wrap-up: a production checklist

Agent Identity turns agents into first-class citizens in IAM. The feature is easy to turn on. The real work is in the pipeline around it. Here is the checklist I would use:

  • [ ] Deploy every agent with identity_type = AGENT_IDENTITY
  • [ ] Put low-risk shared roles on a project principalSet
  • [ ] Grant sensitive data access per agent only
  • [ ] Rebind per-agen

... (truncated at the site's per-page length limit; see the source link below for the full text.)

出处https://dev.to/gde/your-ai-agent-just-got-a-passport-agent-identity-on-google-cloud-and-the-redeploy-trap-nobody-52ip抓取日期 · 采集源 DEV Community

03 / EVIDENCE GAPS

这条还缺什么证据?

下面每条都由本条已有字段推出(等级、理由、商业模式、来源次数、是否演示), 本站不生成推测性结论;通用验证方法放在方法论页。

  • 可核验的收入或付费证据查官网定价页与付费口径;第三方数据源(如 GetLatka)只作旁证,需标注来源与时点。
  • 商业模式未定确认按席位/按用量/授权还是开源托管版收费;开源项目另查 LICENSE 与是否存在付费版。
  • 只有单一来源找一手站点或其他渠道是否重复出现同一产品;社区热帖数量不等于商业进展。

通用验证清单(谁有这个问题/谁愿意付费/一个人能交付哪一小步)见我们的筛选方法。

04 / SIGNAL HISTORY

发现时间线