Granting full control permission on all sub-folders inside S3 bucket (excluding parent ) - amazon-web-services

I have an S3 bucket called my-bucket... I have several sub-folders inside this bucket, let's call them: sub-folder1, sub-folder2, etc
I want my-bucket-user to have read permission to the bucket and full control permission to all of the sub-folders (so this user cannot write at the root level).
I have tried the following bucket policy, which specifically grants permission on each of the sub folders... but this policy would become too long if I have a lot of sub-folders.
{
"Id": "MyBucketPolicy",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListPermissionOnMyBucket",
"Action": [
"s3:GetBucketLocation",
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::my-bucket/*",
"Principal": {
"AWS": [
"arn:aws:iam::773643377756:user/my-bucket-user"
]
}
},
{
"Sid": "FullControlAccessOnSubFolder1",
"Action": "s3:*",
"Effect": "Allow",
"Resource": "arn:aws:s3:::my-bucket/sub-folder1/*",
"Principal": {
"AWS": [
"arn:aws:iam::773643377756:user/my-bucket-user"
]
}
},
{
"Sid": "FullControlAccessOnSubFolder2",
"Action": "s3:*",
"Effect": "Allow",
"Resource": "arn:aws:s3:::my-bucket/sub-folder2/*",
"Principal": {
"AWS": [
"arn:aws:iam::773643377756:user/my-bucket-user"
]
}
}
]
}
Is there a better way of writing this policy?

This policy permits listing the entire contents of the bucket, but only uploading/downloading to a sub-folder (not the root of the bucket):
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "s3:ListBucket",
"Effect": "Allow",
"Resource": "arn:aws:s3:::my-bucket"
},
{
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::my-bucket/*/*"
}
]
}
Basically, the expression my-bucket/*/* forces the requirement of a / in the Key of the object, meaning it is in a sub-folder.

Related

AWS S3 policy limitation to regex path

I would like to create an AWS policy to limit the s3:PutObject access on a path in a bucket.
Easy would you say, but:
I need to set the path with a regex MyBucket/*/Folder1/Folder1-1/Object
It's a cross-account access
I try to do this but it's not working.
On Source Account User policy
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation"
],
"Resource": [
"arn:aws:s3:::MyBucket",
]
},
{
"Sid": "",
"Effect": "Allow",
"Action": [
"s3:GetObjectVersion",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::MyBucket/*",
]
},
{
"Sid": "",
"Effect": "Allow",
"Action": "s3:PutObject",
"Resource": [
"arn:aws:s3:::MyBucket/*",
],
"Condition": {
"StringLike": {
"s3:prefix": "/*/Folder1/Folder1-1/*"
}
}
}
]
}
On Destination Account bucket policy
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::MyAccountID:user/MyUser"
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::MyBucket",
"Condition": {
"StringLike": {
"s3:prefix": "*/Folder1/Folder1-1/*"
}
}
},
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::MyAccountID:user/MyUser"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::MyBucket/*/Folder1/Folder1-1/*"
}
]
}
To clarify my Bucket structure :
|MyBucket
|-Client1
|-|-Folder1
|-|-|-Folder1-1
|-|-|-|-Object
|-Client1
|-|-Folder1
|-|-|-Folder1-1
|-|-|-|-Object
|-ClientXX
|-|-Folder1
|-|-|-Folder1-1
|-|-|-|-Object
I would like my user get PutObject access only not the path Client*/Folder1/Folder1-1/ could you please help me?
Wildcards are not supported in the middle of a string. However, you could use an IAM policy variable:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": ["s3:ListBucket"],
"Effect": "Allow",
"Resource": ["arn:aws:s3:::mybucket"],
"Condition": {"StringLike": {"s3:prefix": ["${aws:username}/Folder1/Folder1-1/*"]}}
},
{
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Effect": "Allow",
"Resource": ["arn:aws:s3:::mybucket/${aws:username}/Folder1/Folder1-1/*"]
}
]
}
The ${aws:username} variable will insert the username of the user. This way, the wildcard is at the end of the string, which is valid.
This is a common way to allow multiple IAM Users to access the same bucket, but each only receives access to their folder within the bucket. This policy could be created on an IAM Group, and the IAM Group could then be assigned to each IAM User without the need to modify it for their particular folder.

AWS S3 Allows reading of all objects except a specific folder

