AWS S3 Allows reading of all objects except a specific folder - amazon-web-services

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/.

Related

IAM Policy for AWS File Transfer

I am trying to setup IAM policy on S3 based for aws file transfer (SFTP) protocol. Here is the requirement:
User should be able to put files to his/her own folder is. {transfer:username}/
While uploading, lambda will add tag "allowdownload":"no" by default.
We have some third party integration to carry approvals and once approved, new tag will be added to file "allowdownload":"Yes"
Business logic complete Step_1 through 3 are working except tag based policy which I have attached to AWS File Transfer server. Policy has conditions to allow/deny get files based on tag value but it seems not working.
As per requirement: files with tag "allowdownload":"Yes" should be allowed
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::mybucket"
],
"Effect": "Allow",
"Sid": "ReadWriteS3"
},
{
"Action": [
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::mybucket/${transfer:UserName}/*"
],
"Effect": "Allow",
"Sid": ""
},
{
"Sid": "DenyMkdir",
"Action": [
"s3:PutObject"
],
"Effect": "Deny",
"Resource": "arn:aws:s3:::mybucket/*/"
}
]
}
Here is bucket Policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::mybucket/${transfer:UserName}/*",
"Condition": {
"StringEquals": {
"s3:ExistingObjectTag/allowdownload": "yes"
}
}
},
{
"Sid": "Statement1",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::mybucket/${transfer:UserName}/*",
"Condition": {
"StringEquals": {
"s3:ExistingObjectTag/allowdownload": "no"
}
}
}
]
}
Also, I have block all public access is ON but still user is able to get files with allowdownload tag = no.
Anything wrong with below policy: Please advise.

How can we allow iam user to only upload object and deny him to delete and list objects?

I wanna create a S3 bucket that anyone can get object but only iam user can upload an object.
My bucket policy is like this.
Anyone can read objects, but cannot do delete, list, create action.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicRead",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "*"
}
]
}
I attached the below policy for a permission to upload object to a user and the group.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1347416638923",
"Effect": "Allow",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::my_bucket/*" //fixed as #Marcin mentioned
}
]
}
The problem is that this user can list objects, delete object from javascript.
How can we allow this user to only upload object?
We use Wasabi storage by the way.
arn:aws:s3:::my_bucket is a bucket, not objects. Thus it should be:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1347416638923",
"Effect": "Allow",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::my_bucket/*"
},
{
"Sid": "ExplityDeny",
"Effect": "Deny",
"Action": "s3:DeleteObject",
"Resource": "arn:aws:s3:::my_bucket/*"
},
{
"Sid": "ExplityDeny2",
"Effect": "Deny",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::my_bucket"
}
]
}

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

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.

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": "*"
}
]
}

Creating a S3 policy to allow full access to one S3 subfolder

I am trying to create a AWS S3 policy to allow full access to a specific S3 subfolder but nothing else. In the example below there is a dev named Bob. I created a directory dedicated entirely to Bob and want to give him full read/write access to this S3 folder only (the bob folder) by logging in to the console.
This is what I tried, although when attempting to access the bob directory I am getting an access denied error. I appreciate any suggestions on how to accomplish this.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:ListAllMyBuckets",
"Resource": "arn:aws:s3:::*"
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::/mydir/devs/bob/*"
]
}
]
}
This is what I have for exactly the same need. Some of the combinations seem counterintuitive (why do I need both ListAllBuckets and ListBucket - but it seems to not work without it):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation",
"s3:ListAllMyBuckets"
],
"Resource": [
"arn:aws:s3:::*"
]
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::mydir"
]
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::mydir/devs/bob/*"
]
}
]
}
Also, I think ListBucket requires a bucket (that is, mydir in your example). I don't think it works with the key (or folder), like mydir/devs/bob
Remember S3 objects are the full key name, so you have given permissions to:
/mydir/devs/bob/*
Which represents all keys prefixed with /mydir/devs/bob/, but wouldn't include the key /mydir/devs/bob itself, which is your "folder". It's also missing a bucket name (bucket-name/mydir/devs/bob/*) This means the user can't use a list action on the "folder" or it's parent folders. So, Bob can't navigate to his folder.
There is a great walkthrough on creating user specific subfolders available on the AWS Blog, here. We can break that info down to fit your use case, the statement ids would look like this:
Allow Bob the needed permissions to see the bucket list in the console:
{
"Sid": "AllowUserToSeeBucketListInTheConsole",
"Action": ["s3:ListAllMyBuckets", "s3:GetBucketLocation"],
"Effect": "Allow",
"Resource": ["arn:aws:s3:::*"]
}
Allow Bob to navigate to his folder by allowing listing on each parent directory
{
"Sid": "AllowRootAndHomeListingOfCompanyBucket",
"Action": ["s3:ListBucket"],
"Effect": "Allow",
"Resource": ["arn:aws:s3:::bucket-name"],
"Condition":{"StringEquals":{"s3:prefix":["","mydir/","mydir/devs/","mydir/devs/bob"],"s3:delimiter":["/"]}}
}
Let Bob list any files and folders inside his folder
{
"Sid": "AllowListingOfUserFolder",
"Action": ["s3:ListBucket"],
"Effect": "Allow",
"Resource": ["arn:aws:s3:::bucket-name"],
"Condition":{"StringLike":{"s3:prefix":["mydir/devs/bob/*"]}}
}
Finally, let Bob take any actions on anything inside his folder
{
"Sid": "AllowAllS3ActionsInUserFolder",
"Action":["s3:*"],
"Effect":"Allow",
"Resource": ["arn:aws:s3:::bucket-name/mydir/devs/bob/*"]
}
This combines to look like this:
{
"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:::bucket-name"],
"Condition":{"StringEquals":{"s3:prefix":["","mydir/","mydir/devs/","mydir/devs/bob"],"s3:delimiter":["/"]}}
},
{
"Sid": "AllowListingOfUserFolder",
"Action": ["s3:ListBucket"],
"Effect": "Allow",
"Resource": ["arn:aws:s3:::bucket-name"],
"Condition":{"StringLike":{"s3:prefix":["mydir/devs/bob/*"]}}
},
{
"Sid": "AllowAllS3ActionsInUserFolder",
"Action":["s3:*"],
"Effect":"Allow",
"Resource": ["arn:aws:s3:::bucket-name/mydir/devs/bob/*"]
}
]
}
The provided documentation also gives a great example on doing this by using the ${aws:username} variable inside the policy so this can be applied to groups.