S3 keep entropy high for cognito-identity.amazonaws.com:sub user directory - amazon-s3

I am authenticating each user via Cognito and each user has a folder everyone can read from but only he can write to it. Works like a charm.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowReadingOthers",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::111111:role/Cognito_Auth_Role"
]
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::xxxxxx/*"
},
{
"Sid": "AllowUploadIntoHomeDirectory",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111111:role/Cognito_Auth_Role"
},
"Action": "s3:PutObject",
"Resource": [
"arn:aws:s3:::xxxxxx/user/${cognito-identity.amazonaws.com:sub}/*"
]
}
]
}
The problem is the entropy for the folder names is very low since every folder starts with "us-east-1:", which can result in performance problems later on.
My workaround is to add additional entries with a "random" (aa-zz) start and add this to the database and the rules. Works too, but I want to avoid having that many rules for my bucket if possible.
"Resource": [
"arn:aws:s3:::xxxxxx/user/aa${cognito-identity.amazonaws.com:sub}/*"
"arn:aws:s3:::xxxxxx/user/ab${cognito-identity.amazonaws.com:sub}/*"
"arn:aws:s3:::xxxxxx/user/ac${cognito-identity.amazonaws.com:sub}/*"
.
.
.
"arn:aws:s3:::xxxxxx/user/zy${cognito-identity.amazonaws.com:sub}/*"
"arn:aws:s3:::xxxxxx/user/zz${cognito-identity.amazonaws.com:sub}/*"
]
Is there another way to add entropy with cognito-identity.amazonaws.com:sub?

Related

IAM Policy is not giving access to the accesspoint

With this policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:ListStorageLensConfigurations",
"s3:ListAccessPointsForObjectLambda",
"s3:GetAccessPoint",
"s3:PutAccountPublicAccessBlock",
"s3:GetAccountPublicAccessBlock",
"s3:ListAllMyBuckets",
"s3:ListAccessPoints",
"s3:ListJobs",
"s3:PutStorageLensConfiguration",
"s3:CreateJob"
],
"Resource": "*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}
]
}
I am allowed to access a specific s3 accesspoint. However, when I try using a more specific access which only gives s3:* actions to a specific accesspoint:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:ListStorageLensConfigurations",
"s3:ListAccessPointsForObjectLambda",
"s3:GetAccessPoint",
"s3:PutAccountPublicAccessBlock",
"s3:GetAccountPublicAccessBlock",
"s3:ListAllMyBuckets",
"s3:ListAccessPoints",
"s3:ListJobs",
"s3:PutStorageLensConfiguration",
"s3:CreateJob"
],
"Resource": "*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "s3:*",
"Resource": "arn:aws:s3:eu-west-1:598276570227:accesspoint/accesspointname"
}
]
}
This does not work, and the EC2 with this role stops being able to access the s3 access point (just copying a file using the AWS CLI)
First why is this happening? The role still should have access to all the actions on that accesspoint by my reckoning (which must be wrong in some way!).
Secondly, I am trying to make it such that an s3 bucket is only accessible from a certain IAM role. I tried setting this from the access policy from the access point itself. This had the opposite problem that it was too permissive and everything could still access it. What is the correct way of doing this - putting an IAM policy on the accesspoint to restrict access to the IAM role or making an IAM Role which has access to this s3 access point?
I got this working by using this:]
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:ListStorageLensConfigurations",
"s3:ListAccessPointsForObjectLambda",
"s3:GetAccessPoint",
"s3:PutAccountPublicAccessBlock",
"s3:GetAccountPublicAccessBlock",
"s3:ListAllMyBuckets",
"s3:ListAccessPoints",
"s3:ListJobs",
"s3:PutStorageLensConfiguration",
"s3:CreateJob"
],
"Resource": "*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*",
"Condition": {
"StringLike": {
"s3:DataAccessPointArn": "arn:aws:s3:eu-west-1:598276570227:accesspoint/accesspointname"
}
}
}
]
}

AWS S3 bucket policy to block source IP address not working

I know this question has been asked a few times and I have gone through a some documents and examples on this. But I am still not able to get it working.
I want to block access to my S3 bucket from one particular IP address and allow all others. I do not want to block instances belonging to an IAM role and hence I am using NotIpAddress Condition for this. Below is the policy I applied on my bucket:
{
"Version": "2012-10-17",
"Id": "Policy1486984747194",
"Statement": [
{
"Sid": "AllowAllExceptOneIP",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-test-bucket",
"Condition": {
"NotIpAddress": {
"aws:SourceIp": "52.38.90.46"
}
}
}
]
}
But this policy isn't working. I am able to upload files to my bucket from this machine, I am using s3-curl.pl to temporarily upload my files.
Can someone please help me find what is wrong here. Thanks.
To block all actions to an S3 bucket from a particular IP, policy needs to have separate deny effect statement for that IP, sample:
{
"Version": "2012-10-17",
"Id": "Policy1487062767078",
"Statement": [
{
"Sid": "AllowAll",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my-test-bucket",
"arn:aws:s3:::my-test-bucket/*"
]
},
{
"Sid": "DenyIP",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my-test-bucket",
"arn:aws:s3:::my-test-bucket/*"
],
"Condition": {
"IpAddress": {
"aws:SourceIp": "52.38.90.46"
}
}
}
]
}
Action and Resource can be changed based on what one needs to block.
Thanks a lot #SergeyKovalev for helping me with this solution.

How can I set a policy for an s3 bucket that allows authenticated users to list the bucket or get any file from the bucket

I have set a permission on the bucket that allows "Authenticated Users" to list, upload, and delete from a bucket I created. This seems to allow me to upload files to the bucket, but it appears that downloading files from the bucket is not covered by this permission, and I instead need to define a policy for the bucket. It's not clear to me how to set such a policy. I tried the policy generator with my best guesses at what I should fill in, but the result was not a valid policy when I pasted it in as a new policy for the bucket (it failed with the message Action does not apply to any resource(s) in statement - Action "s3:ListBucket" in Statement "Stmt-some-number"). Can someone explain what is wrong with the following policy and how to set it correctly to allow authenticated users to retrieve files from the bucket?
{
"Id": "Policy-some-number",
"Statement": [
{
"Sid": "Stmt-some-number",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::my-bucket/*",
"Principal": {
"AWS": [
"*"
]
}
}
]
}
s3:GetObject applies to the objects in the bucket so the Resource is correct: "Resource": "arn:aws:s3:::my-bucket/*".
s3:ListBucket applies to the Bucket itself and so the Resource should be "Resource": "arn:aws:s3:::my-bucket"
your resulting policy should resemble:
{
"Id": "Policy-some-number",
"Statement": [
{
"Sid": "Stmt-some-number",
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::my-bucket/*",
"Principal": {
"AWS": [
"*"
]
}
},
{
"Sid": "Stmt-some-other-number",
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::my-bucket",
"Principal": {
"AWS": [
"*"
]
}
}
]
}
Just to compliment #c4urself answer. the answer help solve my issue as well, but there is some indication from AWS documentation, which you can add more than one resource, just use [] to make them a list.
http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/vpc-endpoints.html#vpc-endpoints-s3-bucket-policies
{
"Statement": [
{
"Sid": "Access-to-specific-bucket-only",
"Principal": "*",
"Action": [
"s3:ListBucket",
"s3:GetObject",
"s3:PutObject"
],
"Effect": "Allow",
"Resource": ["arn:aws:s3:::my_secure_bucket",
"arn:aws:s3:::my_secure_bucket/*"]
}
]
}
Update Bucket policy as below
{
"Version": "2012-10-17",
"Id": "Policy1546023103427",
"Statement": [
{
"Sid": "Stmt1546023101836",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:ListBucket",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::usagereports-atul",
"arn:aws:s3:::usagereports-atul/*"
]
}
]
}
Just make the resource and array/list of resources and add an item to the list with /* as s3:GetObject applies to arn:aws:s3:::my_secure_bucket/*. See below
"Resource": ["arn:aws:s3:::my_secure_bucket",
"arn:aws:s3:::my_secure_bucket/*"

Necessary s3cmd S3 permissions for PUT/Sync

In moving to AWS EC2, I want to restrict my instances' user permissions for good reason. One thing the instances need to do is access files on S3 and write files there. However, I cannot find any way to achieve this without giving all permissions to that user.
s3cmd allows me to call "ls" and "du" on the s3 buckets I gave the policy permission to, but always fails with a 403 error when trying to PUT/sync with one of these folders. If I use my root credentials, the transfer goes right through.
So, I don't get why if I give all permissions to the user for said buckets, it cannot PUT, but if I give it arn:aws:s3:::* (all buckets) then it can. Makes no sense to me.
Anyone else ever dealt with this before?
Try something like this. I think the problem is that you need s3:ListAllMyBuckets and s3:ListBuckets for the s3cmd to work. Not sure why but it wont work unless it can get a list of the buckets. I had the same problem the first time i tried to use permissions with s3cmd and this was the solution.
{
"Statement": [
{
"Action": [
"s3:ListAllMyBuckets"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::*"
},
{
"Action": [
"s3:ListBucket",
"s3:PutObject",
"s3:PutObjectAcl"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::bucket/path",
"arn:aws:s3:::bucket/path/*"
]
}
]
}
Edit I've added the s3:PutObjectAcl action which is required for newer versions of s3cmd as stated by Will Jessop below.
bwight's answer is almost right (it probably used to be for older versions of s3cmd), but I need to add a s3:PutObjectAcl to get it to work:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt123456",
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets"
],
"Resource": [
"arn:aws:s3:::*"
]
},
{
"Sid": "Stmt123457",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": [
"arn:aws:s3:::bucketname",
"arn:aws:s3:::bucketname/*"
]
}
]
}
I was trying to do big file uploads and the policy wasn't working well for me, I ended adding the next policy to the user:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1397834652000",
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets"
],
"Resource": [
"arn:aws:s3:::*"
]
},
{
"Sid": "Stmt1397834745000",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:ListBucketMultipartUploads",
"s3:GetBucketLocation",
"s3:AbortMultipartUpload",
"s3:GetObjectAcl",
"s3:GetObjectVersion",
"s3:DeleteObject",
"s3:DeleteObjectVersion",
"s3:GetObject",
"s3:PutObjectAcl",
"s3:PutObject",
"s3:GetObjectVersionAcl"
],
"Resource": [
"arn:aws:s3:::my_bucket",
"arn:aws:s3:::my_bucket/*"
]
}
]
}
where my_bucket is the bucket where I need to manage files though s3cmd
In case you are giving access to a subfolder (as in the original answer of /bucket-name/path/) and not the entire bucket, the ListBucket action requires a bit more specificity:
{
"Sid": "AllowListingOfFilesInFolder",
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::bucket-name"
],
"Condition": {
"StringLike": {
"s3:prefix": [
"path/*"
]
}
}
}
I believe it works also with the original answer in case you provide access to the entire bucket.

Why am I getting AccessDenied with videos?

Using AWS S3. I have a mixture of video and photo files. All of which are in their respective sub-directories. All files are set to private. I am getting AccessDenied when I try to access a video file. The other files are fine.
I tried this to no avail:
{
"Id": "Policy1331547131417",
"Statement": [
{
"Sid": "Stmt1331546963174",
"Action": [
"*"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::actual_bucket_name_here/uploads/users/*/videos/*",
"Principal": {
"AWS": [
"*"
]
}
},
{
"Sid": "Stmt1331547083926",
"Action": [
"*"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::actual_bucket_name_here/uploads/users/*/photos/*",
"Principal": {
"AWS": [
"*"
]
}
},
{
"Sid": "Stmt1331547130024",
"Action": [
"*"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::actual_bucket_name_here/uploads/users/*/banners/*",
"Principal": {
"AWS": [
"*"
]
}
}
]
}
My bucket policy is the same for videos, photos, and banners. ACL permissions are also the same for all files. So why am I not able to access files from my videos directory?
How do you actually try to access your video files, i.e. by means of which tool, service, API?
The access method in use might actually require permission for the s3:ListBucket action as well, e.g. a JavaScript video player widget might implicitly look for various file formats of the video in question to present a respective selection to your user - you'll need to be aware of the difference between Operations on Buckets (e.g. ListBucket) and Operations on Objects (e.g. GetObject), see my answer to Problems specifying a single bucket in a simple AWS user policy for more details on this.
Extending your video bucket policy accordingly might remedy this issue, e.g. (policy fragment only):
{
"Statement": [
{
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::actual_bucket_name_here/uploads/users/*/videos",
"Principal": {
"AWS": [
"*"
]
}
}
]
}
Please note that this policy fragment addresses the bucket, where yours only addresses the objects therein and both fragments are required - as mentioned above, this subtle difference is explained in my answer to Problems specifying a single bucket in a simple AWS user policy.
In addition to Steffen Opel answer.
Below is what worked for me.
{
"Statement": [
{
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::BUCKET_NAME/*",
"Principal": {
"AWS": [
"*"
]
}
}
]
}