谷歌云 IAM 权限管理教程:资源层级、角色类型、服务账号与最小权限实践

谷歌云 IAM 权限管理

Google Cloud IAM(Identity and Access Management)是 GCP 上所有资源访问控制的基础。每一次对 GCP API 的调用,无论是创建虚拟机、读取存储桶还是查询数据库,系统都会先经过 IAM 验证:这个调用者是谁,它是否有权限执行这个操作。

从 AWS 迁移到 GCP 的团队在 IAM 这里通常需要重新建立认知框架。两者的权限模型在设计思路上存在根本差别,不是把 JSON 策略文档翻译成 GCP 格式,而是需要从资源视角重新思考权限的组织方式。关于两套 IAM 体系的详细对比,可以参考 谷歌云 vs AWS 的完整分析。

GCP IAM 的设计思路

AWS IAM 是身份中心模型:定义一个 IAM 角色,写一份 JSON 策略文档说明这个角色能做什么,然后把策略附加到身份上。权限跟着身份走,身份能做什么由策略文档决定。

GCP IAM 是资源中心模型:在某个具体资源上,绑定一个三元组——谁(Member)被授予了什么角色(Role)。表达的不是”这个身份能做什么”,而是”这个资源上,谁有什么权限”。同一个用户可能对不同资源有不同角色,权限随资源的不同而不同,不是全局附加在身份上的。

这个设计差别带来了实际操作上的不同。在 AWS 中,你创建一个 IAM 角色,写 s3:GetObject 的允许策略,附加给 Lambda 函数。在 GCP 中,你在具体的 Cloud Storage 存储桶上,绑定”服务账号 X 拥有 roles/storage.objectViewer 角色”。前者问的是”这个身份能做什么”,后者问的是”这个资源上谁能做什么”。

GCP IAM 没有 IAM User 这个概念。人类用户通过 Google 账号(Google Account)或 Google Workspace / Cloud Identity 账号访问 GCP,不需要单独创建 IAM 用户并管理访问密钥。非人类工作负载(应用程序、虚拟机、函数)使用服务账号(Service Account)。

资源层级:权限继承的基础

GCP 的所有资源组织在一个四层层级结构中:组织(Organization)→ 文件夹(Folder)→ 项目(Project)→ 资源。这个层级结构是 GCP IAM 和 AWS IAM 最大的架构差异。

组织是整个 GCP 账号体系的根节点,关联一个 Google Workspace 或 Cloud Identity 域名。在组织层级授予的 IAM 角色会自动继承到组织下所有文件夹、项目和资源。组织管理员在这里设置的权限和组织策略,对整个 GCP 账号体系全局生效。

文件夹是项目的逻辑分组,可以用来按业务线、环境或团队组织项目。一个典型的企业 GCP 结构:

Organization: company.com

├── Folder: Production

│   ├── Project: prod-web-app

│   └── Project: prod-data-pipeline

├── Folder: Staging

│   └── Project: staging-web-app

└── Folder: Development

    └── Project: dev-workspace

在 Production 文件夹上授予某个运维团队的 Google Group roles/monitoring.viewer,这个角色会自动继承到 prod-web-app 和 prod-data-pipeline 两个项目内的所有监控资源,不需要在每个项目下单独授予。这是 GCP IAM 层级继承的核心价值。

项目是 GCP 资源的基本组织单元,所有 GCP 资源(Compute Engine 实例、Cloud Storage 存储桶、Cloud SQL 数据库等)都必须属于某个项目,没有项目就没有办法创建资源。每个项目有独立的 API 启用状态、配额和计费关联。

关键规则: 上层的 IAM 角色绑定向下继承,但下层无法覆盖上层授予的权限。如果在组织层级授予了某人 roles/owner,在项目层级对他的权限做任何限制都是无效的。因此,高层级的权限授予需要格外谨慎,不应该在组织或文件夹层级随意授予宽泛的角色。

三种角色类型

GCP IAM 提供三种类型的角色,适合不同的使用场景。

基础角色(Basic Roles)

基础角色是 GCP 最早期的权限模型遗留,包含 Owner、Editor 和 Viewer 三个角色,授予范围极宽——Owner 可以管理项目内几乎所有资源和权限,Editor 可以创建和修改大部分资源,Viewer 可以查看大部分资源。

生产环境中不应使用基础角色。 Owner 和 Editor 违反了最小权限原则,一个只需要管理 Cloud Storage 的用户不应该同时拥有修改防火墙规则和管理数据库的权限。项目创建者默认获得 Owner 角色,这个权限应该在项目建立后立即评估是否需要保留或降级。

预定义角色(Predefined Roles)

预定义角色由 Google 创建和维护,针对具体服务提供精细的权限组合。每种服务通常有多个预定义角色,按照权限范围从小到大排列。以 Cloud Storage 为例:

  • roles/storage.objectViewer:只能查看对象,不能列出存储桶
  • roles/storage.objectUser:可以查看、创建、更新和删除对象
  • roles/storage.admin:完整的存储桶和对象管理权限

