欢迎光临

Google Cloud IAM 权限管理与安全最佳实践:从入门到生产级配置

为什么需要深入理解 Google Cloud IAM

在 Google Cloud Platform (GCP) 上构建任何生产级应用时,身份与访问管理(Identity and Access Management,简称 IAM)是最基础也最关键的安全防线。许多团队在云迁移初期往往采用”先跑通再说”的策略,给所有服务账号绑定 Editor 角色,或者在项目层级使用过于宽泛的权限——这种做法在 PoC 阶段看似高效,一旦进入生产环境,就会暴露出严重的安全隐患。

Google Cloud 数据中心服务器机架

根据 Google 2024 年发布的云安全调查报告,超过 60% 的云安全事件源于 IAM 配置不当。权限过于宽泛、服务账号密钥管理不善、未遵循最小权限原则,是排名前三的安全风险。本文将系统性地梳理 Google Cloud IAM 的核心概念、最佳实践和常见陷阱,帮助你在 GCP 上构建既安全又高效的权限体系。

IAM 核心概念:角色、政策与成员

理解 IAM 的工作机制,首先要掌握三个基础概念:成员(Principal)、角色(Role)和政策(Policy)。

IAM 访问控制概念图

成员(Principal)

在 GCP 中,一个”成员”是任何可以发起 API 请求的实体。常见的成员类型包括:

成员类型 标识符格式 典型用途
Google 账号 user:email@example.com 个人用户管理 GCP 资源
服务账号 serviceAccount:name@project.iam.gserviceaccount.com 应用程序或 VM 实例的 API 调用身份
Google 群组 group:team@example.com 批量管理一组用户的权限
G Suite 域名 domain:example.com 授予整个域名的用户访问权限
公共成员 allUsers 或 allAuthenticatedUsers 匿名访问或所有已验证用户

生产环境中,建议优先使用服务账号和 Google 群组来管理权限,尽量避免直接绑定单个用户账号,也绝对不要在生产环境中使用 allUsers(除非明确需要公开资源,如静态网站托管)。

角色(Role)

角色是权限的集合。GCP 提供三种类型的角色:

  • 基础角色(Basic Roles):Owner、Editor、Viewer。这些角色范围太宽,已不推荐使用。
  • 预定义角色(Predefined Roles):Google 为各个服务精心设计的细粒度角色,如 roles/compute.admin、roles/storage.objectViewer。
  • 自定义角色(Custom Roles):由用户自行组合权限列表,适用于有特殊需求的场景。

Google 的官方建议是:优先使用预定义角色,无法满足需求时再创建自定义角色。基础角色仅应在评估和测试阶段使用,生产环境必须禁用。

政策(Policy)

IAM 政策是一个 JSON 或 YAML 格式的文档,描述哪些成员在哪些资源上拥有哪些角色。政策以绑定(Binding)的形式组织,每个绑定将一组角色关联到一组成员。一个典型的 IAM 政策示例如下:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
  "bindings": [
    {
      "role": "roles/storage.objectViewer",
      "members": [
        "serviceAccount:web-app@project.iam.gserviceaccount.com",
        "group:data-team@example.com"
      ]
    },
    {
      "role": "roles/storage.objectAdmin",
      "members": [
        "serviceAccount:backup-job@project.iam.gserviceaccount.com"
      ]
    }
  ],
  "etag": "BwX8E8C8E8="
}

政策的继承规则是:子资源继承父资源的政策。这意味着在项目层级授予的权限,会自动应用到该项目下的所有 Cloud Storage 存储桶、Compute Engine 实例等资源。理解这一点对设计权限边界至关重要。

服务账号管理与密钥轮换

服务账号是 GCP 中最重要的身份管理工具。它是一个非人类账号,用于代表应用程序或计算实例进行 API 调用。正确管理服务账号是保障云安全的核心环节。

服务账号的最佳实践

1. 为每个应用创建独立服务账号:不要所有应用共用一个服务账号。每个微服务、每个定时任务、每个 CI/CD 流水线都应该有自己专用的服务账号,这样权限边界清晰,任何单一账号的泄露不会波及其他服务。

