IAM 策略评估逻辑完全解析 - 显式 Allow 胜过隐式 Deny 的机制

逐步解析 IAM 在允许或拒绝请求时的评估流程,涵盖隐式 Deny、显式 Allow、显式 Deny 的优先级,以及 SCP、权限边界、会话策略的交叉判定。

IAM 的评估结果只有 3 种

IAM 的策略评估看似复杂,但最终结果只有“显式 Deny”、“显式 Allow”、“隐式 Deny” 3 种。而且,优先级始终是“显式 Deny > 显式 Allow > 隐式 Deny”。隐式 Deny 是指任何策略中都没有写有 Allow 的状态。除根用户外,AWS 默认会隐式拒绝请求,因此未被显式 Allow 的操作会被自动拒绝。这就是“最小权限原则”的技术基础。显式 Allow 是指策略的 Effect 为 Allow,且请求的条件与策略的条件匹配的情况。显式 Deny 是指策略的 Effect 为 Deny 且条件匹配的情况,无论其他哪条策略中有 Allow,显式 Deny 始终优先。这条“Deny 始终胜出”的规则是 IAM 安全模型的根基。即使管理员误授予了范围很广的 Allow,也可以通过显式 Deny 的策略拒绝特定操作。

同一账户内的评估流程

同一账户内的策略评估是按顺序评估多种策略类型的多阶段过程。首先,在适用于请求的各条策略中查找显式 Deny,接着评估 Organizations 的 RCP(资源控制策略)和 SCP(Service Control Policy)。SCP 作为组织中账户的“天花板”发挥作用,SCP 中未允许的操作,无论在账户内哪条策略中被 Allow,都会被拒绝。接下来评估资源策略(S3 存储桶策略、Lambda 的资源策略等)。对于许多资源,如果身份策略或资源策略中的任意一方有显式 Allow,就会允许访问(IAM 角色的信任策略和 KMS 的密钥策略除外)。这是仅在同一账户内成立的规则,跨账户访问时两方的策略中都需要有 Allow。随后评估身份策略(IAM 策略),之后评估权限边界。权限边界是为 IAM 用户或角色设置的“上限”,只有身份策略与权限边界的交集(两方都 Allow 的操作)才会被允许。最后,对于角色会话这类会话主体,会评估会话策略。

SCP 与权限边界的交叉判定

SCP 和权限边界都是设置“允许上限”的机制,但应用级别不同。SCP 在 Organizations 的账户级别,权限边界在 IAM 实体(用户或角色)级别。两者都设置时,最终允许的操作是“SCP 允许 AND 权限边界允许 AND 身份策略允许”的交集。下面用具体示例说明。假设 SCP 允许 s3:* 和 ec2:*,权限边界允许 s3:* 和 lambda:*,身份策略允许 s3:GetObject 和 lambda:InvokeFunction。此时实际被允许的只有 s3:GetObject。lambda:InvokeFunction 因未被 SCP 允许而被拒绝。这种交叉判定使多层次的权限管理成为可能:安全团队用 SCP 设置整个组织的护栏,开发团队负责人用权限边界设置团队成员的权限上限,各个开发者用身份策略授予所需的权限。

条件键的评估 - 容易忽视的陷阱

IAM 策略的 Condition 块是根据请求属性(源 IP、请求时间、标签值等)控制访问的强大功能,但评估逻辑中存在陷阱。容易被误解的是条件键不存在时的行为。例如,设置了用 aws:SourceIp 条件限制访问的策略时,在来自 AWS 服务的内部调用(Lambda 访问 S3 等情况)中,有时不存在 aws:SourceIp。条件键不存在时,该条件会被评估为“不匹配”。Allow 策略的条件不匹配时,Allow 不会被应用,结果为隐式 Deny。Deny 策略的条件不匹配时,Deny 不会被应用,其他策略的 Allow 会生效。如果不理解这种不对称性,就会发生“设置了 IP 限制后,连来自 Lambda 的访问也被阻止了”的问题。作为对策,有一种方法是使用 aws:ViaAWSService 条件键,将经由 AWS 服务的请求排除在条件之外。此外,StringEquals 与 StringLike 的区别(通配符的处理)、IpAddress 与 NotIpAddress 的逻辑关系,也需要在设计策略时准确理解。

跨账户访问的评估规则

跨账户访问的评估规则与同一账户内不同。当账户 A 的主体访问账户 B 的资源时,账户 A 端的身份策略和账户 B 端的资源策略两方都需要有 Allow。对于许多资源,在同一账户内仅凭资源策略的 Allow 就会允许访问(IAM 角色的信任策略和 KMS 的密钥策略除外),但在跨账户时,这条“只需一方即可”的规则不适用。也来确认一下代入角色(AssumeRole)时的处理。IAM 角色的信任策略必须显式允许代入该角色的主体。AssumeRole 之后的操作遵循角色的身份策略。通过 S3 存储桶策略允许跨账户访问时,需要在存储桶策略中将账户 A 的 ARN 指定为 Principal,并且在账户 A 端的身份策略中也允许 s3:GetObject。这种双重允许的要求是一种安全机制,用于防止某一方账户的管理员未预期的访问。

参考资料(AWS 官方)

本页的第一手信息来源是 AWS 官方网站及官方文档。最新的规格与价格请以下列官方页面为准。

如本页内容与官方文档不一致,请以官方文档为准。

分享