基于亚马逊前缀的S3策略是';t工作(AWS、IAM、STS、Ruby)

基于亚马逊前缀的S3策略是';t工作(AWS、IAM、STS、Ruby),ruby,amazon-web-services,amazon-s3,amazon-iam,Ruby,Amazon Web Services,Amazon S3,Amazon Iam,我正在构建一个应用程序,它使用Amazon的安全令牌服务创建临时用户来访问S3存储桶上的子目录。用户由具有bucket完全读/写权限(以及创建用户所需的权限)的IAM用户创建 我创建的用户可以很好地处理会话过期等问题,但是我在制定正确的策略以允许基于前缀的密钥列表时遇到了问题。我希望最终用户拥有的权限是: 读取某些已定义前缀中的对象 将对象写入相同的已定义前缀 列出位于已定义前缀中的所有对象 我设法使读写工作正常,但无论如何,列表访问都不能正常工作。下面是我最接近时使用的Ruby代码: AWS:

我正在构建一个应用程序,它使用Amazon的安全令牌服务创建临时用户来访问S3存储桶上的子目录。用户由具有bucket完全读/写权限(以及创建用户所需的权限)的IAM用户创建

我创建的用户可以很好地处理会话过期等问题,但是我在制定正确的策略以允许基于前缀的密钥列表时遇到了问题。我希望最终用户拥有的权限是:

  • 读取某些已定义前缀中的对象
  • 将对象写入相同的已定义前缀
  • 列出位于已定义前缀中的所有对象
  • 我设法使读写工作正常,但无论如何,列表访问都不能正常工作。下面是我最接近时使用的Ruby代码:

    AWS::STS::Policy.new do |policy|
      policy.allow(
        actions: ["s3:GetObject*", "s3:PutObject*", "s3:DeleteObject*"],
        resources: "arn:aws:s3:::#{ENV['PROJECT_BUCKET']}/#{folder_path}/*"
      )
    
      policy.allow(
        actions: ["s3:*"],
        resources: ["arn:aws:s3:::#{ENV['PROJECT_BUCKET']}/*", "arn:aws:s3:::#{ENV['PROJECT_BUCKET']}"]
      ).where(:s3_prefix).like("#{folder_path}/*")
    end
    
    如果我记得的话,这让我可以阅读和写作,但不能列出清单。由于我仍处于开发阶段,我将代码更改为:

    AWS::STS::Policy.new do |policy|
      # FIXME: This is way too permissive, but it's not working to be more specific.
      policy.allow(
        actions: ["s3:*"],
        resources: ["arn:aws:s3:::#{ENV['PROJECT_BUCKET']}/*", "arn:aws:s3:::#{ENV['PROJECT_BUCKET']}"]
      )
    end
    
    这对于一个明显的问题是,没有任何东西被限制在一个前缀上,这将允许用户对彼此的工作进行重击


    我的策略哪里做错了?

    您可能会对本文感兴趣,因为它专门讨论了创建一个策略,将用户限制为S3存储桶中的前缀

    您很可能只需要参考第二个策略

    { 
            "Statement":
            [
                {
                  "Effect":"Allow",
                  "Action":["s3:PutObject","s3:GetObject","s3:DeleteObject"],
                  "Resource":"arn:aws:s3:::__MY_APPS_BUCKET_NAME__/__USERNAME__/*"
                },
                {
                  "Effect":"Allow",
                  "Action":"s3:ListBucket",
                  "Resource":"arn:aws:s3:::__MY_APPS_BUCKET_NAME__",
                  "Condition":{"StringLike":{"s3:prefix":"__USERNAME__/"}}
                },
                {
                  "Effect":"Deny",
                  "Action":["sts:*", "iam:*", "sdb:*"],
                  "Resource":"*"
                }
            ]
    }
    
    前两条陈述是你最感兴趣的

    希望有帮助。

    < p>扩展鲍伯·金尼的(+ 1),我想解释我认为是你的问题的可能原因,这实际上与使用这个问题无关,但涉及到一些通常遇到的微妙之处:

    本书涵盖了与您类似或相关的各种用例——特别是您的用例显然包括示例2:允许组在Amazon S3中拥有共享文件夹——您已经在第一个片段的第一个策略中有效地实现了这一点(模运算
    GetObjectVersion
    DeleteObjectVersion
    ,仅在使用时相关)

    现在缺少的是-请注意以下微妙之处:

    • 这属于,即您可以在存储桶上执行的操作,而例如,属于,即您可以在Amazon S3对象上执行的操作(此外,目前只有一些操作可能不适用于您的用例)
    • prefix
      参数限制对以指定前缀开头的键的响应。您可以使用前缀将bucket分隔为不同的键集,其方式类似于文件系统使用文件夹的方式。这意味着前缀不能包含通配符规范,或者更确切地说,
      *
      只是一个字符串作为名称的一部分,请参见。
      • 这是许多用户最初偶然发现的文件夹/目录模拟的一个方面,因为S3实际上是一个仅由bucket和对象/键组成的平面存储体系结构(有关这方面的更多详细信息,请参阅我的答案)
    因此,像您这样的许多用例需要两个不同的策略片段来分别处理对象和与bucket相关的操作,因此您可能需要以下内容:

    AWS::STS::Policy.new do |policy|
      policy.allow(
        actions: ["s3:GetObject*", "s3:PutObject*", "s3:DeleteObject*"],
        resources: "arn:aws:s3:::#{ENV['PROJECT_BUCKET']}/#{folder_path}/*"
      )
    
      policy.allow(
        actions: ["s3:ListBucket"],
        resources: ["arn:aws:s3:::#{ENV['PROJECT_BUCKET']}"]
      ).where(:s3_prefix).like("#{folder_path}/")
    end