2. 使用 GKE Workload Identity 而非服务账号密钥:在 Google Kubernetes Engine 上运行的 Pod,可以通过 Workload Identity 绑定到服务账号,完全避免使用 JSON 密钥文件。这不仅消除了密钥泄露的风险,还能让 Kubernetes 内的 Pod 自动获得临时凭证。


1
2
3
4
5
6
7
8
9
10
11
12
13
# 创建服务账号
gcloud iam service-accounts create my-app-sa \
    --display-name="My App Service Account"

# 绑定 Workload Identity 到 K8s ServiceAccount
gcloud iam service-accounts add-iam-policy-binding \
    my-app-sa@project.iam.gserviceaccount.com \
    --role roles/iam.workloadIdentityUser \
    --member "serviceAccount:project.svc.id.goog[namespace/my-ksa]"

# 在 K8s 上添加注解
kubectl annotate serviceaccount my-ksa \
    iam.gke.io/gcp-service-account=my-app-sa@project.iam.gserviceaccount.com

3. 定期轮换服务账号密钥:如果确实需要使用服务账号密钥(例如在本地开发环境或非 GCP 环境中运行的应用),必须建立密钥轮换机制。建议每 90 天轮换一次,并启用密钥旋转的自动化。


1
2
3
4
5
6
7
8
9
10
11
# 列出所有密钥
gcloud iam service-accounts keys list \
    --iam-account=my-app-sa@project.iam.gserviceaccount.com

# 创建新密钥
gcloud iam service-accounts keys create key.json \
    --iam-account=my-app-sa@project.iam.gserviceaccount.com

# 删除旧密钥
gcloud iam service-accounts keys delete KEY_ID \
    --iam-account=my-app-sa@project.iam.gserviceaccount.com

4. 禁用服务账号的用户管理功能:默认情况下,用户可以自行创建和删除服务账号密钥。这可能导致密钥泄露而不自知。建议通过组织政策(Organization Policy)限制密钥创建权限。

条件绑定与基于属性的访问控制

Google Cloud IAM 支持条件绑定(Conditional Bindings),允许你基于属性(如请求来源 IP、资源标签、时间窗口等)动态授予权限。这比静态的”谁有什么角色”更加灵活和精细。

常用条件表达式

条件绑定使用通用表达式语言(Common Expression Language,CEL)编写。以下是一些实用场景:

场景 1:只允许从公司 IP 范围访问


1
2
3
4
5
# 仅允许通过公司 VPN 的 IP 范围访问 Cloud SQL
gcloud projects add-iam-policy-binding my-project \
    --member="serviceAccount:data-pipeline@project.iam.gserviceaccount.com" \
    --role="roles/cloudsql.client" \
    --condition="expression=request.match('/ip_ranges:203.0.113.0/24'),title=VPN_Only"

场景 2:基于资源标签的权限控制


1
2
3
4
5
6
7
8
# 对标记为 environment=production 的资源授予只读权限
# 对标记为 environment=dev 的资源授予读写权限
{
  "condition": {
    "expression": "resource.matchTag('environment', 'production')",
    "title": "production_read_only"
  }
}

场景 3:时间窗口限制


1
2
3
4
5
6
7
# 仅在业务时间(9:00-18:00)允许访问
{
  "condition": {
    "expression": "request.time.getHours('Asia/Shanghai') >= 9 && request.time.getHours('Asia/Shanghai') < 18",
    "title": "business_hours_only"
  }
}

条件绑定是构建零信任架构的重要工具。建议在以下场景中优先使用条件绑定:

  • 敏感数据访问(如 PII、财务数据)需要限制特定网络或设备
  • 生产环境的关键操作需要审批流程
  • 临时授予的紧急权限需要自动过期

组织层面的 IAM 治理

当你的 GCP 项目从几个扩展到几十个甚至上百个时,逐个项目管理 IAM 变得不可持续。这时需要在组织(Organization)层级建立统一的 IAM 治理框架。

推荐的组织层级结构

