AWS S3 Bucket Policy throws Access Denied Error - amazon-web-services

As per the link https://docs.aws.amazon.com/AmazonS3/latest/dev/website-hosting-custom-domain-walkthrough.html --> I was trying to create and host a static page on AWS S3. But I'm having trouble providing public access to my bucket using bucket policy.
So, as soon as I paste
{
"Version":"2012-10-17",
"Statement":[{
"Sid":"PublicReadGetObject",
"Effect":"Allow",
"Principal": "*",
"Action":["s3:GetObject"],
"Resource":["arn:aws:s3:::mybucket-name.com/*"]
}]
}
it's throwing me access denied error.
in IAM, to my user id, I have associated below custom policy, but still, I'm getting the error message.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:ListBucket",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::mybucket-name.com",
"arn:aws:s3:::mybucket-name.com/*"
]
}
]
}
I have also linked this policy to my user name as well as role.
While creating the bucket, my "block public access" looks like this.
Also my ACL button I have provided public access to "List only".
So, can anyone help me what I'm missing here, I have looked into the different proposal provided here, still no luck. Can anyone give me any direction, like without getting lost?

You only assigned yourself permissions to edit content in the bucket. For a list of rights see the S3 docs.
You at least want to add s3:PutBucketPolicy to the list of your user permissions. But s3:PutBucketAcl and s3:PutBucketWebsite might also be useful.
Personally, i would likely just give s3:* to the user setting this up, or you might end up hitting this stumbling block again.

Related

AWS S3 ACL Permissions

So my bucket was and is still functioning correctly, I'm able to upload images through the API with no issues. However, I was messing around with the user policy and I made a change to the Resource for my User Policy and this caused some settings to change.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1420751757000",
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": CHANGE MADE HERE
}
]
}
When I try to upload an image through my AWS account (not using the API), then the ACL public access is private by default. I tried changing my Policy version back to what I had, but no change. I am pretty inexperienced with S3, so if I'm missing crucial info regarding this issue I can provide it.
If you want all objects to be public, then you should use a Bucket Policy.
This should typically be limited to only allowing people to download (Get) an object if they know the name of the object. You can use this Bucket Policy (which goes on the bucket itself):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": [
"arn:aws:s3:::YOUR-BUCKET-NAME/*"
]
}
]
}
This policy is saying: "Allow anyone to get an object from this bucket, without knowing who they are"
It does not allow listing of the bucket, upload to the bucket or deleting from the bucket. If you wish to do any of these operations, you would need to use your own credentials via an API call or using the AWS CLI.
For examples of bucket policies, see: Bucket policy examples - Amazon Simple Storage Service
Your IAM User should probably have a policy like this:
{
"Version":"2012-10-17",
"Statement":[
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
"Resource": [
"arn:aws:s3:::YOUR-BUCKET-NAME",
"arn:aws:s3:::YOUR-BUCKET-NAME/*"
]
}
]
}
This is saying: "Allow this IAM User to do anything in Amazon S3 to this bucket and the contents of this bucket"
That will grant you permission to do anything with the bucket (including uploading, downloading and deleting objects, and deleting the bucket).
For examples of IAM Policies, see: User policy examples - Amazon Simple Storage Service

Able to get some Amazon S3 objects but not all, getting 403 access denied error

