4. IAM 策略编写实践:最小权限原则与常见模式

聊到 IAM 策略,绕不开一个词 —— 最小权限。说白了,就是给每个用户、角色或服务只分配完成任务所必需的那点权限。多一个 Action 都不给。

听起来简单?我在实际项目里见过太多反面案例了。一开始图方便给了 "Action": "*",后来出事了才追悔莫及。你想想,云上的风险往往就藏在这些“反正以后再说”的策略里。

4.1 最小权限:不只是原则

最小权限不是一句口号,它需要落到每个策略的 Action、Resource、Condition 上。我习惯用三个维度来拆解:

  • Action 最小化:只列出业务功能必须的操作,绝不写 "s3:*" 或 "ec2:*"。
  • Resource 最小化:用 ARN 精确到桶、前缀、对象键,比如 arn:aws:s3:::my-bucket/data/*。
  • Condition 最小化:附加约束条件,如 IP 限制、MFA 要求、加密状态。

我记得有一次帮一个金融客户做审计,发现他们的数据工程师竟然有 iam:CreateUser 权限。一问才知道,当初复制粘贴了一个管理员的策略模板。嗯,这就是典型的缺乏最小权限意识。

核心检查清单:

  1. 每个 Action 是否都明确需要?
  2. Resource 是否只覆盖必要范围?
  3. 是否有可选的 Condition 可以收紧?
  4. 是否能用 Deny 排除高风险操作?

4.2 策略编写的基本套路

我写 IAM 策略的流程其实挺固定的。先明确「谁」要「对什么资源」做「哪些操作」,再考虑「在什么条件下允许」。下面这张图能帮你快速理清思路:

最小权限策略决策流程 1. 确定主体/角色 2. 分析业务所需权限 3. 列出必要 Action 集合 4. 限定 Resource 为最小范围 5. 附加 Condition(可选) 测试 + 持续审计 💡 每步都在收窄权限 不要跳过任何一步。 尤其第3步,别偷懒写 * 。 Condition 是最容易被 忽略的“安全带”。

4.3 常见模式与反模式

策略写多了,你会发现有些模式反复出现。我整理了下面这张表,方便你对比:

模式/反模式说明典型案例
基于角色的策略将权限附加到 IAM 角色,用户通过切换角色获取权限开发者角色只能读写 dev 环境的 S3
基于资源的策略直接在资源(如 S3 桶)上定义谁可以做什么S3 桶策略允许特定账户访问
条件键限定用 aws:SourceIp、aws:RequestedRegion 等缩小范围只允许公司 VPN IP 调用 API
❌ 超级管理员模式直接给用户 AdministratorAccess 托管策略新员工入职就给 admin,后来误删关键资源
❌ 通配符滥用"Action": "s3:*" 或 "Resource": "*"本应只读的脚本获得了删除权限

我曾经在一个生产环境里发现某应用使用的服务角色策略写的是 "Action": "ec2:*"。调查后才明白,当初为了“调试方便”临时加上的,交付时忘记改回去了。结果这台实例被入侵后,攻击者能创建任意 EC2 实例并外泄数据。教训很惨痛。

4.4 实战:从宽策略到细粒度

看一个真实的例子。假设需要给一个数据分析师权限,让他可以读取 S3 中某个特定前缀下的 CSV 文件。

第一阶段:新手常犯的宽策略

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:GetObject",
      "Resource": "*"
    }
  ]
}

这个策略的问题显而易见:他可以读你账户下任意桶的任意对象。假如桶里还有配置文件或凭据,风险极大。

第二阶段:加上桶限定

{
  "Effect": "Allow",
  "Action": "s3:GetObject",
  "Resource": "arn:aws:s3:::data-analytics-prod/*"
}

现在他只能读取 data-analytics-prod 这个桶了。但桶里可能有非 CSV 的敏感文件。

第三阶段:增加路径前缀和 Condition

{
  "Effect": "Allow",
  "Action": "s3:GetObject",
  "Resource": "arn:aws:s3:::data-analytics-prod/team-a/reports/*.csv",
  "Condition": {
    "Bool": {
      "aws:SecureTransport": "true"
    }
  }
}

这样只允许通过 HTTPS 读取指定前缀下的 CSV 文件。细粒度到位了。

4.5 避坑指南

  • 不要依赖 Deny 来兜底:Deny 优先级高,但它不是万能的。更好的方式是让 Allow 本身就足够精准。
  • 注意显式 Deny 与隐式 Deny 的区别:没允许的操作默认就是拒绝(隐式 Deny)。显式 Deny 通常用于紧急封锁,使用时要写清楚原因。
  • 策略模拟器是好帮手:写完策略后,先用 IAM Policy Simulator 测试一遍,看看实际效果是否满足要求。我每次写新策略都会跑一遍,省得上线后出 bug。
  • 定期审计:用 Access Analyzer 或 CloudTrail 分析实际被调用的权限,清理那些“僵尸权限”。

我个人习惯在策略里加上 "Sid": "AllowReadOnlyReports" 这样的描述。半年后回来维护时,一眼就能看出这段策略的意图。别小看这个 Sid,它能省很多沟通成本。

最小权限不是一次性能搞定的。业务在变,角色在变,权限也得跟着迭代。养成“写完策略先问自己三个为什么”的习惯:这个 Action 真的必要吗?Resource 能再缩吗?Condition 能用上吗?久而久之,你写的策略会越来越干净。