用 IAM Conditions 收紧 Google Cloud 权限:从管理员角色到 MCP 工具级控制

2026-07-21 41 预计阅读时间: 1 分钟
来源: cloud.google.com AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:9 分钟

Google Cloud IAM 的常规加固路径,是选择预定义角色或自定义角色,再沿组织、文件夹、项目和具体资源配置 Allow、Deny 策略。但当一个项目由多个团队或工作负载共享,或者服务不支持资源级 IAM 绑定时,仅靠“把角色绑定到更小的资源”并不足以落实最小权限原则。这时,IAM Conditions 可以继续约束角色在什么条件下生效。

角色相同,不代表授权边界相同

以 Artifact Registry 为例,将 roles/artifactregistry.editor 绑定到整个项目,意味着主体能够编辑项目内任意仓库;绑定到单个仓库,则只影响该仓库。资源级绑定通常是更直观的选择,但并非所有管理操作和服务都提供这种粒度。

IAM Conditions 在 Allow 策略绑定上附加 CEL(Common Expression Language)表达式,可以根据请求时间、目标服务以及 API 暴露的属性决定本次授权是否成立。它并不会缩小角色本身包含的权限,而是在角色与主体之间增加一道运行时判断。因此,设计条件时需要同时回答三个问题:

  • 谁获得角色:由 IAM binding 的 memberprincipal 决定。
  • 获得什么能力:由预定义角色或自定义角色决定。
  • 哪些请求可以使用这些能力:由 condition 表达式决定。

这三层不能互相替代。尤其不应把主体身份判断大量塞进 condition;允许哪些身份使用策略,通常应直接通过 binding 的主体列表表达。

限制项目 IAM 管理员能够授予的角色

roles/iam.admin 权限很宽,持有者可能授予自己其他角色或创建新角色。把它替换为项目范围的 roles/resourcemanager.projectIamAdmin 是第一步,但对自动部署服务账号而言,这个角色仍可能超过实际需求。

假设构建服务账号只需要为工作负载授予 BigQuery、Agent Platform、日志和链路追踪相关角色,可以这样实践。运行前需要设置项目 ID 和服务账号邮箱,并确保当前操作者有修改项目 IAM 策略的权限:

export PROJECT_ID="my-gcp-project"
export SA_EMAIL="builder@my-gcp-project.iam.gserviceaccount.com"

gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
  --member="serviceAccount:${SA_EMAIL}" \
  --role="roles/resourcemanager.projectIamAdmin" \
  --condition="^:^
title=LimitedIAMAdmin:
expression=api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([
'roles/aiplatform.user',
'roles/bigquery.jobUser',
'roles/bigquery.dataViewer',
'roles/cloudtrace.agent',
'roles/logging.logWriter'
])"

--condition 通常用逗号分隔字段,但 CEL 表达式中的角色列表也包含逗号,因此命令通过 ^:^ 把字段分隔符改成冒号。modifiedGrantsByRole 提供本次请求试图修改的角色集合,hasOnly(...) 要求它只能包含白名单中的角色。

同一策略可以纳入 Terraform 管理,避免生产环境中的授权规则只存在于命令历史中:

variable "project_id" {
  type = string
}

variable "sa_email" {
  type = string
}

resource "google_project_iam_member" "limited_project_iam_admin" {
  project = var.project_id
  role    = "roles/resourcemanager.projectIamAdmin"
  member  = "serviceAccount:${var.sa_email}"

  condition {
    title = "LimitedIAMAdmin"
    expression = <<-EOT
      api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([
        'roles/aiplatform.user',
        'roles/bigquery.jobUser',
        'roles/bigquery.dataViewer',
        'roles/cloudtrace.agent',
        'roles/logging.logWriter'
      ])
    EOT
  }
}

上线前应在非生产项目分别测试白名单内和白名单外的授予操作。条件表达式写错时,风险既可能是越权,也可能是部署流水线突然失去授权能力。

把 MCP 访问从“所有服务器”缩到单个工具

Google Cloud 的部分资源和服务可通过 Model Context Protocol(MCP)服务器访问。预定义角色 roles/mcp.toolUser 在项目级绑定后,会授予对该项目中可用 MCP 服务器的访问能力。对于只需要查询 BigQuery 的智能体,这个边界通常仍然太宽。

可以先将访问范围限制到 BigQuery 服务:

export PROJECT_ID="my-gcp-project"
export SA_EMAIL="analytics-agent@my-gcp-project.iam.gserviceaccount.com"

gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
  --member="serviceAccount:${SA_EMAIL}" \
  --role="roles/mcp.toolUser" \
  --condition="^:^
title=bigquery_mcp_server_only:
expression=resource.service == 'bigquery.googleapis.com'"

这里比较的是服务标识 bigquery.googleapis.com,不是 MCP 路径 bigquery.googleapis.com/mcp。如果智能体只应执行两个 SQL 工具,还可以使用 MCP 工具名称属性继续收紧:

api.getAttribute('mcp.googleapis.com/tool.name', '') in [
  'mcp_bigquery-mcp_execute_sql',
  'mcp_bigquery-mcp_execute_sql_readonly'
]

把这段 CEL 放入 condition 的 expression 字段即可。按工具名称限制时,不必再额外检查 resource.service。不过工具名会成为策略契约的一部分;部署前应核对实际工具标识,并在服务升级后进行回归验证。

时间条件适合临时运维窗口

条件也可以根据请求时间控制访问。例如,下面的 CEL 只允许柏林时区周一至周五的 09:00 至 18:00 之前访问:

request.time.getHours('Europe/Berlin') >= 9 &&
request.time.getHours('Europe/Berlin') < 18 &&
request.time.getDayOfWeek('Europe/Berlin') >= 1 &&
request.time.getDayOfWeek('Europe/Berlin') <= 5

这类规则适合人工运维权限或临时管理窗口,但不适合未经评估就套在持续运行的服务账号上。还要明确时区、夏令时、节假日和紧急响应流程;时间条件不是审批系统,也不能替代短期凭证和审计。

落地时检查四件事

IAM Conditions 提供的是精细的 Allow 控制,不是完整的权限治理方案。采用时可以按以下顺序检查:

  1. 优先把角色绑定到具体资源,只有资源级绑定不可用或粒度不足时再引入条件。
  2. 先选择最小的角色,再用条件约束请求;不要用条件包装一个本可替换掉的超宽角色。
  3. 为允许和拒绝路径都编写验证用例,并检查 Cloud Audit Logs 中的实际请求属性。
  4. 对必须跨项目统一禁止的高风险权限,评估 IAM Deny 策略,形成纵深防御。

条件越复杂,排障成本越高。把 CEL 表达式纳入 Terraform、代码评审和自动化测试,并记录属性来源与预期失败方式,才能让“精确授权”在长期运行中保持可维护。


相关推荐