我有一个节点应用程序,它以下列方式调用assumeRoleWithWebIdentity:
var params = {
DurationSeconds: 3600,
RoleArn: "arn:aws:iam::role/my_test_role",
RoleSessionName: "session_name",
WebIdentityToken: req.body.id_token
};
sts.assumeRoleWithWebIdentity(params, function(err, data) {
//create s3 client with data.Credentials.SecretAccessKey, AccessKeyId, sessionToken
//call s3.listObjectsV2({Bucket: 'my-bucket'}).
});
不,我在IAM中有一个角色叫my_test_role。附加到该角色的是一个名为my_test_policy的策略,其内容如下:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets",
"s3:GetBucketLocation"
],
"Resource": "arn:aws:s3:::*"
},
{
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::my_bucket",
"Condition": {"StringLike": {"s3:prefix": [
"",
"home/",
"home/BOB/*"
]}}
},
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my_bucket/home/BOB",
"arn:aws:s3:::my_bucket/home/BOB/*"
]
}
]
}
在s3中,我有一个名为my_bucket的存储桶,在该存储桶中是文件夹home。在家里有一堆用户文件夹:
my_bucket/home/ALICE
my_bucket/home/BOB
my_bucket/home/MARY
当我的节点应用程序列出对象时,它会列出home中的所有对象。我的政策的目的是将列表限制为承担该角色的用户。因此,如果BOB承担了这个角色,他应该只看到my_bucket / home / BOB,而不是其他任何东西。我最终将取代硬编码的BOB'在$ {my_oidc_url:sub}的政策中。但在我迈出这一步之前,我想我只会硬编码" BOB"并看看是否有效。它不是。假定的角色可以看到所有文件夹。有什么建议?
答案 0 :(得分:0)
在您的s3:ListBucket
政策中,您已允许列出home/
文件夹,因此当然会列出其中的所有内容。
如果您只有home/BOB/*
目录,那么我认为您会得到所需的行为。
答案 1 :(得分:0)
为了测试这种情况,我做了以下事情:
内容如下:
2018-05-11 08:57:55 10096 foo
2018-05-11 08:57:38 10096 home/alice/foo
2018-05-11 08:57:32 10096 home/bob/foo
2018-05-11 08:57:51 10096 home/foo
2018-05-11 08:57:45 10096 home/mary/foo
权限是:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListObjects",
"Effect": "Allow",
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-bucket",
"Condition": {
"StringLike": {
"s3:prefix": [
"home/bob/*"
]
}
}
},
{
"Sid": "AccessObjects",
"Effect": "Allow",
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-bucket/home/bob/*"
}
]
}
(ListObjects
相当于ListBucket
)
通过CLI命令:
aws sts assume-role --role-arn arn:aws:iam::123456789012:role/bob --role-session-name bob
然后我可以在home/bob
路径中执行任何操作,但在其他路径中没有任何内容:
$ aws --profile bob s3 ls s3://my-bucket/home/bob/
2018-05-11 09:16:23 10096 foo
$ aws --profile bob s3 cp foo s3://my-bucket/home/bob/foo
upload: ./foo to s3://my-bucket/home/bob/foo
$ aws --profile bob s3 cp s3://my-bucket/home/bob/foo .
download: s3://my-bucket/home/bob/foo to ./foo
$ aws --profile bob s3 ls s3://my-bucket/home/
An error occurred (AccessDenied) when calling the ListObjects operation: Access Denied
$ aws --profile bob s3 ls s3://my-bucket/
An error occurred (AccessDenied) when calling the ListObjects operation: Access Denied
政策变量
虽然可以轻松地将IAM用户替换为policy variable,但对于假定角色来说,这似乎并不容易。这是因为变量将设置为:
aws:username
将未定义aws:userid
将设置为role id:caller-specified-role-name
这并不像简单地引用' bob'的值那么容易。您实际上需要将S3路径命名为:AIDAJQABLZS4A3QDU576Q:bob
答案 2 :(得分:0)
好吧,它最终成了一些东西。
以下政策对我有用
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowUserToSeeBucketListInTheConsole",
"Action": [
"s3:ListAllMyBuckets",
"s3:GetBucketLocation"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::*"
},
{
"Sid": "AllowRootAndHomeListingOfCompanyBucket",
"Action": "s3:ListBucket",
"Effect": "Allow",
"Resource": "arn:aws:s3:::my-bucket2"
},
{
"Sid": "DenyAllListingExpectForHomeAndUserFolders",
"Effect": "Deny",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::my-bucket2",
"Condition": {
"Null": {
"s3:prefix": "false"
},
"StringNotLike": {
"s3:prefix": [
"",
"home/",
"home/${MY_OIDC_URL:sub}/*"
]
}
}
},
{
"Sid": "AllowAllS3ActionsInUserFolder",
"Effect": "Allow",
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-bucket2/home/${MY_OIDC_URL:sub}/*"
}
]
}