AWS S3 存储桶策略

AWS S3 Bucket policies

我已经使用 cloudformation 创建了一个存储桶:

AWSTemplateFormatVersion: "2010-09-09"
Parameters:
  BucketName:  
    Type: String
    Description: "Choose a name for the S3 Bucket"
    Default: "myrandomnameforbucket"
  S3Bucket:
    Type: "AWS::S3::Bucket"
    Properties:
      AccessControl: "Private"
      BucketName: !Ref BucketName

现在我正在编写 bucketPolicy,但遇到了一些问题。我想达到的目标:

我怎样才能做到这一点? 目前我拒绝从 userA 删除并允许从 userA 上传。

          - Effect: Deny
            Principal:
              AWS: 
                !GetAtt UserA.Arn
            Action: "s3:DeleteObject"
            Resource: 
              Fn::Join:  ["", ["arn:aws:s3:::", Ref: "S3Bucket", "/*"]]
          - Effect: Allow
            Principal:
              AWS: 
                !GetAtt UserA.Arn
            Action: "s3:PutObject"
            Resource: 
              Fn::Join:  ["", ["arn:aws:s3:::", Ref: "S3Bucket", "/*"]]
          - Effect: Allow
            Principal: "?" # * is public?
            Action: s3:GetObject
            Resource: 
              Fn::Join:  ["", ["arn:aws:s3:::", Ref: "S3Bucket", "/*"]]
  {
"Version": "2012-10-17",
"Id": "S3PolicyId1",
"Statement": [
    {
        "Sid": "AllowGet",
        "Effect": "Allow",
        "Principal":{"AWS":"arn:aws:iam::account-number-without-hyphens:user/user1"},
        "Action": [
            "s3:Get*",
            "s3:List*"
        ],
        "Resource": [
            "arn:aws:s3:::s3_bucket_name",
            "arn:aws:s3:::s3_bucket_name/*"
        ]
    },
    {
        "Sid": "DenyDeleteObject",
        "Effect": "Deny",
        "Principal": {"AWS":"arn:aws:iam::account-number-without-hyphens:user/user1"},
        "Action": "s3:Delete*",
        "Resource": [
            "arn:aws:s3:::s3_bucket_name",
            "arn:aws:s3:::s3_bucket_name/*"
        ]
    },
    {
        "Sid": "Allow anyone in your account to access bucket",
        "Effect": "Allow",
        "Principal": {
            "AWS": "arn:aws:iam::account-number-without-hyphens:root"
        },
        "Action": [
            "s3:Get*",
            "s3:List*",
            "s3:Put*",
            "s3:Delete*"
        ],
        "Resource": [
            "arn:aws:s3:::s3_bucket_name",
            "arn:aws:s3:::s3_bucket_name/*"
        ]
    }
]

}

这是我快速整理的 JSON 格式的模板。我在这里的假设是您的组 "ALL users (in my environment, nob public)" 是帐户中的每个人。因此,我们在第三块中定义它。你可以随心所欲地操纵本金。

如果您有任何问题,请提出,我很乐意提供帮助。

我理解有两个问题:

  1. 如何在排除匿名用户时向所有 IAM 用户授予访问权限
  2. 如何限制一个用户比其他用户更多,即:删除您刚刚授予他人的权限

第一个问题一开始听起来很简单,因为the documentation states:

In resource-based policies, use the Principal element to specify the accounts or users who are allowed to access the resource

所以这意味着您可以执行以下操作:

Principal:
    AWS: !Ref "AWS::AccountId"

但是当我尝试时,它就是行不通。在设置特定用户的 arn 时,它对我有用。这对我来说似乎是一个错误。或文档中的不明确之处。有this other report I found.

无论如何,你能做的就是使用Principal: AWS: "*",然后使用Conditionrestrict to IAM users only

第二个问题要简单得多:评估政策时,显式 deny 优先于一般 allowsee documentation.

生成的策略可以是例如写成这样:

S3Policy:
  Type: "AWS::S3::BucketPolicy"
  Properties:
    Bucket: !Ref S3Bucket
    PolicyDocument:
      Statement:
        - Effect: Deny
          Action: "s3:DeleteObject"
          Resource: !Join ["", ["arn:aws:s3:::", Ref: "S3Bucket", "/*"]]
          Principal:
            AWS: !GetAtt UserA.Arn
        - Effect: Allow
          Action: "s3:PutObject"
          Resource: !Join ["", ["arn:aws:s3:::", Ref: "S3Bucket", "/*"]]
          Principal:
            AWS: !GetAtt UserA.Arn
        - Effect: Allow
          Action: ["s3:GetObject", "s3:DeleteObject"]
          Resource: !Join ["", ["arn:aws:s3:::", Ref: "S3Bucket", "/*"]]
          Principal:
            AWS: "*"
          Condition:
            StringEquals:
              "aws:PrincipalType": ["User"]