How to deny all actions to a specific folder inside S3 bucket? - amazon-web-services

Basically, this policy is for AWS Transfer Family. I need to deny all access to a specific folder inside the S3 bucket. I tried the below policy, but still I was able to list the contents of the folder. But it was denied for PUT and DELETE operations.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation",
"s3:ListAllMyBuckets"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:ListBucketVersions",
"s3:GetBucketAcl"
],
"Resource": [
"arn:aws:s3:::${bucket_name}"
]
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject",
"s3:GetObjectAcl",
"s3:GetObjectVersionTagging",
"s3:GetObjectVersionAcl",
"s3:GetObjectVersion"
],
"Resource": [
"arn:aws:s3:::${bucket_name}/*"
]
},
{
"Effect": "Deny",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::${bucket_name}/app/restricted",
"arn:aws:s3:::${bucket_name}/app/restricted/*"
]
}
]
}
Expected:
aws s3 ls s3://sample_bucket/app/restricted/data - Access Denied
Behaviour:
aws s3 ls s3://sample_bucket/app/restricted/data - Listing all the contents of the folder

The ListBucket operation (which lists objects within a bucket) is a bucket-level permission, so it ignores the path in the supplied Resource.
Instead, you can specify the path in a Condition parameter.
From Amazon S3 Bucket: Deny List, Read, Write to specific folder - Stack Overflow:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::${bucket_name}",
"Condition": {
"StringLike": {
"s3:prefix": "app/restricted/*"
}
}
}
]
}
This will Deny listing the contents of the bucket when the prefix is app/restricted/*. Add this statement to your existing policy, since it specifically applies to ListBucket. Keep your existing Deny statement since it applies to other operations, such as GetObject and PutObject (which do accept paths in the resource).

Related

AWS Transfer service - SFTP - deny ability to list directory is affecting ability to put file to the directory

I'm attempting to set up permissions for a user account on AWS Transfer Service with SFTP protocol. I have a use case where a user should be able to add a file to a directory but not list the files in it.
When I tweak the IAM role to deny 's3:ListBucket' for a specific subdirectory the put operation fails as well. Theoretically s3 does allow to Put object without having the ability to list the prefixes. AWS transfer service however seems to be implicitly using the list bucket operation before put. Has anyone managed to deny listing ability while still being able to upload.
IAM policy :
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "s3:ListBucket",
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::<my-bucket>"
],
"Sid": "AllowListDirectories",
"Condition": {
"StringLike": {
"s3:prefix": [
"data/partner_2/*"
]
}
}
},
{
"Sid": "DenyMkdir",
"Action": [
"s3:PutObject"
],
"Effect": "Deny",
"Resource": "arn:aws:s3:::<my-bucket>/*/"
},
{
"Sid": "DenyListFilesInSubDirectory",
"Action": [
"s3:ListBucket"
],
"Effect": "Deny",
"Resource": "arn:aws:s3:::<my-bucket>",
"Condition": {
"StringLike": {
"s3:prefix": [
"data/partner_2/data/incoming/*"
]
}
}
},
{
"Effect": "AllowReadWirteInSubDirectory",
"Action": [
"s3:GetObject",
"s3:GetObjectVersion",
"s3:PutObject",
"s3:PutObjectAcl",
"s3:PutObjectTagging",
"s3:PutObjectVersionAcl",
"s3:PutObjectVersionTagging"
],
"Resource": "arn:aws:s3:::<my-bucket>/data/partner_2/data/incoming/*"
},
{
"Effect": "AllowOnlyReadInADifferentDirectory",
"Action": [
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": "arn:aws:s3:::<my-bucket>/data/partner_2/data/outgoing/*"
}
]
}
The output from SFTP client:
sftp> cd data/incoming
sftp> ls
Couldn't read directory: Permission denied
sftp> put /Users/foo/Downloads/test.log
Uploading /Users/foo/Downloads/test.log to /data/incoming/test.log
remote open("/data/incoming/test.log"): Permission denied
sftp> get test-one.txt
Fetching /data/incoming/test-one.txt to test-one.txt
sftp> exit
Since you will have to allow the upload to your s3 bucket through SFTP, this answer doesn't quite meet your requirements. If the SFTP requirement wasn't there, you may be able to provide pre-signed urls to the client to upload files securely.
I couldn't manage to find an exact solution, however, a workaround could be allowing list+upload permission to a directory in your bucket that is specific to the client/user. Got a helpful video here to share, and corresponding medium article.
Basically, the IAM policy the user is attached to will have the following permissions to a specific folder while you block all public access to your bucket.
{
"Version": "2023-02-16",
"Statement": [
{
"Sid": "AllowListingOfUserFolder",
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::<my-bucket>"
],
"Condition": {
"StringLike": {
"s3:prefix": [
"restricted-folder-user-1/*",
"restricted-folder-user-1"
]
}
}
},
{
"Sid": "HomeDirObjectAccess",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": "arn:aws:s3:::<arn of restricted-folder-user-1>*"
}
]
}

S3 policy - user able to list all prefixes and objects

I wanted the to limit the user to upload and list objects in dir1 only but it's able to list all the prefixes of the bucket. It can only upload to dir1 which is desired. How can I modify the policy so that user1 can list and upload objects of dir1 only?
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowListingOfUserFolder",
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::mybucket"
]
},
{
"Sid": "HomeDirObjectAccess",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject"
],
"Resource": "arn:aws:s3:::mybucket/dir1/*"
}
]
}
The ListBucket command (which shows objects in a bucket) takes a Condition like this:
{
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::my-bucket",
"Condition":
"StringLike": {
"s3:prefix": "dir1/*
}
}
This will Allow listing the contents of that bucket, but only if the prefix starts with dir1/.
See also: Use IAM policies to grant access to user-specific folders

AWS set policy to specific S3 bucket folder

I have this policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:ListBucket",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::static.MYURL.com",
"arn:aws:s3:::static.MYURL.com/images/carousel/*"
]
}
]
}
And currently the user under that policy can List all the object inside the static.MYURL.com bucket.
How can I restrict to only see the object under static.MYURL.com/images/carousel/ ?
I just want that the user can list, delete, get and read object inside that folder
Yes, you can check out some helpful links provided by #amitd. Here is a sample policy that will hopefully meet your needs:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::static.MYURL.com",
"arn:aws:s3:::static.MYURL.com/images/carousel/*"
]
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::static.MYURL.com"
],
"Condition": {
"StringLike": {
"s3:prefix": [
"images/carousel/*"
]
}
}
}
]
}
Please refer following documents from AWS;
Grant Access to User-Specific Folders in an Amazon S3 Bucket
OR
How can I grant a user access to a specific folder in my Amazon S3 bucket?
OR
How can I use IAM policies to grant user-specific access to specific folders?
You can use AWS Policy Generator

How to restrict user to view only specific buckets

I have a set of users: user1 and user2. Ideally they should have access to read and write in their own buckets.
I want to give them console access so they can login and upload the data in S3 through drag and drop.
So I want to the ability of one user to view buckets of other users.
I am using the following IAM policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation",
"s3:ListBucketMultipartUploads"
],
"Resource": "arn:aws:s3:::user1_bucket",
"Condition": {}
},
{
"Effect": "Allow",
"Action": [
"s3:AbortMultipartUpload",
"s3:DeleteObject",
"s3:DeleteObjectVersion",
"s3:GetObject",
"s3:GetObjectAcl",
"s3:GetObjectVersion",
"s3:GetObjectVersionAcl",
"s3:PutObject",
"s3:PutObjectAcl",
"s3:PutObjectVersionAcl"
],
"Resource": "arn:aws:s3:::user1_bucket/*",
"Condition": {}
}
]
}
But it does not show any bucket for the user. All the user can see is Access Denied .
I tried to add principal in the policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::9xxxxxxxxxx:user/user1"},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::user1_bucket"
]
}
]
}
This gives an error.
This policy contains the following error: Has prohibited field Principal For more information about the IAM policy grammar, see AWS IAM Policies
What can I do ?
There are two ways you can do this.
Bucket policies: You select who can access and control said bucket, by attaching a policy. Example for your case:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "bucketAccess",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::AWS-account-ID:user/user-name"
},
"Action": [
"s3:GetObject",
"s3:AbortMultipartUpload",
"s3:DeleteObject",
"s3:DeleteObjectVersion",
"s3:GetObjectAcl",
"s3:GetObjectVersion",
"s3:GetObjectVersionAcl",
"s3:PutObject",
"s3:PutObjectAcl",
"s3:PutObjectVersionAcl"
],
"Resource": [
"arn:aws:s3:::examplebucket/*"
]
}
]
}
Source: Bucket Policy Examples - Amazon Simple Storage Service
Or you can give access through role policies, which I think is better. You almost had it, but you messed up at the end. Your policy should look something like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets"
],
"Resource": "arn:aws:s3:::"
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation"
],
"Resource": "arn:aws:s3:::examplebucket"
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:PutObjectAcl",
"s3:GetObject",
"s3:GetObjectAcl",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::examplebucket/"
}
]
}
Source: User Policy Examples - Amazon Simple Storage Service
I hope this helps.
It appears that your requirement is:
Users should be able to use the Amazon S3 management console to access (view, upload, download) their own S3 bucket
They should not be able to view the names of other buckets, nor access those buckets
With listing buckets
The first requirement can be met with a policy like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AccessThisBucket",
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
]
},
{
"Sid": "ListAllBucketForS3Console",
"Effect": "Allow",
"Action": "s3:ListAllMyBuckets",
"Resource": "arn:aws:s3:::*"
}
]
}
This allow them to access their specific bucket, but it also allows them to list all bucket names. This is a requirement of the Amazon S3 management console, since the first thing it does is list all of the buckets.
Without listing buckets
However, since you do not want to give these users the ability to list the names of all buckets, you could use a policy like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
]
}
]
}
This gives them full access to their own bucket, but they cannot list the names of other buckets.
To use this in the management console, they will need to jump directly to their bucket using a URL like this:
https://console.aws.amazon.com/s3/buckets/my-bucket
This will then allow them to access and use their bucket.
They will also be able to use AWS Command-Line Interface (CLI) commands like:
aws s3 ls s3://my-bucket
aws s3 cp foo.txt s3://my-bucket/foo.txt
Bottom line: To use the management console without permission to list all buckets, they will need to use a URL that jumps straight to their bucket.

AWS S3: can't list the bucket after change of policy

We have created a Bucket in AWS S3 and a IAM-User with a specific policy to restrict the access to this bucket as follows:
Bucket: testbucket
Policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:GetObjectAcl",
"s3:GetObjectVersion",
"s3:PutObject",
"s3:PutObjectAcl",
"s3:PutObjectVersionAcl"
],
"Resource": [
"arn:aws:s3:::testbucket/*",
]
}
]
}
Then we've created a IAM-User and assigned this policy to the permissions of the user. We got an Access-Key and a Secret-Access-Key and can successfully upload files to the bucket and also download them with a given, known URL to the resources.
Now we want be able to also List all objects in the bucket.
Therefor i have changed the policy this way:
New Policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:GetObjectAcl",
"s3:GetObjectVersion",
"s3:PutObject",
"s3:PutObjectAcl",
"s3:PutObjectVersionAcl"
],
"Resource": [
"arn:aws:s3:::testbucket/*",
]
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::testbucket/*"
]
}
]
}
The new item here is s3:ListBucket.
I have changed this policy successfully and can reload the page on AWS to ensure that these changes are still existing.
However, i've already waited for a hour but i am still unable to list the objects of the bucket.
For testing i use the app CyberDuck. It can list the bucket itself after authentication but it still can't list the objects in the bucket.
Do i need to do something else?
s3:ListBucket applies to the bucket, not to the objects within it. Therefore, the second statement must not have the trailing slash and wildcard and so should be:
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::testbucket"
]
}