几个常用的预定义角色:

角色说明
roles/viewer查看所有资源(不推荐,范围过宽)
roles/compute.instanceAdmin.v1管理 Compute Engine 实例
roles/compute.networkAdmin管理 VPC 网络和防火墙规则
roles/storage.objectViewer查看 Cloud Storage 对象
roles/cloudsql.client连接 Cloud SQL 实例
roles/iam.serviceAccountUser以服务账号身份运行工作负载
roles/logging.logWriter写入 Cloud Logging

生产环境权限授予应优先从预定义角色中选择,选择能覆盖实际需求的最小权限角色。

自定义角色(Custom Roles)

当预定义角色的权限范围无法精确匹配需求时,可以创建自定义角色,手动组合具体的权限(permission)。权限的格式是 service.resource.verb,例如 compute.instances.list、storage.objects.get。

创建一个只允许列出和启动 Compute Engine 实例的自定义角色:

gcloud iam roles create instanceOperator \

  –project=my-project \

  –title=”Instance Operator” \

  –description=”Can list and start instances only” \

  –permissions=compute.instances.list,compute.instances.start \

  –stage=GA

自定义角色的维护成本高于预定义角色:GCP 添加新功能或新权限时,预定义角色会自动更新,自定义角色不会。如果业务依赖某个新权限,需要手动更新自定义角色。使用自定义角色的团队应该定期检查角色权限是否仍然符合最新需求。

IAM 绑定:正确授予角色的方式

IAM 绑定(IAM Binding)是 GCP 授权操作的基本单元,将一个主账号(Member)绑定到某个资源上的某个角色。用 gcloud 在项目层级授予角色:

# 向用户授予项目级别的 Compute 实例管理角色

gcloud projects add-iam-policy-binding my-project \

  –member=”user:dev@company.com” \

  –role=”roles/compute.instanceAdmin.v1″

# 向 Google Group 授予 Cloud Storage 只读角色

gcloud projects add-iam-policy-binding my-project \

  –member=”group:storage-readers@company.com” \

  –role=”roles/storage.objectViewer”

# 向服务账号授予 Cloud SQL 连接角色

gcloud projects add-iam-policy-binding my-project \

  –member=”serviceAccount:app@my-project.iam.gserviceaccount.com” \

  –role=”roles/cloudsql.client”

查看当前项目的完整 IAM 策略:

gcloud projects get-iam-policy my-project

IAM 策略更改是最终一致的,通常在 2 分钟内生效,极端情况下可能需要 7 分钟。 刚授予权限后立即测试如果遇到权限拒绝,不一定是配置错误,等待几分钟后再次测试。

服务账号:非人类工作负载的身份

服务账号是 GCP 为应用程序和工作负载设计的身份,格式为 name@project-id.iam.gserviceaccount.com,可以被授予 IAM 角色,也可以附加到 Compute Engine 实例,让实例上运行的应用以服务账号的身份调用 GCP API。

服务账号有一个重要的双重性质,是很多初学者感到困惑的地方。服务账号既是主账号(Principal)——可以像用户一样被授予资源访问权限;同时也是资源(Resource)——可以在服务账号本身上配置 IAM 策略,控制谁有权使用或模拟这个服务账号。

创建一个专用于 Web 应用的服务账号并授予所需权限:

# 创建服务账号

gcloud iam service-accounts create web-app-sa \

  –display-name=”Web Application Service Account” \

  –project=my-project

# 授予读取 Cloud Storage 对象的权限

gcloud projects add-iam-policy-binding my-project \

  –member=”serviceAccount:web-app-sa@my-project.iam.gserviceaccount.com” \

  –role=”roles/storage.objectViewer”

# 授予写入 Cloud Logging 的权限

gcloud projects add-iam-policy-binding my-project \

  –member=”serviceAccount:web-app-sa@my-project.iam.gserviceaccount.com” \

  –role=”roles/logging.logWriter”

将服务账号附加到 Compute Engine 实例后,实例上运行的应用不需要任何密钥或配置文件,GCP 客户端库会自动从实例元数据服务获取凭证。关于 Compute Engine 实例的创建和服务账号配置,可以参考 Cloud Compute Engine 使用教程。

几条必须遵守的服务账号规范:

每个应用应该有自己专用的服务账号,而不是多个应用共用一个。共用服务账号时,任何一个应用需要新权限都会影响其他应用,同时出现安全事件时难以确定是哪个应用的服务账号被滥用。

不要使用 Compute Engine 默认服务账号(project-number-compute@developer.gserviceaccount.com)运行生产应用。默认服务账号默认拥有项目的 Editor 基础角色,权限远超应用实际需要,违反最小权限原则。

一个 Compute Engine 实例只能关联一个服务账号,服务账号一旦确定后更换需要停止并重新配置实例。在创建实例前确认好需要关联哪个服务账号,避免后期调整。

服务账号密钥与 Workload Identity

