Grant access to read a subdirectory within an Amazon S3 bucket - amazon-web-services

I've never used AWS S3 before. We use it to automatically backup call recordings for clients. One of our clients for audit purposes needs access to their recordings.
I am using the client CyberDuck as a way to access the files.
I want to give them access to only their files.
Our file structure is as follows:
recordings/12345/COMPANYNAMEHERE/
I just learned that you build and do things based on scripts and policies. So I did some research and tried to build one but I get an access denied on listing.
Just curious if I am going about this correctly.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:ListAllMyBuckets",
"Resource": "arn:aws:s3:::*"
},
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::recordings/12345/COMPANYNAMEHERE",
"arn:aws:s3:::recordings/12345/COMPANYNAMEHERE/*"
]
}
]
}

You have only given them permission to ListAllMyBuckets, which means they can only list the names of your buckets, and can't do anything else.
If you have already created an IAM User for them, then giving them this policy would allow them to list and retrieve their files, but only from the given directory (or, more accurately, with the given prefix):
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::my-bucket"
],
"Condition": {
"StringLike": {
"s3:prefix": [
"recordings/123/*"
]
}
}
},
{
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::my-bucket/recordings/123/*"
]
}
]
}
If you do this a lot with customers, then you can use IAM Policy Variables to create a rule that substitutes their username:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::my-bucket"
],
"Condition": {
"StringLike": {
"s3:prefix": [
"recordings/${aws:username}/*"
]
}
}
},
{
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::my-bucket/recordings/${aws:username}/*"
]
}
]
}

Related

AWS IAM Policy to Deny all buckets except one

I'm trying to create a IAM policy to give read-only permissions on a specific bucket:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::mybucket"
]
},
{
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::mybucket/*"
]
}
]
}
The problem is that I have some buckets which are public, so I want to deny every permission on those buckets, I tried to write something like the following in the policy but doesn't work. My idea is to deny everything outside my specific bucket.
{
"Effect": "Deny",
"Action": "*",
"Resource": "*",
"Condition": {
"StringNotLike": {
"s3:prefix": [
"mybucket",
"mybucket/",
"mybucket/*"
]
}
}
},
I solved myself with a different approach, since s3:prefix applies only to a subset of actions, this approach won't fit my use case.
Instead I can use NotResource
{
"Effect": "Deny",
"Action": "*",
"NotResource": [
"arn:aws:s3:::mybucket",
"arn:aws:s3:::mybucket/*"
]
}

AWS S3 Policy, Allow all resources and deny some

why this policy is not working? it allows all command on all resources but not deny on the selected folders! how can i resolve this kind of problem?
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Deny",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::agdstorage/Storage_WK/Agedi Monaco/Banca",
"arn:aws:s3:::agdstorage/Storage_WK/Agedi Monaco/Bilanci",
"arn:aws:s3:::agdstorage/Storage_WK/Agedi Monaco/Bilanci/*",
"arn:aws:s3:::agdstorage/Storage_WK/Agedi Monaco/Contenziosi",
"arn:aws:s3:::agdstorage/Storage_WK/Agedi Monaco/Contenziosi/*",
"arn:aws:s3:::agdstorage/Storage_WK/Agedi France/Affari societari",
"arn:aws:s3:::agdstorage/Storage_WK/Agedi France/Affari societari/*",
]
},
{
"Sid": "Stmt1595519755000",
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::agdstorage/*",
"arn:aws:s3:::agdstorage"
]
}
]
}
Here is an example of using Deny. (I did not test this!)
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::agdstorage"
],
"Condition": {
"StringNotLike": {
"s3:prefix": [
"Storage_WK/Agedi Monaco/Banca/*",
"Storage_WK/Agedi Monaco/Bilanci/*",
"Storage_WK/Agedi Monaco/Contenziosi/*",
"Storage_WK/Agedi France/Affari societari/*"
]
}
}
},
{
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::agdstorage/*"
]
},
{
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Effect": "Deny",
"Resource": [
"arn:aws:s3:::agdstorage/Storage_WK/Agedi Monaco/Banca/*",
"arn:aws:s3:::agdstorage/Storage_WK/Agedi Monaco/Bilanci/*",
"arn:aws:s3:::agdstorage/Storage_WK/Agedi Monaco/Contenziosi/*",
"arn:aws:s3:::agdstorage/Storage_WK/Agedi France/Affari societari/*"
]
}
]
}
Note that ListBucket is controlled via the Prefix, so it is simply using StringNotLike.
For GetObject and PutObject, it is using the resources you listed.
The ListBucket command operates at the bucket-level, not at the object-level.
Here is an example of a policy that grants access only to a specific folder:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": ["s3:ListBucket"],
"Effect": "Allow",
"Resource": ["arn:aws:s3:::mybucket"],
"Condition": {"StringLike": {"s3:prefix": ["David/*"]}}
},
{
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Effect": "Allow",
"Resource": ["arn:aws:s3:::mybucket/David/*"]
}
]
}
Note that ListBucket references the Bucket, but limits access by specifying a Prefix.
This is different to GetObject and PutObject that can be limited by providing a path in Resource.
To know how each command operates, consult Actions, Resources, and Condition Keys for Amazon S3 - AWS Identity and Access Management and refer to the Resource Types column.
If possible, try to avoid using Deny since negative logic can sometimes be less obvious (just like this sentence). It is better to only grant the desired permissions, rather than granting everything and then denying some permissions. For example, the policy shown in your question actually grants permission to delete objects outside of the specified folders (eg at the root level) and to even delete the bucket itself (if it is empty).
If you are simply wanting to grant users access to their own folder, you can use IAM Policy Elements: Variables and Tags:
{
"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}/*"]
}
]
}
This automatically adjusts the policy based upon the username of the user, so they can access folders based on their username.

AWS IAM Users, Groups & Policies

I have only 1 bucket called "partners" & then I am creating folders under it for each of our partners. Then I create an IAM user for each partner and the goal is to give them access to their individual folder. So, if I have two partners/users called Alice & Bob, I want to give each of them access to their individual folders called Alice & Bob under the "partners" bucket. The goal is not to give S3 Console access, just programmatically they should be able to read/write/modify their content in those folders.
So, I was thinking of simply creating "inline policy" for each IAM user to restrict them to their folder. Is this the correct way or are there other alternatives? Here is my current "inline policy" for IAM user Alice.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowListBucketIfSpecificPrefixIsIncludedInRequest",
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::partners"
],
"Condition": {
"StringLike": {
"s3:prefix": [
"alice/*"
]
}
}
},
{
"Sid": "AllowUserToReadWriteObjectDataInProperFolder",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::partners/alice/*"
]
},
{
"Sid": "ExplicitlyDenyAnyRequestsForAllOtherFolders",
"Action": [
"s3:ListBucket"
],
"Effect": "Deny",
"Resource": [
"arn:aws:s3:::partners"
],
"Condition": {
"StringNotLike": {
"s3:prefix": [
"alice/*",
""
]
},
"Null": {
"s3:prefix": false
}
}
}
]
}

Restrict access to a single folder in S3 bucket

I want to restrict the access to a single folder in S3 bucket.
I have written a IAM role for the same. Somehow I am not upload/sync the files to this folder. Here, bucket is the bucket name and folder is the folder where I want to give access.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowUserToSeeBucketListInTheConsole",
"Action": [
"s3:ListAllMyBuckets",
"s3:GetBucketLocation"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::*"
]
},
{
"Sid": "AllowRootAndHomeListingOfBucket",
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::bucket"
],
"Condition": {
"StringEquals": {
"s3:prefix": [
""
],
"s3:delimiter": [
"/"
]
}
}
},
{
"Sid": "AllowListingOfUserFolder",
"Action": [
"s3:ListBucket",
"s3:PutObject",
"s3:PutObjectAcl",
"s3:GetObject",
"s3:GetObjectAcl",
"s3:HeadObject"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::bucket"
],
"Condition": {
"StringLike": {
"s3:prefix": [
"folder/*"
]
}
}
}
]
}
Please suggest where I am wrong.
This restrictive IAM policy grants only list and upload access to a particular prefix in a particular bucket. It also intends to allow multipart uploads.
References:
https://docs.aws.amazon.com/AmazonS3/latest/API/API_Operations.html
https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListBucket",
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::mybucket",
"Condition": {
"StringLike": {
"s3:prefix": "my/prefix/is/this/*"
}
}
},
{
"Sid": "UploadObject",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:AbortMultipartUpload",
"s3:ListMultipartUploadParts"
],
"Resource": [
"arn:aws:s3:::mybucket/my/prefix/is/this/*",
]
}
]
}
Note that specifying the s3:ListBucket resource compactly as "arn:aws:s3:::mybucket/my/prefix/is/this/*" didn't work.
Since you have requested to suggest, where you are wrong:
1> In AllowListingOfUserFolder, you have used the object as resource but you have used bucket level operations and "s3:prefix" will not work with object level APIs.
Please refer to the sample policies listed here:
http://docs.aws.amazon.com/AmazonS3/latest/dev/example-policies-s3.html#iam-policy-ex1
https://aws.amazon.com/blogs/security/writing-iam-policies-grant-access-to-user-specific-folders-in-an-amazon-s3-bucket/
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListObjectsInBucket",
"Effect": "Allow",
"Action": ["s3:ListBucket"],
"Resource": ["arn:aws:s3:::bucket-name"]
},
{
"Sid": "AllObjectActions",
"Effect": "Allow",
"Action": "s3:*Object",
"Resource": ["arn:aws:s3:::bucket-name/*"]
}
]
}
https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_s3_rw-bucket.html
I believe for the scenario you're describing AWS recommends Bucket Policies. AWS IAM should be used to secure AWS resources such as S3 itself, whereas Bucket policies can be used to secure S3 buckets and documents.
Check out this AWS blog post on the subject:
https://aws.amazon.com/blogs/security/iam-policies-and-bucket-policies-and-acls-oh-my-controlling-access-to-s3-resources/

IAM AWS S3 to restrict to a specific sub-folder

I'm using AWS S3 component to store files.
I have a bucket called "mybucket" and with the following folders :
+---Mybucket
\---toto1
\---toto2
+---toto3
| \--- subfolder
| \---subsubfolder
\---toto4
I have AWS console users that need only need to access "toto3" folder.
I tried to restrict the access to this folder, but the user must have the right to list the root of bucket. If I put additional rights to acces the root folder, users can browser "toto1" and "toto2" folders and I don't want.
I want to configure something like that:
Authorize to list all buckets of my S3 account (listAllBuckets policy)
Autorize to list the root of the bucket (it's OK for me if the user see the directories names)
Deny access for all prefix bucket different from "toto3"
Autorize every actions for the user in toto3 folder
I don't want to write an inclusive rules
I tried this IAM policy without any success :
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:PutObject",
"s3:GetObject"
],
"Resource": ["arn:aws:s3:::mybucket/toto3/*"]
},
{
"Sid": "Stmt1457617383000",
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation",
"s3:ListBucket"
],
"Resource": ["arn:aws:s3:::mybucket"]
},
{
"Sid": "Stmt1457617230000",
"Effect": "Deny",
"Action": ["s3:*"],
"Condition": {
"StringNotLike": {
"s3:prefix": "toto3*"
}
},
"Resource": [
"arn:aws:s3:::mybucket/*"
]
},
{
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets"
],
"Resource": [
"*"
]
}
]
}
Here's a policy that will work for you:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::mybucket/toto3/*"
]
},
{
"Sid": "Stmt1457617230000",
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Condition": {
"StringLike": {
"s3:prefix": [
"",
"toto3/"
]
}
},
"Resource": [
"arn:aws:s3:::mybucket*"
]
}
]
}
Details:
ListAllMyBuckets is required by the Console. It shows a list of all buckets.
Any action permitted within the toto3/ path.
ListBucket (retrieve objects list) permitted in the root of the bucket and in the toto3/ path.
I successfully tested this solution.
AWS Documentation Reference: Allow Users to Access a Personal "Home Directory" in Amazon S3
I edit your code to have the following and it works ! THanks !!
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::mybucket/toto3/*"
]
},
{
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets",
"s3:GetBucketLocation"
],
"Resource": "arn:aws:s3:::*"
},
{
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::mybucket",
"Condition": {
"StringLike": {
"s3:prefix": [
"",
"toto3/",
"toto3*"
]
}
}
}
]
}
I need to grant an external vendor access only to a subfolder under a folder, that was under a bucket (!!!). Something like this:
bucket/folder/subfolder
Here's how I accomplished it:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:ListBucket",
"s3:DeleteObject",
"s3:GetBucketLocation"
],
"Resource": [
"arn:aws:s3:::bucket/*",
"arn:aws:s3:::bucket"
]
"Condition": {
"StringLike": {
"s3:prefix": [
"bucket/folder/subfolder/*",
"bucket/folder/subfolder/",
"bucket/folder/subfolder",
"folder/subfolder/*",
"folder/subfolder/",
"folder/subfolder",
]
}
}
}
]
}
Is it possible to limit the below rule but give specific folder access? I don't want the user see the directory names/folder names with-in the specific bucket.
Autorize to list the root of the bucket (it's OK for me if the user see the directories names)