LabHub
学习 学习路径 课程

云权限设计

把策略 JSON 一行行拆开

在 LabHub 中继续学习

一句话总结

策略归根结底是一份说明四件事的文档——允许或拒绝(Effect)对什么(Resource) 执行哪些操作(Action),以及这些规则在什么条件下(Condition)生效

概念图: 策略语言的版本 · 存储桶本身 · 存储桶中的对象 · 该服务属于全局服务

为什么需要理解这些内容

策略即使语法完全有效,也可能开放出超出预期的权限。如果只确认 Allow 效果, 却不检查资源范围和条件,那么通过评审的策略很快就会成为权限提升的路径。 因此,必须把策略拆分为各个组成部分,并按照固定顺序检查危险的组合。

它是如何工作的

最小形式

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ReadReportsOnly",
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:ListBucket"],
      "Resource": [
        "arn:aws:s3:::acme-reports",
        "arn:aws:s3:::acme-reports/*"
      ]
    }
  ]
}

Version 虽然看起来像日期,但它表示的是策略语言的版本。应原样使用 2012-10-17。改成其他值后,变量替换等功能将会消失。

Resource 为什么要写两行

这是初学者最容易出错的地方。

两者是不同的资源。只写其中一个,就会出现“能看到列表却打不开文件” 或者恰好相反的情况。

ARN 的结构

arn:aws:s3:::acme-reports/reports/2026/*
 │   │   │  │ │        └ 자원 경로
 │   │   │  │ └ 계정 ID (S3 는 비움)
 │   │   │  └ 리전 (S3 는 전역이라 비움)
 │   │   └ 서비스
 │   └ 파티션 (aws / aws-cn / aws-us-gov)
 └ 고정

其中出现空字段并不是拼写错误,而是表示该服务属于全局服务

通配符——风险取决于它出现的位置

表达式 含义 风险等级
"Action": "s3:Get*" 所有读取类操作
"Action": "s3:*" S3 的所有操作(包括删除)
"Action": "*" 所有服务的所有操作 管理员
"Resource": "*" 所有资源 视上下文而定

如果 "Action": "*""Resource": "*" 同时出现在一条语句中, 它授予的就是管理员权限。这是评审策略时最先应该查找的组合。

Condition——真正收紧权限的地方

这是限制权限最有力的手段,却也是最少被使用的手段。

"Condition": {
  "IpAddress":     { "aws:SourceIp": ["203.0.113.0/24"] },
  "Bool":          { "aws:SecureTransport": "true" },
  "StringEquals":  { "aws:PrincipalTag/team": "platform" },
  "DateLessThan":  { "aws:CurrentTime": "2026-12-31T00:00:00Z" }
}

同一个 Condition 块内的多个键以 AND 连接,而同一个键包含多个值时则使用 OR。混淆这条规则,会得到与原本意图完全相反的策略。

NotAction 是一个陷阱

{ "Effect": "Allow", "NotAction": "iam:*", "Resource": "*" }

它看起来像是“允许除 IAM 之外的所有操作”,但实际上,未来推出的所有新服务 也会被自动允许。原因在于这是一份黑名单,而不是白名单。 权限应始终通过允许列表明确列出。

阅读顺序

评审时按照以下顺序检查会更快。

  1. 先看 Effect: Deny 语句——哪些操作被绝对禁止
  2. Action 中是否包含 *
  3. Resource 中是否包含 *
  4. 是否有 Condition——如果没有,该权限从任何地方都能生效
  5. 是否有 NotAction / NotResource——如果有,就要保持警惕

实际工作中会遇到的情况

下一步

接下来了解无需分发长期密钥也能授予权限的方法——角色与临时凭证。