服务账号密钥是一个 JSON 文件,包含服务账号的私钥,可以从任何地方使用这个文件以服务账号身份认证。它是最传统的服务账号使用方式,也是最危险的。

密钥文件一旦泄露(提交到 GitHub 仓库、打包进容器镜像、通过日志暴露),攻击者可以从任何位置以对应服务账号的身份调用 GCP API,直到密钥被手动撤销。密钥没有自动过期机制,管理失当的密钥会长期有效。

在 GCP 上运行的工作负载不需要服务账号密钥。 以下几种场景有对应的无密钥认证方式:

Compute Engine 实例上的应用,将服务账号附加到实例,GCP 客户端库自动从实例元数据服务(169.254.169.254)获取临时凭证,无需任何密钥文件。

GKE Pod 上的应用,使用 Workload Identity:将 Kubernetes ServiceAccount 绑定到 GCP 服务账号,Pod 获得短期有效的 GCP 访问令牌,不需要在 Pod 内挂载任何密钥文件。

GitHub Actions 等外部 CI/CD 系统,使用 Workload Identity Federation:GCP 信任外部身份提供商(GitHub OIDC 令牌),CI/CD 任务用自己的身份令牌换取短期 GCP 访问令牌,不需要在 CI 环境中存储任何 GCP 密钥。

只有在 GCP 外部、无法配置 Workload Identity 的场景(如本地开发机器、第三方系统),才考虑使用服务账号密钥,且需要设置密钥过期时间(通过组织策略强制),并定期轮换。

组织策略与 IAM 策略的区别

很多人把组织策略(Organization Policy)和 IAM 策略混为一谈,两者实际上解决的是完全不同的问题。

IAM 策略定义”谁可以对这个资源做什么”,是基于身份的访问控制,控制的是操作权限。

组织策略定义”这个组织不允许做什么”,是基于资源的约束,控制的是资源配置的合规性。组织策略不关心是谁在操作,只要操作违反了约束,无论操作者是 Owner 还是普通 Viewer 都无法绕过。

常见的组织策略约束:

  • constraints/compute.requireShieldedVm:强制所有新创建的 VM 使用屏蔽虚拟机
  • constraints/compute.vmExternalIpAccess:限制哪些项目的 VM 可以配置公网 IP
  • constraints/iam.allowedPolicyMemberDomains:限制只允许公司域名的账号被授予 IAM 角色
  • constraints/compute.skipDefaultNetworkCreation:新项目不自动创建默认 VPC

组织策略从 GCP VPC 的防火墙配置到实例类型都能覆盖,是企业统一管控 GCP 使用合规性的核心工具。关于 VPC 网络的组织策略配置,可以参考谷歌云 VPC 网络配置教程中的默认网络配置部分。

常见权限配置问题与最小权限实践

不要在项目层级授予过宽的角色

最常见的 IAM 配置错误是在项目层级授予服务账号 roles/editor 或 roles/owner,理由是”方便,先跑起来再说”。这类权限配置一旦服务账号密钥泄露或服务账号被滥用,攻击者可以删除任意资源、修改所有配置、创建新实例挖矿。

正确做法是只在具体资源上授予具体角色,而不是在项目层级授予宽泛角色。一个只需要读取某个特定 Cloud Storage 存储桶的应用,应该在那个存储桶上授予 roles/storage.objectViewer,而不是在项目层级授予 roles/storage.admin。

用 Google Group 管理用户权限

直接把 IAM 角色授予个人邮箱,在人员变动时需要逐一更新权限配置,容易遗漏。通过 Google Group 管理用户集合,把 IAM 角色授予 Group,人员加入或离开只需要修改 Group 成员,不需要改动任何 IAM 绑定。

定期审计当前 IAM 状态

# 查看项目当前完整的 IAM 绑定

gcloud projects get-iam-policy my-project \

  –format=”table(bindings.role, bindings.members)”

# 列出项目内所有服务账号

gcloud iam service-accounts list –project=my-project

# 列出某个服务账号的密钥(确认是否有长期密钥)

gcloud iam service-accounts keys list \

  –iam-account=app-sa@my-project.iam.gserviceaccount.com

GCP 的 IAM Recommender 和 Policy Analyzer 工具可以分析当前权限中哪些长期未使用,并给出缩减建议。定期运行权限审计,识别和清除不再需要的权限绑定,是保持 IAM 健康状态的基础操作。

账号开通与代理充值

配置 GCP IAM 需要有效的谷歌云账号,且在组织层级管理权限需要开通 Cloud Identity 或 Google Workspace。新账号在初期有使用限制,部分高级 IAM 功能(如 Workload Identity Federation 的某些配置)需要账号权重达到一定水平才能正常使用。
通过 谷歌云代理商 渠道开通的账号稳定性更高,支持 USDT 等灵活付款方式、免绑卡,充值享赠金返点($100 到账 $110,$500 到账 $600,$1000 到账 $1250),适合正式业务长期使用。

谷歌云优惠
滚动至顶部