GCP 用户与权限学习及实战案例#

验证:未记录
适用版本
未记录
验证范围
尚未登记验证记录。

以一家 startup 的报表应用为主线,理解员工身份、用户组、资源层级、授权、服务账号、安全约束、审计与权限撤销。目标是能够设计一套基本合理的权限方案,并解释一次访问为什么成功或失败。

本文是 hands-on 教程的背景与设计原则。公司、域名、人员及资源名称均为示例;配套实验在 labs 目录中。阅读和编写教程不需要提供个人账号,云端实验由读者以后在独立实验环境自行执行。

学习范围与方法#

重点学习 Google Cloud 的用户与权限基础。Cloud Run、Cloud Storage、Secret Manager 只是承载权限实验的应用组件,不展开其完整产品功能。

每个实验都回答六个问题:谁发起请求、使用什么凭据、访问什么资源、需要什么权限、授权来自哪里、如何验证和撤销。

建议按顺序完成各阶段。每阶段先预测结果,再操作,最后记录实际结果;同时验证应该成功和应该失败的请求。所有破坏性演示只使用可丢弃的实验资源,不能用生产资源验证删除权限。

暂不深入 GKE RBAC、复杂企业 SSO、多组织架构、VPC Service Controls、Principal Access Boundary 和完整 CI/CD 实现。知道这些控制可能影响访问即可;基础案例不配置它们。Workforce Identity Federation 面向人员身份,Workload Identity Federation 面向工作负载,本案例只在外部流水线中引入后者。

基础概念#

IAM 的基本问题是:谁在什么资源上可以执行什么操作,以及授权是否附带条件。

概念 含义 案例中的对应项
Authentication 认证 确认请求使用的身份 员工登录,应用取得身份凭据
Authorization 授权 判断该身份能否执行操作 能否读取某个 Bucket 的对象
Principal 主体 被授予访问权限的身份或身份集合 员工、Google Group、SA
Permission 权限 一个具体操作的权限 storage.objects.get
Role 角色 一组权限的集合 Storage Object Viewer
Binding 授权绑定 把角色与主体关联,可附带条件 开发组获得某个角色
Allow Policy 附着在资源上的允许策略,包含绑定 项目的 IAM 授权策略
Resource 与 Scope 访问目标及授权作用范围 项目、某个 Bucket、某个 Secret
Organization 公司云资源层级的顶层组织资源 Acme 的组织资源
Group 用于集中管理一组身份 开发团队用户组

Google Workspace / Cloud Identity 管理公司人员身份和组;GCP IAM 为身份授予云资源访问权限。创建员工账号、把员工加入组、给组授予角色,是不同的动作。

角色定义也不同于角色授予。创建 Custom Role 不会自动给任何人权限;还需要在合适的资源上授予该角色。组织级 Custom Role 可以复用于该组织内符合条件的资源,但“角色定义在组织级”并不意味着“已在整个组织授权”。

入门阅读:IAM 概览、Allow Policy、角色概览。

公司与业务设定#

Acme 使用示例域名 acme.example,有 DevOps、开发和 QA 三个团队。应用接收报表请求,从原始数据 Bucket 读取数据,生成报表并写入报表 Bucket;另从 Secret Manager 读取一个用于调用第三方服务的示例密钥。

实验使用虚构数据和无实际价值的测试密钥。初期把 Cloud Run 设置为需要认证的内部服务,由 QA 调用。真实客户登录、客户间的数据隔离属于应用授权,不能仅靠运行 SA 的 IAM 权限解决,暂不实现。

这里的租户指独立管理云资源的业务团队、业务项目或客户,不是应用中登录的最终用户。一个业务项目可以包含多个 GCP Project。案例采用先按租户划分、再按环境划分的结构:

Acme Organization
├── Shared-platform Folder              # 平台共享资源,单独授权
│   ├── acme-network Project
│   └── acme-audit Project
├── Tenant-A Folder                     # 租户 A:报表业务
│   ├── Non-production Folder
│   │   ├── acme-dev Project
│   │   └── acme-test Project
│   └── Production Folder
│       └── acme-prod Project
└── Tenant-B Folder                     # 租户 B:另一业务
    ├── Non-production Folder
    │   ├── tenant-b-dev Project
    │   └── tenant-b-test Project
    └── Production Folder
        └── tenant-b-prod Project