一个典型的 GCP 资源层级结构如下:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
组织(example.com)
├── 文件夹:安全团队
│   ├── 项目:安全审计日志
│   └── 项目:密钥管理
├── 文件夹:生产环境
│   ├── 文件夹:电商平台
│   │   ├── 项目:用户服务
│   │   ├── 项目:订单服务
│   │   └── 项目:支付服务
│   └── 文件夹:数据分析平台
│       ├── 项目:数据管道
│       └── 项目:BI 报表
└── 文件夹:开发与测试环境
    ├── 项目:开发环境
    └── 项目:测试环境

在组织层级上,建议设置以下角色:

  • 组织管理员(roles/resourcemanager.organizationAdmin):3-5 人,负责管理资源层级结构
  • 安全审核员(roles/iam.securityReviewer):安全团队,具有只读审计权限
  • 文件夹管理员:每个文件夹分配管理员,负责该文件夹下项目的权限管理

组织政策(Organization Policies)

组织政策是 GCP 的”全局开关”,可以强制约束所有项目的行为。关键的安全相关组织政策包括:


1
2
3
4
5
6
7
8
9
10
11
12
13
# 限制服务账号密钥创建(推荐)
gcloud resource-manager org-policies enable-enforce \
    constraints/iam.disableServiceAccountKeyCreation \
    --organization=ORG_ID

# 限制公共 IP 访问(防止意外暴露)
gcloud resource-manager org-policies set-policy policy.yaml \
    --organization=ORG_ID

# 要求使用 CMEK(客户管理加密密钥)
gcloud resource-manager org-policies enable-enforce \
    constraints/gcp.restrictNonCmekServices \
    --organization=ORG_ID

以下是我推荐的”必须启用”的组织政策清单:

政策约束 作用 优先级
iam.disableServiceAccountKeyCreation 禁止创建新的服务账号密钥
iam.disableServiceAccountKeyUpload 禁止上传外部密钥
compute.restrictLoadBalancerCreationForTypes 限制负载均衡器类型
storage.uniformBucketLevelAccess 强制使用统一的存储桶级访问控制
sql.restrictPublicIp 禁止 Cloud SQL 使用公共 IP

IAM 审计与监控

配置好 IAM 只是第一步,持续监控和审计权限使用情况同样重要。GCP 提供了 Cloud Audit Logs 和 Cloud Asset Inventory 两个核心工具来帮助追踪 IAM 变更。

设置审计日志提醒


1
2
3
4
5
6
7
8
9
10
11
12
# 创建日志接收器,将 IAM 变更日志发送到 BigQuery
gcloud logging sinks create iam-audit-sink \
    bigquery.googleapis.com/projects/my-project/datasets/iam_audit \
    --log-filter="protoPayload.methodName=SetIamPolicy OR protoPayload.methodName=google.iam.admin.v1.CreateRole"

# 创建 Pub/Sub 主题,用于实时告警
gcloud pubsub topics create iam-change-alerts

# 设置日志路由器
gcloud logging sinks create iam-alert-sink \
    pubsub.googleapis.com/projects/my-project/topics/iam-change-alerts \
    --log-filter="protoPayload.methodName=SetIamPolicy"

将审计日志送到 BigQuery 后,可以运行以下 SQL 查询来发现异常权限变更:


1
2
3
4
5
6
7
8
9
10
11
12
SELECT
  protopayload_auditlog.authenticationInfo.principalEmail AS user,
  protopayload_auditlog.servicedata_v1_iam.policyDelta.bindingDeltas AS changes,
  timestamp
FROM `my-project.iam_audit.cloudaudit_googleapis_com_activity_*`
WHERE
  protopayload_auditlog.methodName = 'SetIamPolicy'
  AND protopayload_auditlog.servicedata_v1_iam.policyDelta.bindingDeltas
    IS NOT NULL
  AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)
ORDER BY timestamp DESC
LIMIT 100

使用 Cloud Asset Inventory 做权限分析

Cloud Asset Inventory 可以扫描整个组织或特定项目的 IAM 政策,生成全面的权限报告。建议每周运行一次扫描:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 导出全组织的 IAM 政策
gcloud asset export \
    --organization=ORG_ID \
    --content-type=iam-policy \
    --output-bigquery-table=projects/my-project/datasets/asset_inventory/tables/iam_policies

