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 只能处于一条父级路径中,不能同时挂到两棵树下。本案例按你的场景采用租户优先,环境策略在各租户下维护。
身份与管理职责#
| 职责 | 日常工作 | 授权原则 |
|---|---|---|
| 身份管理员 | 创建、停用公司账号,管理组与 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 时,按以下顺序调查:
- 保存完整错误、时间、目标操作和资源;不要先加 Editor。
- 确认真实身份:用户、ADC、被模拟 SA、部署 SA 或运行 SA。
- 确认缺少或被拒绝的具体权限,以及请求真正作用的资源。
- 检查直接绑定、组成员、父级继承和条件;考虑传播延迟。
- 使用 Policy Troubleshooter 解释 IAM 允许与拒绝的来源;信息不完整时不要把未知当作允许。
- 若 IAM 授权符合预期,继续按错误检查组织约束、服务配置等;Troubleshooter 不覆盖所有访问机制。
- 只补必要权限或修正身份,并重新执行正反两类验证。
教学故障包括:绑定了错误运行 SA、给错 Bucket 授权、临时授权到期、Deny 生效、创建密钥触发组织约束、权限变更尚未传播。
参考:审计日志、Policy Troubleshooter、变更传播。
人员与权限生命周期#
入职时按职责加入组;转岗时先检查旧职责授权,避免只增加不移除。离职时结合身份系统停用与会话管理,清理组成员、直接授权、SA impersonation 路径、代码仓库及发布系统访问。
个人本地退出登录,不等于云端撤销其所有授权;组成员变更也不是保证立即生效。已经取得的短期凭据、已有 SA 密钥和其他访问路径要分别评估。若员工曾接触共享凭据或长期密钥,应按暴露情况撤销或轮换,不因员工离职直接删除仍承载业务的 SA。
定期复查高权限组、Custom Role、SA 使用者、长期密钥、临时例外、日志访问与紧急恢复机制。以实际业务需求和使用证据调整权限,不能仅凭短时间未使用就断定权限不需要。
最终验收问题#
完成案例后,应能结合具体身份和资源回答:
- 为什么员工登录成功,却看不到项目?
- 为什么移除用户的项目绑定后,用户仍能访问?
- 为什么开发项目中的 SA 可能访问另一个项目的 Bucket?
- 为什么有调用应用的权限,应用读取 Bucket 仍会失败?
- 给 SA 授予角色与在 SA 上授予角色有什么区别?
- 为什么没有直接 Secret 读取权的人,可能通过生产部署间接读取它?
- 为什么存在 Allow 授权,操作仍被拒绝?
- 为什么临时授权到期后,用户仍可能访问?
- 为什么禁止新建 SA 密钥不妨碍 Cloud Run 使用绑定的 SA?
- 为什么删除组成员不等于访问即时、全面撤销?
- CLI 与应用为什么可能使用不同身份?
- 如何从日志和策略证明一次访问的允许或拒绝原因?
下一步准备#
如果以后实际执行教程,按实验 01 自行准备独立环境;以下是环境前提,不是要求读者向文档作者提供账号:
- 当前登录使用个人 Gmail 还是公司托管账号。
- 是否拥有可管理的域名及 Workspace / Cloud Identity。
- 是否存在 Organization,以及当前身份的管理权限。
- 是否有可用的实验项目和 Billing Account。
- 是否已有需要保留的组织策略、组和业务授权。
- 实验是否能够使用独立账号和虚构数据。
没有 Organization 时,可先在独立项目中学习身份、角色、SA、应用访问和部分策略实验;组织层级、公司身份治理及相应继承实验,在具备环境后继续。不能把“个人项目里的授权练习”视为已完成公司组织搭建。
教程入口:README。本资料包含实验步骤、样例应用和策略模板;所有云端操作均未执行,扩展练习须自行验证。