员工身份与租户组(与资源树分别管理)
alice → tenant-a-devops 组
bob   → tenant-a-developers 组
carol → tenant-a-qa 组
租户 B 使用自己的组;平台共享运维使用独立的平台组。

项目名称为逻辑名称;实际 Project ID 和 Bucket 名称需使用可用的唯一名称。后文的 dev、test、prod 和实验变量均指租户 A;devops、developers、qa 是租户 A 对应组的简称。租户 B 和 Shared-platform 是扩展结构示例,主线实验不要求全部创建。

“共用一个 GCP 账号”在这里应明确为共用 Organization,以及可能共用 Billing Account。员工仍使用各自的登录身份,应用使用各自的 SA。Billing Account 单独管理授权,不是上述资源树的父级;共用账单账号不会自动产生业务资源访问权。

租户边界与授权位置#

GCP Resource Manager 的层级是 Organization → Folder → Project → 服务资源;这里没有新增名为 Tenant 的层级资源,而是用 Folder 表达业务租户。Folder 可嵌套,适合按部门、业务或环境分组并继承策略。

  • 组织层:集中管理全局治理策略和确实需要全组织范围的职责,不在这里给某个租户的开发组授予业务读取、编辑角色。
  • 租户层:租户范围内的管理职责放在对应 Tenant Folder;此处的 Allow 会向下覆盖该租户所有环境,不能把仅限开发的角色放在这里。
  • 环境与项目层:租户 A 开发组的角色授予在 A 的 Non-production Folder 或具体 dev Project;QA 只获得所需测试资源权限;生产运维和部署单独授权。
  • 共享资源层:网络、审计等共享资源按需要单独授权,不因租户存在就自动开放。共享服务连接也需单独配置。

例如把 Cloud Run Viewer 授予 tenant-a-developers 在 A 的 Non-production Folder 上:该绑定可覆盖 A 的 dev/test,不覆盖 A 的 prod,也不覆盖 B 的任何环境。若 Bob 在 Organization 上另有更广授权,租户文件夹不会抵消该继承权限,必须检查所有授权来源。

Folder 本身不会自动实现网络隔离、数据隔离或应用内客户隔离;仍需分别设计 IAM、网络和应用授权。各租户、各环境应使用独立的运行 SA 和部署身份,不通过共用业务 SA 绕过租户边界。

租户优先适合按业务归属委派管理;若公司主要按生产与非生产统一治理,也可以采用 Organization → 环境 Folder → 租户 Folder → Project。一个 Project 只能处于一条父级路径中,不能同时挂到两棵树下。本案例按你的场景采用租户优先,环境策略在各租户下维护。

参考:资源层级、Folder 管理。

身份与管理职责#

职责 日常工作 授权原则
身份管理员 创建、停用公司账号,管理组与 MFA 身份系统管理权独立考虑;严格控制权限组的成员管理权
云权限管理员 管理 IAM 和安全策略 使用受控管理身份,不作为日常开发身份
平台运维 维护指定云资源 不默认拥有整个组织的 IAM 修改权
开发 编写代码,在开发环境调试 开发环境授权;生产默认无直接访问
QA 调用测试应用,查看测试输出和日志 只授予测试需要的访问
生产发布 发布获批代码 使用专用部署身份与受控流程
账单管理员 管理账单及费用相关事项 单独理解账单权限与项目关联所需权限

同一人可以兼任职责,但职责相同或人员重叠不代表应长期合并所有权限。区分 Workspace / Cloud Identity 超级管理员、Organization Administrator、项目 IAM 管理员和 Billing Administrator;组织管理员也不等于默认具有所有业务数据的读写权限。

实践原则:使用公司托管账号、启用 MFA、不共享账号;把超级管理员与日常身份分开,并准备受控的紧急恢复途径。普通员工通过组获得权限,组本身要有明确负责人和成员变更规则。能给权限组加人的人,能够间接影响访问权限。

参考:身份治理、超级管理员最佳实践、账单访问管理。

授权设计与最佳实践#

团队授权需求#

