Can't add multiple bucket policies to S3 bucket - amazon-web-services

im unable to add domain level privacy bucket policy with zencoder bucket policy. they work when i add one at a time but when i try to implement both it doesnt work. im just looking for a solution to implement both bucket polices in one bucket. i tried to add condition from the domain level privacy to zencoders bucket policy. but the domain level privacy stops working.
here is the bucket policies im trying to add .
{
"Version": "2012-10-17",
"Id": "http referer policy example",
"Statement": [
{
"Sid": "Allow get requests originating from www.example.com and example.com.",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::newbbbb/*",
"Condition": {
"StringLike": {
"aws:Referer": "https://www.vlogmo.com/*"
}
}
}
]
}
{
"Version": "2012-10-17",
"Id": "ZencoderBucketPolicy",
"Statement": [
{
"Sid": "Stmt1295042087538",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::395540211253:root"
},
"Action": [
"s3:GetObjectAcl",
"s3:GetObject",
"s3:PutObjectAcl",
"s3:PutObject",
"s3:ListMultipartUploadParts"
],
"Resource": "arn:aws:s3:::MY-BUCKET/*"
},
{
"Sid": "Stmt1295042087538",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::395540211253:root"
},
"Action": [
"s3:ListBucketMultipartUploads",
"s3:GetBucketLocation"
],
"Resource": "arn:aws:s3:::MY-BUCKET"
}
]
}

im just looking for a solution to implement both bucket polices in one bucket
You can't do this. A bucket can have only one policy. So you have to join your two policies, into one by adding new Statement:
{
"Version": "2012-10-17",
"Id": "ZencoderBucketPolicy",
"Statement": [
{
"Sid": "Stmt1295042087538",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::395540211253:root"
},
"Action": [
"s3:GetObjectAcl",
"s3:GetObject",
"s3:PutObjectAcl",
"s3:PutObject",
"s3:ListMultipartUploadParts"
],
"Resource": "arn:aws:s3:::MY-BUCKET/*"
},
{
"Sid": "Stmt1295042087538",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::395540211253:root"
},
"Action": [
"s3:ListBucketMultipartUploads",
"s3:GetBucketLocation"
],
"Resource": "arn:aws:s3:::MY-BUCKET"
},
{
"Sid": "Allow get requests originating from www.example.com and example.com.",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::newbbbb/*",
"Condition": {
"StringLike": {
"aws:Referer": "https://www.vlogmo.com/*"
}
}
}
]
}

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.

How to merge AWS S3 bucket policies?

We have an existing S3 bucket policy in production:
{
"Version": "2012-10-17",
"Id": "Policy[redacted]",
"Statement": [
{
"Sid": "ServiceA access",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[redacted]:root"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::mysite-production/*"
},
{
"Sid": "ServiceA access",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[redacted]:root"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::mysite-production"
},
{
"Sid": "AllowPublicRead",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::mysite-production/*"
}
]
}
We have another 3rd party service we want to grant access which requires:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:PutObjectAcl",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*"
},
{
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets",
"s3:GetBucketLocation"
],
"Resource": "arn:aws:s3:::*"
}
]
}
I've tried merging the ListAllMyBuckets and GetBucketLocation into the final section of our original policy but that yields "Policy has invalid action" errors:
{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:PutObjectAcl",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::mysite-production/*"
}
How can I merge these into one cohesive policy? Or is it possible for a bucket to have two policies?
Thanks in advance!
You can actually apply both IAM policies and S3 bucket policies
simultaneously, with the ultimate authorization being the least-privilege union of all the permissions.
Source: https://aws.amazon.com/blogs/security/iam-policies-and-bucket-policies-and-acls-oh-my-controlling-access-to-s3-resources/

Couldn't read directory: Permission denied when using AWS SFTP

I am trying to set up a simple AWS SFTP server with a scoped-down policy but keep getting permission denied errors when trying to put and get.
Here is IAM Role with generic S3 bucket access:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowListingOfUserFolder",
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::SOME-EXAMPLE-BUKCET"
]
},
{
"Sid": "HomeDirObjectAccess",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObjectVersion",
"s3:DeleteObject",
"s3:GetObjectVersion"
],
"Resource": "arn:aws:s3:::SOME-EXAMPLE-BUCKET/*"
}
]
}
And this is the scoped-down policy which I attach to the user when I create it in the SFTP panel:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::${transfer:HomeBucket}",
"Condition": {
"StringLike": {
"s3:prefix": [
"${transfer:UserName}/*",
"${transfer:UserName}"
]
}
}
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "s3:GetBucketLocation",
"Resource": "arn:aws:s3:::SOME-EXAMPLE-BUCKET"
},
{
"Sid": "VisualEditor2",
"Effect": "Allow",
"Action": "s3:ListAllMyBuckets",
"Resource": "*"
},
{
"Sid": "VisualEditor3",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObjectAcl",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::${transfer:HomeDirectory}/*",
"arn:aws:s3:::${transfer:HomeDirectory}*"
]
}
]
}
The goal is for a user to log in and land in their home directory with read/write/delete permissions for just that directory. I've tried various policies from the following links but never quite get what I need:
Connecting to AWS Transfer for SFTP
https://docs.aws.amazon.com/transfer/latest/userguide/users.html
https://docs.aws.amazon.com/transfer/latest/userguide/requirements-roles.html
I always either get no access at all and everything is denied (i.e. can't even ls). Or I can ls but can't do anything else like mkdir, put, get, etc...
In the scoped-down policy, why do you use transfer:UserName in the ListBucket condition rather than transfer:HomeDirectory like in the Put/Get/DeleteObject statement? Is the HomeDirectory of the user the same as its username?
What happens when you try something like this?
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::${transfer:HomeBucket}",
"Condition": {
"StringLike": {
"s3:prefix": [
"${transfer:HomeDirectory}/*",
"${transfer:HomeDirectory}"
]
}
}
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "s3:GetBucketLocation",
"Resource": "arn:aws:s3:::SOME-EXAMPLE-BUCKET"
},
{
"Sid": "VisualEditor2",
"Effect": "Allow",
"Action": "s3:ListAllMyBuckets",
"Resource": "*"
},
{
"Sid": "VisualEditor3",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObjectAcl",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::${transfer:HomeDirectory}/*",
"arn:aws:s3:::${transfer:HomeDirectory}*"
]
}
]
}
Do not use ${transfer:Username} in the scoped down policy. Also, make sure you specify it as Policy key within secrets manager.
I have documented the full setup here in case you need to reference it - https://coderise.io/sftp-on-aws-with-username-and-password/

AWS S3 storage permission denied from Elastic Beanstalk

I'm trying to access to one of my S3 storage buckets from my EC2 instance deployed by ElasticBeanstalk. My EC2 instance belongs to aws-elasticbeanstalk-ec2-role and I have granted this role with AmazonS3FullAccess policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}
]
}
Then the bucket policy is as follows:
"Version": "2008-10-17",
"Statement": [
{
"Sid": "eb-ad78f54a-f239-4c90-adda-49e5f56cb51e",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::XXXXXX:role/aws-elasticbeanstalk-ec2-role"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::elasticbeanstalk-us-east-XXXXXX/resources/environments/logs/*"
},
{
"Sid": "eb-af163bf3-d27b-4712-b795-d1e33e331ca4",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::XXXXXX:role/aws-elasticbeanstalk-ec2-role"
},
"Action": [
"s3:ListBucket",
"s3:ListBucketVersions",
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": [
"arn:aws:s3:::elasticbeanstalk-us-east-2-XXXXXX",
"arn:aws:s3:::elasticbeanstalk-us-east-2-XXXXXX/resources/environments/*"
]
},
{
"Sid": "eb-58950a8c-feb6-11e2-89e0-0800277d041b",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:DeleteBucket",
"Resource": "arn:aws:s3:::elasticbeanstalk-us-east-2-XXXXXX"
}
]
}
When I try to access the bucket from an SSH connection or through a script inside .ebextensions I receive an Access Denied 403 error. I tried making the files public and using the same commands and I worked perfectly, but the files I need can't be public.
I think I have the correct policies for both the bucket and the EC2 role. I might be forgetting some detail though.
Any help will be welcomed. Thank you folks in advance!
So based on my knowledge and previous issues I experienced, your bucket policy is incorrect.
It isn't valid because ListBucket and ListBucketVersions actions must be applied to bucket name, not prefix.
Here is my corrected policy that should work;
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "eb-ad78f54a-f239-4c90-adda-49e5f56cb51e",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::XXXXXX:role/aws-elasticbeanstalk-ec2-role"
},
"Action": "s3:PutObject",
"Resource": [
"arn:aws:s3:::elasticbeanstalk-us-east-XXXXXX/resources/environments/logs/*",
"arn:aws:s3:::elasticbeanstalk-us-east-XXXXXX/resources/environments/logs"
]
},
{
"Sid": "eb-af163bf3-d27b-4712-b795-d1e33e331ca4",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::XXXXXX:role/aws-elasticbeanstalk-ec2-role"
},
"Action": [
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": [
"arn:aws:s3:::elasticbeanstalk-us-east-2-XXXXXX/resources/environments",
"arn:aws:s3:::elasticbeanstalk-us-east-2-XXXXXX/resources/environments/*"
]
},
{
"Sid": "eb-af163bf3-d27b-4712-b795-anything",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::XXXXXX:role/aws-elasticbeanstalk-ec2-role"
},
"Action": [
"s3:ListBucket",
"s3:ListBucketVersions"
],
"Resource": [
"arn:aws:s3:::elasticbeanstalk-us-east-2-XXXXXX"
]
},
{
"Sid": "eb-58950a8c-feb6-11e2-89e0-0800277d041b",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:DeleteBucket",
"Resource": "arn:aws:s3:::elasticbeanstalk-us-east-2-XXXXXX"
}
]
}
Useful docs to reference to for the future -> AWS s3 docs

Restricting AWS S3 Bucket access to a single role

I'm trying to restrict access to an S3 bucket to a single EC2 role. I've attached the following bucket policy to the bucket, and the bucket has public access turned off. However when the policy is applied, I can still get to the bucket using curl from an instance without the role attached. Can anyone let me know what I'm missing?
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::bucketname",
"Condition": {
"StringLike": {
"aws:userid": [
"AROQQQCCCZZDDVVQQHHCC:*",
"123456789012"
]
}
}
},
{
"Sid": "",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:DeleteObject",
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::bucketname/*",
"Condition": {
"StringLike": {
"aws:userid": [
"AROQQQCCCZZDDVVQQHHCC:*",
"123456789012"
]
}
}
},
{
"Sid": "",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::bucketname/*",
"arn:aws:s3:::bucketname"
],
"Condition": {
"StringNotLike": {
"aws:userid": [
"AROQQQCCCZZDDVVQQHHCC:*",
"123456789012"
]
}
}
}
]
}
I believe the following S3 policy should do the job. Remember to replace role arn with the correct one which I assume it attached to your EC2 instance. Also, make sure your ec2 role has correct policy to perform list,get,put,delete actions.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ExplicitDenyAllActions",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::bucketname/*",
"arn:aws:s3:::bucketname"
]
},
{
"Sid": "AllowListForIAMRole",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111111111111:role/ROLENAME"
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::bucketname"
},
{
"Sid": "AllowDeleteGetPutForIAMRole",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111111111111:role/ROLENAME"
},
"Action": [
"s3:Delete*",
"s3:Get*",
"s3:Put*"
],
"Resource": [
"arn:aws:s3:::bucketname/*",
"arn:aws:s3:::bucketname"
]
},
{
"Sid": "AllowAllActionForUser",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::111111111111:user/USERNAME"
]
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::bucketname/*",
"arn:aws:s3:::bucketname"
]
}
]
}
Useful docs where you can find more info -> AWS docs on s3 policies