我正在构建一个使用亚马逊安全令牌服务的应用程序来创建临时用户来访问S3存储桶上的子目录。用户由具有对存储桶的完全读/写访问权限的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
这可以100%正常工作,显而易见的问题是,没有任何东西限制在一个允许用户破坏彼此工作的前缀。
我的政策中我做错了什么?
您可能会发现此文章,因为它专门讨论了创建策略以限制用户在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":"*"
}
]
}
前两个陈述是你最感兴趣的。
希望这可以帮助。
扩展Bob Kinney的 引用的文章和片段 (+ 1),我想解释一下我认为你的问题的可能原因,这实际上与使用它无关 AWS安全令牌服务(STS),但涉及经常遇到的一些细微之处 Amazon S3 IAM策略 一般来说:
该 Amazon S3的示例策略 涵盖与您类似或相关的各种用例 - 特别是您的用例显然包括 示例2:允许组在Amazon S3中拥有共享文件夹 - 你已经在第一个片段的第一个策略中有效地实现了它(模数 GetObjectVersion
, DeleteObjectVersion
,仅在使用时相关 对象版本控制)。
现在缺少的是 ListBucket - 请注意以下细微之处:
因此,像您这样的许多用例需要两个不同的策略片段来分别处理对象和存储桶相关的操作,因此您可能需要以下内容:
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