身份 dev test prod
开发组 部署、调试、使用开发数据 必要的测试结果与日志 默认不授予日常访问;按需临时看日志
QA 组 按需 调用应用、读报表、查看必要日志 默认无访问
DevOps 组 维护指定基础设施 维护指定基础设施 受控运维,不默认获得任意授权能力
生产部署 SA 不使用 不使用 更新指定应用,使用指定运行 SA
各环境运行 SA 仅本环境所需资源 仅本环境所需资源 仅本环境所需资源

此表表达业务需求。实际角色应从需要的操作反推,优先选择足够精确的预定义角色,并在进入实验时核对包含的权限。不要默认给 Owner 或 Editor,也不要为了精确而立即创建大量 Custom Role。

尽量在最小必要范围授予权限;但不是所有操作都支持同样细粒度的资源级授权。创建资源等操作可能需要父级权限,应以服务支持范围为准。

继承与有效权限#

更窄的子级 Allow 不会覆盖父级宽权限;删一条 binding 也不保证撤权。 核对资源本地、Project / Folder / Organization、直接用户授权及 Group membership 的全部路径。

相关 Deny 可以阻止已被 Allow 授予的权限;未被 Deny 不代表已经获得 Allow。实际请求还可能受组织约束或服务自身控制影响。不要把 IAM Allow 的存在当作所有操作必定成功的保证。

参考:资源层级与权限继承。

角色的维护#

Custom Role 的 Alpha、Beta、GA 表示维护者声明的成熟度,三者不改变权限的生效方式。Disabled 会停止该角色提供权限,但不会抹掉其他角色提供的同等权限。阶段不会自动晋级,GA 也不代表 Google 审核过权限设计。

实验中可设计一个有限的日常操作角色,检查其权限后经历 Alpha、Beta、GA,再禁用并观察结果。实际维护时记录角色负责人、用途和变更影响。

应用身份与最小权限#

每个环境分别使用一个专用运行 SA,例如 report-app-dev、report-app-test、report-app-prod。实际邮箱包含所在 Project ID。

调用者 → Cloud Run 调用权限 → 报表应用
                                 ↓ 以 report-app-prod 运行
                           读取原始数据 Bucket
                           创建报表 Bucket 中的新对象
                           读取指定 Secret

发布流程 → 部署 SA → 更新 Cloud Run 并绑定运行 SA
目标资源 运行 SA 所需能力 初始候选角色及授予位置
原始数据 Bucket 读取原始对象 roles/storage.objectViewer,授予在该 Bucket
报表 Bucket 创建新对象 roles/storage.objectCreator,授予在该 Bucket
一个 Secret 访问 Secret 版本内容 roles/secretmanager.secretAccessor,授予在该 Secret

这是候选权限方案,实施前核对角色当前权限。Object Viewer 也包含对象列表等权限,并非只有单个读取权限。应用为报表生成唯一对象名,不依赖覆盖已有对象;如果业务需要覆盖、读取输出或删除,应先修改需求再调整授权。QA 读取报表使用自己的授权。

SA 有两个视角:作为主体访问 Bucket;作为资源,控制谁能管理、绑定或模拟它。在某个 SA 上授予角色与把某个角色授予 SA,方向不同。

分别理解:Service Account User 的 actAs 允许把 SA 作为受支持资源的运行身份,部署者仍需部署权限;Token Creator 支持生成短期凭据和impersonation 身份。不要在项目层随手授予对所有 SA 的使用或impersonation 能力。SA Admin 也不能简单等同于 Token Creator。

默认 SA、Google 管理的 Service Agent 和自己创建的应用 SA 需要区分。不要给普通用户授予专供 Service Agent 使用的角色,也不要因不了解用途而删除其授权。

Cloud Run 使用绑定的运行 SA 和环境提供的凭据;不下载 JSON 密钥。对于本地开发,区分 gcloud 登录身份与 Application Default Credentials(ADC);应用可能没有使用 CLI 当前显示的账号。项目选择或 quota project 也不是身份和授权范围。

参考:Cloud Run 服务身份、SA 认证角色、SA 最佳实践、ADC 原理。

生产发布的权限边界#

生产部署 SA 与运行 SA 分开。部署身份只获得发布所需能力,不默认管理 IAM、Deny 或组织策略。若流水线运行在外部平台,使用 Workload Identity Federation 获取短期凭据,并限制可信仓库、分支或环境等身份属性。

