好的,我来为你系统整理一下 MinIO / AWS S3 中 **策略 JSON 的语法和常用参数**。这份指南结合了你之前遇到的桶权限场景,帮助理解每部分的作用。 --- ## 一、策略 JSON 顶层结构 一个完整的策略由以下元素组成: ```json { "Version": "2012-10-17", // 版本号(必须,固定值) "Statement": [ // 一个或多个权限声明 { "Sid": "OptionalId", // 可选,声明ID "Effect": "Allow", // 允许或拒绝 "Principal": {...}, // 谁(仅某些类型的策略需要) "Action": [...], // 哪些操作 "Resource": [...], // 哪些资源 "Condition": {...} // 条件限制(可选) } ] } ``` > **注意**:在 MinIO 中,用户/组策略(Identity Policy)通常不需要 `Principal`,它用于存储桶策略(Bucket Policy)。我们这里主要讲解用户/组策略。 --- ## 二、各字段详解 ### 1. `Version`(必选) - **固定值**:`"2012-10-17"` - 表示策略语言的版本,当前所有 S3 兼容系统都使用这个值。 ### 2. `Statement`(必选) - 类型:**数组**,内部包含一个或多个声明对象。 - 每个声明定义一组权限。 ### 3. `Sid`(可选) - **Statement ID**:任意字符串,用于标识该声明。 例如:`"Sid": "AllowListBucket"` ### 4. `Effect`(必选) - 两个取值:`"Allow"` 或 `"Deny"` - **Deny 优先级高于 Allow**。即如果一个请求匹配了某个 Deny 声明,即使有 Allow 也会被拒绝。 ### 5. `Action`(必选) - 指定允许或拒绝的**操作**。取值可以是: - **单个操作**:`"Action": "s3:GetObject"` - **多个操作**:`"Action": ["s3:GetObject", "s3:PutObject"]` - **通配符所有操作**:`"Action": "s3:*"` (也可以是 `"*"` 表示所有服务所有操作,但不推荐) - **常用 S3 Action** 见下文第四部分。 ### 6. `Resource`(必选) - 指定操作作用的**资源**(桶、对象、前缀等)。使用 **ARN(Amazon Resource Name)** 格式。 - **MinIO / S3 的 ARN 格式**: ``` arn:aws:s3:::桶名称 arn:aws:s3:::桶名称/对象键 arn:aws:s3:::桶名称/前缀/* ``` - 示例: - `"arn:aws:s3:::orderbook"` —— 桶本身 - `"arn:aws:s3:::orderbook/*"` —— 桶内所有对象 - `"arn:aws:s3:::orderbook/2024/*"` —— 桶内 `2024/` 前缀下的所有对象 - `"arn:aws:s3:::orderbook/report.pdf"` —— 单个对象 - 可以写数组包含多个资源。 ### 7. `Condition`(可选) - 用于在**特定条件**下才生效。格式为 `"条件运算符": { "条件键": "值" }` - 常见条件运算符: - `StringEquals`、`StringNotEquals` - `StringLike`(支持 `*` 通配符)、`StringNotLike` - `IpAddress`、`NotIpAddress` - `Bool`(布尔值) - `DateGreaterThan`、`DateLessThan` - 常见条件键(S3): - `s3:prefix` —— 对象前缀 - `s3:delimiter` —— 分隔符 - `s3:max-keys` —— ListObjects 的最大数量 - `aws:SourceIp` —— 客户端 IP - `aws:RequestedRegion` —— 请求的区域 - **示例**:只允许来自特定 IP 的上传 ```json "Condition": { "IpAddress": { "aws:SourceIp": "192.168.1.100/32" } } ``` --- ## 三、策略生效规则(重要) 1. **默认隐式拒绝**:任何未在策略中明确 Allow 的操作,都会被拒绝。 2. **显式 Deny 优先**:只要任意一个声明匹配 `Effect: "Deny"`,即使其他声明有 Allow,也会被拒绝。 3. **合并策略**:用户可能同时有**用户策略**、**组策略**、**桶策略**,最终权限是这些策略的并集,再减去 Deny。 --- ## 四、常用 S3 Action 分类(MinIO 支持大部分) | 分类 | Action | 说明 | | :--- | :--- | :--- | | **读操作** | `s3:ListBucket` | 列出桶内对象(需要桶资源 `arn:aws:s3:::bucket`) | | | `s3:GetObject` | 下载对象 | | | `s3:GetObjectAcl` | 获取对象的 ACL | | | `s3:GetObjectTagging` | 获取对象的标签 | | | `s3:HeadObject` | 获取对象元数据(不返回内容) | | **写操作** | `s3:PutObject` | 上传对象 | | | `s3:DeleteObject` | 删除对象 | | | `s3:DeleteObjectVersion` | 删除特定版本(启用版本控制时) | | | `s3:PutObjectAcl` | 修改对象的 ACL | | | `s3:PutObjectTagging` | 设置/修改对象标签 | | | `s3:AbortMultipartUpload` | 终止分片上传 | | **桶管理** | `s3:CreateBucket` | 创建桶 | | | `s3:DeleteBucket` | 删除桶 | | | `s3:PutBucketPolicy` | 设置桶策略 | | | `s3:GetBucketPolicy` | 获取桶策略 | | | `s3:PutBucketVersioning` | 设置版本控制 | | | `s3:PutBucketLifecycle` | 设置生命周期规则 | | **多部分上传** | `s3:ListMultipartUploadParts` | 列出已上传的分片 | | | `s3:UploadPart` | 上传分片 | > **提示**:使用 `s3:*` 可匹配该服务下所有操作。MinIO 还支持一些扩展操作(如 `admin:*`),但通常不写在用户存储策略中。 --- ## 五、实战示例:逐步构建一个桶控制策略 ### 场景:只允许对 `orderbook` 桶进行读写,**不允许删除** ```json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:GetObject", "s3:PutObject" ], "Resource": [ "arn:aws:s3:::orderbook", "arn:aws:s3:::orderbook/*" ] } ] } ``` ### 场景:完全控制 `orderbook` 桶(所有操作) ```json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:*", "Resource": [ "arn:aws:s3:::orderbook", "arn:aws:s3:::orderbook/*" ] } ] } ``` ### 场景:只允许上传到 `uploads/` 前缀,且文件名为 `incoming-*` ```json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::orderbook/uploads/incoming-*" } ] } ``` ### 场景:拒绝删除任何对象(显式 Deny) ```json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:*", "Resource": [ "arn:aws:s3:::orderbook", "arn:aws:s3:::orderbook/*" ] }, { "Effect": "Deny", "Action": [ "s3:DeleteObject", "s3:DeleteObjectVersion" ], "Resource": "arn:aws:s3:::orderbook/*" } ] } ``` ### 场景:限制只能从特定 IP 访问 ```json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::orderbook/*", "Condition": { "IpAddress": { "aws:SourceIp": "10.0.0.0/24" } } } ] } ``` --- ## 六、常见错误与调试 | 错误现象 | 可能原因 | 解决方案 | | :--- | :--- | :--- | | 能列出桶,但无法上传 | 桶对象资源 `/*` 缺失 | 确保 Resource 包含 `arn:aws:s3:::桶名/*` | | 无法列出桶内对象 | 缺少 `s3:ListBucket` 或桶级 Resource | 添加桶本身资源(不带 `/*`) | | 能上传但无法覆盖 | 显式 Deny 或没有完整写入权限 | 检查是否有 `s3:PutObject` | | IP 限制不生效 | Condition 语法错误或键名不对 | 使用 `aws:SourceIp` 且值为 CIDR | | 策略不生效 | 策略未正确附加到用户/组 | 使用 `mc admin policy attach` 检查 | --- ## 七、MinIO 特有提醒 - MinIO 默认禁用 `s3:CreateBucket` 等管理操作,除非你使用 `root` 或拥有管理员策略。 - MinIO 支持 **内置策略**(如 `readonly`、`readwrite`、`consoleAdmin`),可以直接附加。 - 策略 JSON 大小限制通常为 **20KB**(MinIO 默认)。 - 使用 `mc` 命令可以验证策略语法: `mc admin policy create myminio mypolicy ./policy.json` --- 希望这份整理能够帮助你灵活编写策略。如果你有具体的访问控制需求,可以提供描述,我可以直接为你生成策略 JSON。