# 分析哪些服务账号有 Editor 或 Owner 角色
SELECT
  asset_type,
  resource,
  JSON_EXTRACT_ARRAY(iam_policy.bindings) AS bindings
FROM `my-project.asset_inventory.iam_policies`
WHERE
  EXISTS (
    SELECT 1 FROM UNNEST(JSON_EXTRACT_ARRAY(iam_policy.bindings)) AS binding
    WHERE
      JSON_EXTRACT_SCALAR(binding, '$.role') IN (
        'roles/editor', 'roles/owner'
      )
  )

常见陷阱与排查方法

即使经验丰富的 GCP 用户,也常常在 IAM 配置上踩坑。以下是最常见的几个问题及解决方法:

权限传播延迟

IAM 政策变更通常需要 60-120 秒才能完全生效,这在自动化部署中常常导致问题。例如,刚创建的服务账号立即尝试访问资源,可能因权限尚未同步而失败。解决方法是在 Terraform 或 Deployment Manager 的部署脚本中,在资源创建和首次使用之间加入适当的等待时间(如 90 秒)。

“权限不足”但看起来配置正确

当遇到 Permission Denied 错误时,建议按以下顺序排查:

  1. 检查是否在正确的资源层级上授予了权限(项目级 vs 资源级)
  2. 确认是否有更严格的”拒绝”政策覆盖了”允许”政策
  3. 检查组织政策(Organization Policy)是否限制了该操作
  4. 使用 Policy Troubleshooter 工具可视化分析权限路径

Policy Troubleshooter 是排查权限问题的利器,可通过命令行或 Console 使用:


1
2
3
4
5
# 使用 Policy Troubleshooter 排查
gcloud policies troubleshoot \
    --principal=serviceAccount:my-app@project.iam.gserviceaccount.com \
    --permission=storage.objects.list \
    --resource=//storage.googleapis.com/my-bucket

服务账号的”隐式”权限

很多开发者不知道,GCP 的某些服务(如 Compute Engine、Cloud Functions)在创建时会自动创建服务账号,并授予 Editor 角色。这会导致实际权限远超预期。建议在项目创建初期就禁用这种默认行为:


1
2
3
4
5
6
7
8
# 禁用 Compute Engine 默认服务账号的自动 Editor 角色
gcloud compute project-info add-metadata \
    --metadata google-compute-default-service-account=disable

# 或者使用自定义服务账号启动 VM
gcloud compute instances create my-instance \
    --service-account=my-custom-sa@project.iam.gserviceaccount.com \
    --scopes=cloud-platform

总结与行动清单

Google Cloud IAM 是一个强大但复杂的系统,正确配置它需要持续的学习和实践。以下是我为每个 GCP 项目推荐的”最低安全配置清单”:

  1. 禁用基础角色:在项目层面检查是否有任何角色为 Owner/Editor/Viewer 的绑定,替换为预定义角色
  2. 使用服务账号最小权限:为每个应用创建独立服务账号,只授予其实际需要的权限
  3. 启用密钥轮换:如果使用服务账号密钥,确保有自动化轮换机制
  4. 部署组织政策:至少启用 iam.disableServiceAccountKeyCreation 和 storage.uniformBucketLevelAccess
  5. 设置审计日志:将 IAM 变更日志发送到 BigQuery 或 Pub/Sub,建立实时告警
  6. 定期审核:使用 Cloud Asset Inventory 每周扫描一次权限,发现并修复过度授权
  7. 使用条件绑定:对敏感操作添加网络或时间限制
  8. 启用 Workload Identity:在 GKE 上使用 Workload Identity 替代服务账号密钥

安全性不是一劳永逸的配置,而是一个持续的过程。随着你的 GCP 使用规模不断扩大,IAM 治理也需要持续演进。建议每季度进行一次全面的 IAM 审计,确保权限体系始终处于最佳状态。

GCP 云安全监控仪表盘

最后,推荐查阅 Google 官方的 IAM Best Practices 文档,获取最新的安全建议和更新。云安全领域变化迅速,保持学习是保障安全的最佳方式。

【本站文章皆为原创,未经允许不得转载】:汤不热吧 » Google Cloud IAM 权限管理与安全最佳实践:从入门到生产级配置
分享到: 更多 (0)