能发布任意代码并以生产 SA 运行的人,可能通过代码间接读取该 SA 能访问的数据。因此,缺少直接 Secret 读取角色,不代表拥有生产部署权的人与 Secret 完全隔离。代码审核、受保护的发布流程和流水线修改权限也属于信任边界。

云审计日志通常记录流水线使用的身份;要关联到实际代码作者、批准人和版本,需要结合流水线记录。学习到此即可,不在本案例展开整套发布平台。

参考:部署流水线 SA 最佳实践。

条件授权与安全约束#

机制 案例事件 必须理解的边界
IAM Conditions 开发者获得两小时生产日志查看权 条件只约束所在绑定,其他无条件授权仍可能生效
Deny Policy 禁止指定普通人员删除生产项目 核对受支持权限;例外只解除该规则的拒绝,不产生授权
Organization Policy 禁止创建 SA 长期密钥 约束操作或配置,不负责给人授予角色;禁止新建不会撤销已有密钥

一般需求优先通过精确 Allow 解决,不需要为所有未授权行为额外写 Deny。Deny 用于明确、稳定且值得防范误授权的限制,不能替代合理的 Allow 设计。

IAM Conditions 的截止时间不等同于审批流程。案例先用它理解时间条件;后续如需申请、审批和自动到期的完整机制,再认识 Privileged Access Manager。

Organization Policy 的继承与覆盖行为取决于约束和策略类型,不把 IAM Allow 的累加规则直接套用到它。实施前先检查当前有效策略,避免把已有默认约束当作自己刚配置的结果。

Deny 演示先在隔离实验项目中验证,再讨论放在生产文件夹上的意义。不对真实生产项目执行删除验证。

参考:IAM Conditions、Deny、Deny 支持的权限、SA 组织约束。

分阶段实验与验收#

阶段 实验 通过标准 清理或回滚
0 环境盘点 确认身份系统、组织、账单、管理员、可用实验项目 能画出实际环境,不把示例值当真实配置 只读盘点,无需回滚
1 公司与员工 建立实验账号、组和 MFA;明确管理员职责 能解释在哪创建人、在哪给人授权 移除实验组成员,保留必要恢复身份
2 授权与继承 对比用户直接授权、组授权、父级授权 能追踪多条授权来源,并解释移除一条后为何仍有访问 移除实验绑定,复查继承
3 角色 查看预定义角色,创建一个有限 Custom Role 能区分角色定义与绑定;验证 Disabled 的影响 恢复阶段或移除绑定并清理角色
4 本地身份 对比 CLI、ADC 和按需模拟开发 SA 能证明每次测试使用的真实身份 清理实验凭据和模拟权限
5 应用运行 在 dev 部署报表应用,配置三个资源授权 能读输入、写新报表、读指定 Secret;不能删输入、访问无关 Secret 撤销实验授权,清理应用和虚构数据
6 QA 调用 QA 以自身身份调用受保护应用 QA 能调用不等于 QA 获得运行 SA 的云权限 移除调用及结果读取绑定
7 发布身份 使用独立部署 SA,讨论外部流水线联合认证 能区分部署、调用、运行身份,解释间接数据访问 移除实验联合信任及部署授权
8 临时访问 授予有到期时间的日志查看角色 到期后此授权不再提供权限;检查其他路径 删除过期实验绑定
9 安全约束 隔离环境验证 Deny 与禁止创建 SA 密钥 明确是哪一层拒绝,例外仍需要 Allow 恢复实验策略,保留变更前记录
10 故障排查 移除运行 SA 的读取授权或故意绑定错误 SA 从错误和日志找到真实原因,恢复最小必要授权 恢复已知正确配置
11 转岗与离职 撤销人员访问并检查直接、组、模拟等路径 解释撤销范围、传播延迟和剩余凭据问题 实验账号停用或清理,不停用共享业务 SA
12 定期复查 检查组、角色、SA、例外和日志访问 每项高权限有负责人、用途和复查结论 清理不再需要的权限

每个实验记录:执行者、目标资源、变更前状态、预期允许、预期拒绝、实际结果、时间、日志或错误依据、恢复状态。新建资源可能产生费用,进入部署阶段前确定实验规模并在完成后清理。

