There are multiple S3 buckets in the aws account. All users are assigned a group policy which gives S3 all access.
But now the requirement is -> there is one S3 bucket which should be limited access to the all users. In this bucket there are folders as per aws user names. A user should only be able to access the objects in the folder having her username. That user should have all permissions in that specific folder and that user should not be able to access the folders having other user's names.
All S3 buckets : bucket1 , bucket2 to bucket10
Specific bucket : bucket3
Objects in the specific bucket : bucket3/report/user={user_name}
ex : bucket3/report/user=user1 ,bucket3/report/user=user2
Requirement :
- user1 have list, put, delete objects inside -> bucket3/report/user=user1
- user1 can not access bucket3/report/user=user2
Following is the policy we have created. This policy is blocking access to all S3 buckets.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowGroupToSeeBucketListInTheConsole",
"Action": [
"s3:ListAllMyBuckets",
"s3:GetBucketLocation"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::*"
]
},
{
"Sid": "AllowRootAndHReportListingOfBucket",
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::bucket3"
],
"Condition": {
"StringEquals": {
"s3:prefix": [
"",
"report/"
],
"s3:delimiter": [
"/"
]
}
}
},
{
"Sid": "DenyListingOfOtherUserFolder",
"Action": [
"s3:*"
],
"Effect": "Deny",
"Resource": [
"arn:aws:s3:::bucket3"
],
"Condition": {
"StringNotLike": {
"s3:prefix": [
"report/user=${aws:username}/*",
"report/user=${aws:username}"
]
}
}
},
]
}
As I'm new to aws I couldn't resolve the issue. How should I update the policy to get the requirement fulfilled?
Thanks in advance
CodePudding user response:
There is no need to use 'Deny'. Instead, use IAM Policy Variables.
From IAM policy elements: Variables and tags - AWS Identity and Access Management:
Consider writing a policy to allow each user to have access to his or her own objects in an Amazon S3 bucket, as in the previous example. But don't create a separate policy for each user that explicitly specifies the user's name as part of the resource. Instead, create a single group policy that works for any user in that group.
You can do this by using policy variables, a feature that lets you specify placeholders in a policy. When the policy is evaluated, the policy variables are replaced with values that come from the context of the request itself.
The following example shows a policy for an Amazon S3 bucket that uses a policy variable.
{
"Version": "2012-10-17",
"Statement": [
{
"Action": ["s3:ListBucket"],
"Effect": "Allow",
"Resource": ["arn:aws:s3:::mybucket"],
"Condition": {"StringLike": {"s3:prefix": ["${aws:username}/*"]}}
},
{
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Effect": "Allow",
"Resource": ["arn:aws:s3:::mybucket/${aws:username}/*"]
}
]
}
CodePudding user response:
Luckily for you the more granular you get in IAM permissions, the more you can deny and denials are implicit, and allows are explicit. Given a general s3 admin rights to every s3 bucket, assuming the IAM policy has something like Resources: [*]
then explicitly denying to the bucket everyone will override the admin right explicitly allow.
However, there are no actual directories in that s3 bucket. What you see as directories in the console are just a representation, but to s3 each object is defined by the full key - all parts of it.
But you Can deny actions to specific resources, with wildcards, and in s3 you can add the key to the resource part of the IAM policy to deny.
So in theory, you could write an IAM policy that Denies everything in a given bucket, then explicitly allows a given user access to their 'directory' as part of a wild card of the resource.
Something pseudo code like this:
{
Actions: Deny s3:*
Resources: [arn:of:your:s3:bucket]
}
{
Actions: Allow s3:*
Principle: [Arn:of:user:account]
Resources: [arn:of:your:s3:bucket/userdirectory/*]
}
please recall the above is pseudocode, and will not work as is ;) - Plus I've not tested it directly. I do however know that, even with s3:* allow action to everything in the account, I have bricked s3 buckets by explicitly denying everyone access to an s3 bucket and forgetting to give any allows :P Took aws root access to fix!
In truth however, this is a hack and you would be better off removing the admin rights to resources: [*] and create individual policies based on who needs what explicitly for each bucket set, making use of groups/policies/roles multi structure to make it easy to provide access to any given user to any given bucket (or more).
Another option is to use the ACL controls of files in s3. One of these controls limits access to any given object in an s3 to the user who uploaded it, preventing all other users from accessing it. (including services) without the ability to modify the ACL of an object. If you really don't want to turn off broad spectrums access off to all s3 buckets, you can implicitly deny ACL modification instead.