IAM 策略评估与显式拒绝

开发者的 AWS 安全实践

Rahul Singh

Technical Product Manager

策略是一组规则

{
  "Effect": "Allow",
  "Action": "s3:GetObject",
  "Resource": "arn:aws:s3:::reports/*",
  "Condition": {
    "Bool": {
      "aws:SecureTransport": "true"
    },
    "IpAddress": {
      "aws:SourceIp": "203.0.113.0/24"
    }
  }
}

一个 IAM 语句的三个字段沿一条主干自上而下排列并编号 1 到 3:Effect 表示 allow 或 deny,Action 表示调用哪个 API,Resource 表示指向的对象,由 ARN 命名。

开发者的 AWS 安全实践

策略是一组规则

{
  "Effect": "Allow",
  "Action": "s3:GetObject",
  "Resource": "arn:aws:s3:::reports/*",
  "Condition": {
    "Bool": {
      "aws:SecureTransport": "true"
    },
    "IpAddress": {
      "aws:SourceIp": "203.0.113.0/24"
    }
  }
}

一个 IAM 语句的四个字段沿一条主干自上而下排列并编号 1 到 4:Effect 表示 allow 或 deny,Action 表示调用哪个 API,Resource 表示由 ARN 命名的目标对象,Condition 表示需要满足的条件。最后一行写着:四个字段,一条规则。

开发者的 AWS 安全实践

三问一答

问题

  • Action:这是该调用吗
  • Resource:这是目标吗
  • Condition:条件是否匹配

答案

  • Effect:允许或拒绝

一个 IAM 语句的四个字段上下排列:Action、Resource 和 Condition 用一个括号归为 "The question",Effect 用另一括号归为 "The answer"。

开发者的 AWS 安全实践

规则不止来自一个地方

一个附加到角色的策略文档,箭头从角色指向一个存储桶。

基于身份

  • 附加到角色
  • 该角色能做什么
开发者的 AWS 安全实践

规则不止来自一个地方

一个附加到角色的策略文档,箭头从角色指向一个存储桶。

一个附加到资源的策略文档,箭头从主体指向一个存储桶。

基于身份

  • 附加到角色
  • 该角色能做什么

基于资源

  • 附加到被访问的对象
  • 谁能访问此存储桶
开发者的 AWS 安全实践

当规则相互矛盾时

{"Effect": "Allow", "Action": "s3:*", "Resource": "*"}
{"Effect": "Deny",  "Action": "s3:DeleteObject", "Resource": "*"}
开发者的 AWS 安全实践

当规则相互矛盾时

{"Effect": "Allow", "Action": "s3:*", "Resource": "*"}
{"Effect": "Deny",  "Action": "s3:DeleteObject", "Resource": "*"}

请求: s3:DeleteObject 的结果:Denied。

显式拒绝优先于任何允许,再宽也无效

一条允许语句和一条拒绝语句同时作用于一个请求,拒绝路径加粗,结果标注为 denied。

开发者的 AWS 安全实践

评估顺序与隐式拒绝

IAM 策略评估流程图:API 请求先检查是否存在适用的显式拒绝,再检查是否存在适用的允许;若二者皆无,则为隐式拒绝。

  • 显式拒绝: 有语句明确说不行
  • 允许: 有语句说可以,且无任何拒绝
  • 隐式拒绝: 没有任何相关语句
开发者的 AWS 安全实践

四个请求,三种结果

{"Effect": "Allow", "Action": "s3:*",
 "Resource": "*"}

{"Effect": "Deny", "Action": "s3:DeleteObject",
 "Resource": "*"}
  • s3:GetObject → 允许:广泛的允许已覆盖
  • s3:DeleteObject → 显式拒绝:有语句明确拒绝
  • kms:Decrypt、dynamodb:GetItem → 隐式拒绝:此策略未涉及这些服务
  • KMS 管理加密密钥;DynamoDB 是托管键值数据库
开发者的 AWS 安全实践

为何加权限常无效

同样错误,两个原因

显式拒绝

  • 再加允许无济于事
  • 找到该拒绝,再收窄或移除

隐式拒绝

  • 加一条窄范围的允许
  • 加在发起调用的身份上

一个 AccessDenied 错误分叉成两种原因。左侧:找到了 deny,因此再多的 allow 也无效。右侧:没有找到 allow,因此在调用身份上添加一条窄范围 allow 即可解决。

开发者的 AWS 安全实践

让我们一起练习吧!

开发者的 AWS 安全实践

Preparing Video For Download...