审计日志与故障排查#

管理操作关注 Admin Activity;对象读取等数据操作关注相关服务的 Data Access 日志。Data Access 多数默认未开启,应在相关实验前明确检查和启用需要的类别,并考虑记录量和费用。应用日志不等于云审计日志,也不要把密钥或原始敏感数据写入日志。

日志查看权本身也是敏感权限;普通日志与包含私有数据访问记录的日志可能需要不同查看角色。QA 的日志权限也应限制在必要环境和范围。

遇到 403 时,按以下顺序调查:

  1. 保存完整错误、时间、目标操作和资源;不要先加 Editor。
  2. 确认真实身份:用户、ADC、被模拟 SA、部署 SA 或运行 SA。
  3. 确认缺少或被拒绝的具体权限,以及请求真正作用的资源。
  4. 检查直接绑定、组成员、父级继承和条件;考虑传播延迟。
  5. 使用 Policy Troubleshooter 解释 IAM 允许与拒绝的来源;信息不完整时不要把未知当作允许。
  6. 若 IAM 授权符合预期,继续按错误检查组织约束、服务配置等;Troubleshooter 不覆盖所有访问机制。
  7. 只补必要权限或修正身份,并重新执行正反两类验证。

教学故障包括:绑定了错误运行 SA、给错 Bucket 授权、临时授权到期、Deny 生效、创建密钥触发组织约束、权限变更尚未传播。

参考:审计日志、Policy Troubleshooter、变更传播。

人员与权限生命周期#

入职时按职责加入组;转岗时先检查旧职责授权,避免只增加不移除。离职时结合身份系统停用与会话管理,清理组成员、直接授权、SA impersonation 路径、代码仓库及发布系统访问。

个人本地退出登录,不等于云端撤销其所有授权;组成员变更也不是保证立即生效。已经取得的短期凭据、已有 SA 密钥和其他访问路径要分别评估。若员工曾接触共享凭据或长期密钥,应按暴露情况撤销或轮换,不因员工离职直接删除仍承载业务的 SA。

定期复查高权限组、Custom Role、SA 使用者、长期密钥、临时例外、日志访问与紧急恢复机制。以实际业务需求和使用证据调整权限,不能仅凭短时间未使用就断定权限不需要。

最终验收问题#

完成案例后,应能结合具体身份和资源回答:

  1. 为什么员工登录成功,却看不到项目?
  2. 为什么移除用户的项目绑定后,用户仍能访问?
  3. 为什么开发项目中的 SA 可能访问另一个项目的 Bucket?
  4. 为什么有调用应用的权限,应用读取 Bucket 仍会失败?
  5. 给 SA 授予角色与在 SA 上授予角色有什么区别?
  6. 为什么没有直接 Secret 读取权的人,可能通过生产部署间接读取它?
  7. 为什么存在 Allow 授权,操作仍被拒绝?
  8. 为什么临时授权到期后,用户仍可能访问?
  9. 为什么禁止新建 SA 密钥不妨碍 Cloud Run 使用绑定的 SA?
  10. 为什么删除组成员不等于访问即时、全面撤销?
  11. CLI 与应用为什么可能使用不同身份?
  12. 如何从日志和策略证明一次访问的允许或拒绝原因?

下一步准备#

如果以后实际执行教程,按实验 01 自行准备独立环境;以下是环境前提,不是要求读者向文档作者提供账号:

  • 当前登录使用个人 Gmail 还是公司托管账号。
  • 是否拥有可管理的域名及 Workspace / Cloud Identity。
  • 是否存在 Organization,以及当前身份的管理权限。
  • 是否有可用的实验项目和 Billing Account。
  • 是否已有需要保留的组织策略、组和业务授权。
  • 实验是否能够使用独立账号和虚构数据。

没有 Organization 时,可先在独立项目中学习身份、角色、SA、应用访问和部分策略实验;组织层级、公司身份治理及相应继承实验,在具备环境后继续。不能把“个人项目里的授权练习”视为已完成公司组织搭建。

教程入口:README。本资料包含实验步骤、样例应用和策略模板;所有云端操作均未执行,扩展练习须自行验证。

搜索文档

输入关键词,搜索所有文档。

↑ ↓ 选择 · Enter 打开 · Esc 关闭