Problem Statement:
Account A is uploading some file in an Amazon S3 bucket in Account B. I am in account C and trying to access objects in Account B Amazon S3 bucket. I am able to access some of the files but not all.
Account A is uploading files like this
this.s3Client.putObject(bucketName, key, new FileInputStream(content), metadata);
this.s3Client.setObjectAcl(bucketName, key, CannedAccessControlList.BucketOwnerFullControl);
I am only getting access denied for some of the files not all.
While I have checked Bucket Policy and lambda policy. It seems correct to me, as I am able to access other objects that were not uploaded by Account A and I feel that this issue is related to an object permission, where the uploader in s3 bucket has the exclusive access. But as we see in the above code, uploader is setting object acl to BucketOwnerFullControl
All the files are set to public already, also I have given access to Account C aws account canonical Id under ACL.
ACLs
Lambda policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::ACCOUNT_B_BUCKET/*"
}
]
}
Bucket Policy
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Example permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::AWS_ACCOUNT_C:root"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::ACCOUNT_B_BUCKET/*"
}
]
}
I have spent a lot of time on this and it is frustrating now. Please also let me know how can I debug these types of issues faster?
Can you please check the ACL or GO to S3 console and Select all files and make public. this is just a debugging step .

Understand Amazon S3 Bucket permissions

We have a bucket we want to store backups in.
The bucket is set to private not public (because it's backups) but when I try and give an IAM user permission to read and write to it AWS says that the bucket is private.
There is another bucket which is set to public where we're storing images and things that the any user should be able to see, but AWS complains that this one is set to public and is a security risk.
So not quite sure which setting should apply to which. The main goal at the moment is allowing restricted write access to the bucket for the purposes of backing up databases.
Any help would be greatly welcome :) thanks
The best practice is to keep the bucket private and give the permissions as needed, always using the Least Privilege Principle. In your case, you will need to give the users read and write permission with an IAM policy, such as the example:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:ListBucket"],
"Resource": ["arn:aws:s3:::examplebucket"]
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": ["arn:aws:s3:::examplebucket/*"]
}
]
}
For more information, you can check: https://aws.amazon.com/blogs/security/writing-iam-policies-how-to-grant-access-to-an-amazon-s3-bucket/

S3 policy - listing only specific bucket for user [duplicate]

I've been able to generate a user policy that only gives access to a specific bucket, however after trying everything (including this post: Is there an S3 policy for limiting access to only see/access one bucket?).
The problem: I am unable to restrict the listing of the buckets down to just one bucket. For a variety of reasons, I do not want the listing to show any buckets other than the one specified.
I've tried a variety of policies, to no avail. Here's my latest policy JSON which is working as far as restricting operations, but not listing:
{
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets",
"s3:ListBucket",
"s3:GetBucketLocation"
],
"Resource": "arn:aws:s3:::*"
},
{
"Effect": "Deny",
"Action": [
"s3:ListBucket"
],
"NotResource": [
"arn:aws:s3:::acgbu-acg",
"arn:aws:s3:::acgbu-acg/*"
]
},
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::acgbu-acg",
"arn:aws:s3:::acgbu-acg/*"
]
}
]
}
Any help would be greatly appreciated. I'm beginning to wonder if it's even possible.
It is not currently possible to restrict the list of buckets to show only one bucket.
The AWS console relies on the ListAllMyBuckets action to get the list of buckets owned by the user, but the returned list can not be restricted by using an Amazon Resource Name (or ARN; the only ARN that's allowed for ListAllMyBuckets is arn:aws:s3:::*).
This limitation isn't clearly explained in the official AWS docs, but ListAllMyBuckets is a service level API call (it's also called GET Service in the REST API), not a bucket level API call and its associated ARN in the IAM policy refers to the S3 service an not to a specific bucket.
For possible workarounds, see this answer on StackOverflow:
The free "S3 Browser" (this works on my version 3-7-5) allows users with the proper permissions to "Add External Bucket" for the account, all they need to know is the name of the bucket. This allows them to "see" their bucket and the contents (and what ever abilities they've been given inside that bucket), they won't see any of the other buckets.
To make the bucket "play nice" with the S3 Browser behavior, I suggest the following IAM Policy for the User or Group:
{
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation",
"s3:GetBucketAcl"
],
"Resource": "arn:aws:s3:::acgbu-acg"
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:GetObjectAcl",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::acgbu-acg/*"
}
]
}
It's a work around, and it's okay if the user only needs to do it once. But if the buckets your user is accessing are changing around a lot then this work around isn't very practical.
I came here looking for how to restrict access to a bucket to one (or a list of) user(s). Maybe, post title is ambiguous ?
Anyway, it seems to have Google's favor, so let's enrich it a little :
If you need to restrict access to a bucket to some user(s), follow those steps :
First, get the IDs of the user you want to grant rights to.
This can be achieved using the awscli command aws iam list-users
Those IDs look like this : "AIDAIFKYAC9DNJXM2CRD", or "AIDAZ362UEKJCJMFFXCL"
Please, comment if it's available in the web console.
Once you got the ID(s) that must be given access, put a policy on the bucket you want to protect.
To do this with the web console :
-> Open S3 -> Open your bucket -> Select the "properties" tab -> Click on "Edit bucket policy"
To apply the policy using awscli, create a file with the policy's content, and put it on your bucket using this command :
aws s3api put-bucket-policy --bucket NAME_OF_YOUR_BUCKET --policy file:///path/to/policyFile.json
Of course, set YOUR_BUCKET_NAME and the file's path to your values, BUT DON'T remove the file:// prefix before your file's name
Warning : this deny policy will override the default "access to s3" a user could have. This means you can deny access to your OWN user with this. Use with caution !
I'm even afraid you could make a bucket fully innaccessible.
Out of curiosity, I tried accessing with our account's root user, which I didn't grant access to, and effectively couldn't.
Gotta ask this to support, and hopefully update this answer.
Anyway, I'm sure you'll be careful enough, so here's a sample policy.
Just replace the bucket's name with yours and the userId(s) with the one(s) you want to authorize to access.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::your-bucket-name",
"arn:aws:s3:::your-bucket-name/*"
],
"Condition": {
"StringNotLike": {
"aws:userId": [
"AIDAXAXAXAXAXAXAXAXAX",
"AIDAOXOXOXOXOXOOXOXOX",
"AIDAXIXIXIXIXIXIXIXIX"
]
}
}
}
]
}
For something more specific, or if you want to use roles instead of users, see this AWS post explaining in detail how to restrict access to a buckets
Hope this helps
The original poster was asking about a user policy. This would be attached to particular user(s) while others may have more leineint policies (or no policy) applied to them. A typical use case would be where you only want to restrict one user, whose credentials need to be shared outside the highest trust group. User policy is the way to go for that..

How do I limit access to S3 Bucket for particular IAM Role?

We want to store some data on S3 and only allow EC2 instances or a particular user with a particular IAM role to access them. Unfortunately we're having some trouble doing this.
We set a policy on the bucket like this
{
"Version": "2012-10-17",
"Id": "SamplePolicy",
"Statement": [
{
"Sid": "Stmt1331136294179",
"Effect": "Deny",
"NotPrincipal": {
"AWS": [
"arn:aws:iam::our-account-number:user/the-user",
"arn:aws:iam::our-account-number:role/the-role"
]
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::the-bucket/*"
},
{
"Sid": "Stmt1331136364169",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::our-account-number:user/the-user",
"arn:aws:iam::our-account-number:role/the-role"
]
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::the-bucket/*"
}
]}
When we access the Bucket (using boto) with users key it works fine, from a local machine or any EC2 instance.
But, when we access the bucket from Boto we get
ClientError: An error occurred (AccessDenied) when calling the GetObject operation: Access Denied
I've confirmed that the instance has the correct IAM role
curl http://169.254.169.254/latest/meta-data/iam/info/
{
"Code" : "Success",
"LastUpdated" : "2015-10-22T09:09:31Z",
"InstanceProfileArn" : "our-account-number:instance-profile/the-role",
"InstanceProfileId" : "instance-rpofile-id"
}
I've also tried to remove the policy from the bucket, which indeed makes it accessible again.
Any ideas how to handle this?
The sample I shared here is a simplified version I've been doing for debugging. In production, we want are forcing the object to be encrypted with KMS and have an access policy on the key as well. We like that solution alot, and prefer to keep it if we can.
Thanks
One mistake with this that I've made many times involves your ARN
For some permissions you need it on the bucket itself (no /*)... and some you need on it's contents.
I'd attempt to use what you currently have, only include both, so something like...
"Resource": ["arn:aws:s3:::the-bucket/*", "arn:aws:s3:::the-bucket"]
The issue here is that for NotPrincipal you have to provide the specific session role. Unfortunately, when using InstanceProfiles (or Lambda), this session role is dynamic. AWS does not support wildcards in the principal field so therefore it is basically impossible to use NotPrincipal with an InstanceProfile.
See AWS support response here that acknowledges it as a known limitation: https://forums.aws.amazon.com/message.jspa?messageID=740656#740656