AWS Mutliple CloudFront distributions in S3 Bucket Policy - amazon-web-services

I'm trying to add multiple CloudFront distributions to a secured bucket
I saw another StackOverflow post where you add multiple users like this, but I'm getting the Invalid principal in policy error
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity **************",
"arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity **************"
]
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucket-name/*"
}
]
How can I add multiple principles?

Your policy is correct. However, the error Invalid principal in policy often indicates that the principles simply don't exist yet. Make sure that you've already created two OAI users and you are using their IDs correctly in your policy.

Related

Mapping multiple S3 buckets to the same URL using AWS CloudFront - Access Denied error on non-default path patterns

How can I map two different S3 buckets to the same URL using AWS CloudFront?
I have created two origins; one origin with path /preview of one bucket and another with the path /harry for another bucket. In the behaviors section, I have set the Default behavior to use the /preview origin and a separate behavior with the /harry/* path pattern that uses the /epub origin. However, only the Default behavior is working and the /harry/* pattern returns an "Access Denied" error.
URL example:
https://xxxx.cloudfront.net/harry/example.xhtml = Access Denied
https://xxxx.cloudfront.net/image.png = Works fine
Cloud front configuration:
Origins: https://postimg.cc/N9MQh5dQ
Behaviors: https://postimg.cc/KkKCrL93
Preview Origin policy
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E3HIYxxxx"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::xxxxxstorage/preview/*"
}
]
}
harry origin policy
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E3HIYxxxx"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::xxxxxdevelopment/harry/*"
}
]
}
The issue with this configuration is that only the Default behavior is working, regardless of the associated origin. Is there something that I am missing or not properly configured in this setup?
I aim to do the same thing that you are trying to do, but am still in the research phase.
It seems you need a folder inside the alternative bucket with a name which matches the trailing portion of the bucket Origin Domain Name.
There is an brief post on this topic from 2015: https://stackoverflow.com/a/32002341
As well as an excellent blog post and YouTube video: https://vimalpaliwal.com/blog/2018/10/10f435c29f/serving-multiple-s3-buckets-via-single-aws-cloudfront-distribution.html
This is the approach that I will take as I move forward.

access denied when I attempt to upload to s3 with a signed post could it be the bucket policy?

I have a s3 bucket which does not have public access. I have a bucket policy but it was automatically generated when I connected a CDN to the bucket for a origin access Identity.
But thats all the policy has.
Bucket polices are dicks for me. Im wondering if this is in fact the problem or if it may be something else.
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::shofi-mod/*"
}
]
}
for comparison here is the bucket policy of my other bucket that does have public access. I am looking at the two for clues of what it is I should do
{
"Version": "2012-10-17",
"Id": "",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam:::user/shofi-stuff-bucket-user"
},
"Action": [
"s3:ListBucket",
"s3:ListBucketVersions",
"s3:GetBucketLocation",
"s3:Get*",
"s3:Put*"
],
"Resource": "arn:aws:s3:::shofi-stuff"
}
]
}
thank you so much kings
There's a few topics here.
The first bucket policy you have shown simply grants access to CloudFront via an Allow policy. It would not interfere with the pre-signed URL.
The second bucket policy (while not being directly relevant to your question) has an error in it. When using GetObject and PutObject, access must be granted to the contents of the bucket, no the bucket itself. (Whereas ListBucket does apply to the bucket.)
Therefore, the Resource should grant access to the bucket and the contents of the bucket:
"Resource": ["arn:aws:s3:::shofi-stuff", "arn:aws:s3:::shofi-stuff/*"]
As to why your pre-signed URL is not working, it would either be due to:
The underlying credentials (IAM User, IAM Role) that was used to generate the pre-signed URL does not have permission to perform the upload (perhaps due to a similar Resource problem), or
The pre-signed URL is being incorrectly generated

How to make a public bucket only accessible from cloudfront without OAI?

I have a bucket that contains some images. The bucket is publicly accessible using the following policy.
{
"Version": "2008-10-17",
"Id": "s3BucketPolicy",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::Bucketname/*"
}
]
}
Also I have a cloudfront distribution that points to the same bucket. My problem now is that my file is accessible from both cloudfront link and bucket link.
CloudfrontLink: www.xxxxxx.xxxx/xxxx
BucketLink: www.bucketname/xxx
My question how can i make my bucket publicly accessible using cloudfront only. I don't want signed urls or cookies. I want any my anyone with cloudfrontlink to be able to access the image and prevent anyone with bucketlink from accessing the image.
Change the S3 bucket policy principal to the OAI of the CloudFront Distribution. For example:
{
"Version": "2008-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ABCDABCDABCDAB"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::mybucket/*"
}
]
}
This will prevent access to the bucket contents outside of CloudFront. You don't need signed URLS here. See the documentation for more details.

AWS S3 Bucket Policy with NotPrincipal denying access

I have configured my S3 bucket with Bucket Policy that looks like this
{
"Version": "2012-10-17",
"Id": "Policy100000000000",
"Statement": [
{
"Sid": "Stmt1463490591045",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucketname/*"
},
{
"Sid": "Stmt1463490591012",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::012345678900:user/user1",
"arn:aws:iam::012345678900:user/user2"
]
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::bucketname"
},
{
"Sid": "Stmt1463490660089",
"Effect": "Deny",
"NotPrincipal": {
"AWS": [
"arn:aws:iam::012345678900:user/user1",
"arn:aws:iam::012345678900:user/user2"
]
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucketname/*.xml"
}
]
}
The goal is to allow access to xml files in the bucket root to the selected users only. The rule doesn't seem to be working, since I get access denied
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>DE3DB1FF18B53997</RequestId><HostId>Iy+RnfkFKygJWkSTI0dXjssFsGFP2MydZZi/R5KBw5M8mZnfClt6HMOKJvAwy7sJgSx9BJQ3DbN=</HostId></Error>
I've tried fetching the xml files with AWS Node.js and Python SDKs and with aws-cli. I keep getting the same access denied message.
The AWS documentation regarding Bucket Policies is quite scattered around and has not provided me with a solution to the problem. There's very little documentation at all about using notPrincipal in the policy.
The ListBucket permission works all right, which means that the problem is specific to the rule, not the aim users.
The goal is to allow access to xml files in the bucket root to the selected users only
As per current documentation, s3 do not support file listing resource per postfix/filetype. It only support with prefix, so you would need to put a star without .xml at the end (which allow to access all objects at the folder layer), then you could implement logic to your app if you would allow to access the file or not.
For the bucket policy, by default, s3 policy would give access to user from the account (where the bucket created), as long as the IAM policy have the permission to do so. This is defined from ACL (Access Control List), go to S3 > Permission > Access Control List to check it out.[ AWS S3 ACL docs ]. So the first 2 statement might not be necessary in the statements. For the last statement, this might work but need an additional assumed-role ARN which will vary depending on what is defined for the role session name.
It is recommended to not use the NotPrincipal, and instead use the Condition key at the statement. Put the roleId as the userId at the StringNotLike statement to ignore the deny statement for the particular roleId. Also include the account number at the userId. Example as follows.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::MyExampleBucket",
"arn:aws:s3:::MyExampleBucket/*"
],
"Condition": {
"StringNotLike": {
"aws:userId": [
"ROLE_ID_HERE:*",
"ACCOUNT_NUMBER_HERE"
]
}
}
}
]
}
Check out on this AWS blog for more info:
https://aws.amazon.com/blogs/security/how-to-restrict-amazon-s3-bucket-access-to-a-specific-iam-role/
Your last deny policy simply doesn't talk about what should happen (allow or deny) to the requests with principal user1 or user2. When you send an s3 request as user1 or user2, the bucket policy won't have any effect (since it doesn't have any rule matching the principal user1 or user2 w.r.t the given action and the given resource).
The goal is to allow access to xml files in the bucket root to the selected users only
In this situation, you can mention a rule for explicitly allowing those users the access to your xml files.
{
"Sid": "Stmt1463490660089",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::012345678900:user/user1",
"arn:aws:iam::012345678900:user/user2"
]
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucketname/*.xml"
}

AmazonS3FullAccess managed policy on a group doesn't give S3 permission?

I have an S3 bucket that has in its policy permission for my CloudFront origin access identity:
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity <mine>"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::<my-bucket>/*"
}
]
}
Additionally I've created a group and attached the AmazonS3FullAccess managed policy to it and added an IAM user to that group. The managed policy looks like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}
]
}
However when that user tries to add anything to the bucket, I get a 403 (access denied). I'm unsure if any other operations work, I haven't written code to try them. It's only when I specifically allow that user's ARN access to the bucket directly in the bucket policy that they're allowed to add objects. What am I missing? It seems like the above group policy should allow members of that group access to all operations in all buckets, but it doesn't do that.
EDIT: After a whole bunch more poring over documentation, I think I've figured out that Amazon doesn't intend for groups to be used this way. They want you to use roles instead, which you can assign to an EC2 instance for automagic credential management. That's fine, but then I can't figure out how to test my code (using the aws-sdk Ruby gem) locally. Amazon says to define environment variables for your access ID and key - but what access ID and key? There's no such thing for a role...
Try replacing (in your policy):
"Resource": "arn:aws:s3:::<my-bucket>/*"
with:
"Resource": ["arn:aws:s3:::<my-bucket>", "arn:aws:s3:::<my-bucket>/*",]
and:
"Principal": {"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity <mine>"},
with:
"Principal": {"AWS": "arn:aws:iam::ACCOUNT_ID:user/USERNAME"},