Reputation: 339
I am attempting to allow multiple users access to a single S3 bucket. However they should only have access to a particular directory in that bucket.
Imagine the following
my-bucket
- client-1
- important-doc.txt
- client-2
- somefile.jpg
- my-own-file.js
With that in mind (allowing say, client-1 access to only that directory) I have the following policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::my-bucket"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": "arn:aws:s3:::my-bucket/client-1/*"
}
]
}
This works as you would expect, client-1
can connect to the bucket, go to their particular directory and download. However it appears they have the ability to list the directory of the entire bucket, I assume due to the s3:ListBucket
permission being allowed. But if I restrict that to only the folder my Transmit app notifies me that permission is denied.
Can anyone advise me how to correctly write this permission?
Upvotes: 0
Views: 129
Reputation: 269370
The first choice is how to track and authenticate the users.
Option 1: IAM Users
Normally, IAM User credentials are given to employees and applications. Policies can be applied directly against IAM Users to grant them access to resources.
In the case of granting IAM Users access to specific folders within an Amazon S3 bucket, the easiest method would be to put these users into an IAM Group and then author a policy that uses IAM Policy Variables that can automatically insert the name of the IAM User into the policy:
{
"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}/*"]
}
]
}
There is a limit of 5000 IAM Users in an AWS Account.
Option 2: Temporary credentials
Rather than giving IAM User 'permanent' credentials, the AWS Security Token Service (STS) can issue temporary credentials with an assigned permission policy.
The flow would typically be:
The credentials expire after a period of time and the users must reconnect to your app to obtain a new set of temporary credentials.
This is more secure because the app is responsible for ensuring authentication and granting permissions. There is less risk of accidentally granting permissions to a set of users.
Option 3: Pre-signed URLs
When a web application wishes to allow access to private objects in Amazon S3, it can generate an Amazon S3 pre-signed URLs, which is a time-limited URL that provides temporary access to a private object. It works like this:
<img src='...'>
, it generates a pre-signed URL that grants temporary access to a private objectThis is common in applications like photo-sharing systems where users might want to share photos with other users, so that the security is more complex than simply looking at the directory where the image is stored.
Bottom line
If you are using IAM Users, then use Option 1 and take advantage of IAM Policy Variables to write one policy that will grant appropriate access to each user. However, consider carefully whether giving IAM User access to external people is acceptable within your security posture.
Upvotes: 1
Reputation: 12259
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::my-bucket",
"Condition": {
"StringEquals": {
"s3:prefix": [
"client-1"
],
"s3:delimiter": [
"/"
]
}
}
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::my-bucket",
"Condition": {
"StringLike": {
"s3:prefix": [
"client-1/*"
]
}
}
},
{
"Sid": "VisualEditor2",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": "arn:aws:s3:::my-bucket/client-1/*"
}
]
}
Upvotes: 0