How can I allow reading of all objects except a single folder and its contents?
The rule below blocks me the whole bucket.. (can't read the bucket)
If this feature isn't possible, how can I allow reading on files at the root but deny on all subfolders?
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListBucket",
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::my-bucket"
},
{
"Sid": "ReadOnly",
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket/*"
},
{
"Sid": "DenyOneFolder",
"Effect": "Deny",
"Action": "s3:GetObject",
"Resource": [
"arn:aws:s3:::my-bucket/my-folder",
"arn:aws:s3:::my-bucket/my-folder/*"
]
}
]
}
My bucket strcture:
my-bucket
my-folder
object3
object1
object2
You can add an explicit Deny in your bucket policy for Listing objects that matches the prefix my-folder.
Edit: This policy will work only if the list bucket request contains the prefix.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListBucket",
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::my-bucket"
},
{
"Sid": "ReadOnly",
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket/*"
},
{
"Sid": "DenyOneFolderRead",
"Effect": "Deny",
"Action": "s3:GetObject",
"Resource": [
"arn:aws:s3:::my-bucket/my-folder/*"
]
},
{
"Sid": "DenyOneFolderList",
"Effect": "Deny",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::my-bucket",
"Condition" : {
"StringEquals" : {
"s3:prefix": "my-folder"
}
}
}
]
}
The policy works correctly, though I would remove the Deny on arn:aws:s3:::my-bucket/my-folder because it's not useful.
I think the confusion here is that you are expecting this policy to prevent the IAM user listing and/or getting the objects under s3://my-bucket/my-folder/. It won't do that, specifically the listing part, and in fact you cannot do that. You can't control a user's ability to list the bucket at a granular level (e.g. below a specific prefix).
The policy will successfully prevent the user getting (as in downloading) objects under s3://my-bucket/my-folder/.

how to write a IAM policy to give full s3 access but one directory

I am trying to give all permissions on a single s3 bucket but a single folder. I am trying to use explicit deny the folder name being Beijing path is like
buck123-test/china/Beijing/. bucket name is buck123-test.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1561641021576",
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::buck123-test"
},
{
"Sid": "Stmt1561639869054",
"Action": "s3:*",
"Effect": "Deny",
"Resource": "arn:aws:s3:::buck123-test/china/Beijing"
}
]
}
how can i achieve my requirement as the above policy is not working
Your policy is missing Allow actions for objects in your bucket.
What about ? (not tested myself, let's report if this works)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1561641021576",
"Action": [
"s3:*"
],
"Effect": "Allow",
"Resource": ["arn:aws:s3:::buck123-test", "arn:aws:s3:::buck123-test/*"]
},
{
"Sid": "Stmt1561639869054",
"Action": "s3:*",
"Effect": "Deny",
"Resource": "arn:aws:s3:::buck123-test/china/Beijing/*"
}
]
}
Note that you need the two resources. The bucket name only resource is required for ListBucket and other bucket level operations. The /* resource is required for object level operations like Put and Get
Revised answer, you were missing some critical pieces to the policy document, try this as it should work, but I have not tested this.
You can add additional actions if you want to allow users to GetObject, PutObject etc.
{
"Id": "Policy1561648158487",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1561648106618",
"Action": "s3:*",
"Effect": "Deny",
"Resource": "arn:aws:s3:::buck123-test/china/Beijing/*",
"Principal": "*"
},
{
"Sid": "Stmt1561648156125",
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::buck123-test/*",
"Principal": "*"
}
]
}

S3 Policy for GetObject+PutObject in subfolders

I have a folder structure in an s3 bucket (my-bucket) like this:
/folder1/
/folder2/subfolder/
/folder3/subfolder/subsubfolder/
file.ext
file2.ext
etc...
I want to be able to list, put and get all folders and objects in the root of the bucket and any subfolder (and subfolder of subfolder).
Here is my current policy for the user group that needs these permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": [
"arn:aws:s3:::my-bucket"
]
},
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": [
"arn:aws:s3:::my-bucket/*"
]
},
{
"Effect": "Allow",
"Action": "s3:PutObject",
"Resource": [
"arn:aws:s3:::my-bucket/*"
]
},
{
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets",
"s3:List*"
],
"Resource": "arn:aws:s3:::*"
}
]
}
Using this policy I can only get and put objects in the root of the bucket. But I also want to get and put objects into the folders within the bucket. These folder names are dynamic so I cannot have them in the policy. How do I do this? I know with S3 full access policy it work but not with my example on above. I just keep on getting Access Denied error when trying this.
Any help would be appreciated.
The full policy would look something like this. This works from AWS S3 console.
Notice, that I didn't add s3:DeleteObject. If you need that as well don't forget to add it besides s3:PutObject and s3:GetObject.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::my-bucket"
},
{
"Effect": "Allow",
"Action": "s3:ListAllMyBuckets",
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject"
],
"Resource": "arn:aws:s3:::my-bucket/*"
}
]
}

How I can upload files to Amazon S3 without listing bucket

I am uploading files to S3 using Angular front-end with S3 Bucket policy as:
{
"Id": "Policy1499245520254",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1499245493674",
"Action": [
"s3:*"
],
"Effect": "Allow",
"Resource": ["arn:aws:s3:::test-dev/*",
"arn:aws:s3:::test-dev"],
"Principal": "*"
}
]
}
But if I change the above policy to
{
"Id": "Policy1499245520254",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1499245493674",
"Action": [
"s3:*"
],
"Effect": "Allow",
"Resource": ["arn:aws:s3:::test-dev/*",
"arn:aws:s3:::test-dev"],
"Principal": "*"
},
{
"Sid": "Stmt1499245517941",
"Action": [
"s3:ListBucket"
],
"Effect": "Deny",
"Resource": "arn:aws:s3:::test-dev",
"Principal": "*"
}
]
}
Where I added:
{
"Sid": "Stmt1499245517944",
"Action": [
"s3:ListBucket"
],
"Effect": "Deny",
"Resource": "arn:aws:s3:::test-dev",
"Principal": "*"
}
adding bucket list deny, the upload fails. Any way how I can upload files without listing bucket.
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:GetObjectACL",
"s3:PutObject",
"s3:PutObjectAcl",
"s3:PutObjectTagging",
"s3:PutObjectVersionAcl",
"s3:PutObjectVersionTagging"
],
"Resource": [
"arn:aws:s3:::test-dev",
"arn:aws:s3:::test-dev/*"
]
}
]
}
I solved it by just allowing these permissions, apparently bucket list is not needed in this and solves the problem.
That's because the s3:ListBucket actions covers the GET Bucket (List Objects) and HEAD Bucket operations. The HEAD Bucket operation determines if the bucket exists and you have permission to access it, which seems to be called before any action on objects (such as the s3:PutObject action). See Specifying Permissions in a Policy.