Why bucket policy is used? - amazon-s3

I have a question about s3 bucket access, it's so complecated for me.
my configuration for s3 bucket is "public access is denied"
when I don't specify any policy in s3 bucket policy and give a user predefined S3 readonly permission, I can bring list of buckets and list of object in buckets.
But when I only make bucket policy for the user who has no iam policy attached to list buckets and object. the user are not able to list buckets and objects.
If it is true, why bucket policy is necessary to use?
bucket policy I made is like this.
{
"Version": "2012-10-17",
"Id": "Policy1672363253371",
"Statement": [
{
"Sid": "Stmt16",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::2040:user/viewer"
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::test-bucket"
}
{
"Sid": "Stmt17",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::2040:user/viewer"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::test-bucket/*"
}
]
}

Related

S3 Bucket Policy to work with CloudFront GetObject and PutObject directly to the bucket using Multer-S3

I am trying to make a S3 bucket policy that only allows GetObject from CloudFront but able to PutObject directly to the bucket.
Tried with several combinations but none of the worked.
Here is the latest attempt that I tried.
With, Block All Public Access: ALL OFF.
Bucket Policy:
{
"Version": "2012-10-17",
"Id": "Policy1604429581591",
"Statement": [
{
"Sid": "Stmt1605554261786",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::MYBUCKET/*"
},
{
"Sid": "Stmt1605557746418",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::MYBUCKET/*"
},
{
"Sid": "Stmt1605557857544",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:MYCLOUDFRONT"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::MYBUCKET/*"
}
]
}
This allows me to PutObject to the bucket but GetObject using CloudFront URL got access denied. If I removed
{
"Sid": "Stmt1605557746418",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::MYBUCKET/*"
}
I can GetObject from CloudFront as well as from bucket directly.
Please help!
Found the solution of it.
First follow the instructions here to setup CloudFront: https://aws.amazon.com/premiumsupport/knowledge-center/cloudfront-access-to-amazon-s3/. Key point is
5. For Restrict Bucket Access, select Yes.
I was using Multer-S3 to upload my image files. ACL needs to be set to
acl: 'authenticated-read',
Also I am using serverSideEncryption, in S3 bucket properties=>Default encryption
Default encryption: Enabled
Server-side encryption: Amazon S3 master-key(SSE-S3)
Multer-S3 config
serverSideEncryption: 'AES256',
S3 Bucket permission un-Block all public access and ACL only enables Bucket Owner's permissions.
The final bucket policy I have is:
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E36AHAEXL422P3"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::MYBUCKET/*"
},
{
"Sid": "Stmt1605745908405",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::MYBUCKET/*",
"Condition": {
"StringEqualsIfExists": {
"s3:x-amz-server-side-encryption": "AES256"
}
}
}
]
}
With all above configurations, this allows PubObject from anyone as long as requests have server side encryption with 'AE256'. GetObject requests directly to the bucket will be blocked. All GetObject requests need to go through CloudFront.

Cannot upload to s3 bucket with public access blocked

I'm trying to upload to an s3 bucket which works fine if I set Block all public access: Off. However, with it on and the following bucket policy I get an access denied message
{
"Version": "2012-10-17",
"Id": "Policy1594969692377",
"Statement": [
{
"Sid": "Stmt1594969687722",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::066788420637:user/transloadit2"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::bucketname"
}
]
}
I thought that enabling/disabling public access just allowed rules to be created to then make the bucket public? I don't understand why it is blocking my upload when it is disabled.
Many thanks,
Matt
It appears that you wish to grant permission for a specific IAM User to upload to an Amazon S3 bucket.
For this, instead of creating a bucket policy you should add a policy to the IAM User themselves, such as:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
]
}
]
}
Note: This policy is granting too many permissions, including permission to delete the bucket and all its contents. I recommend that you limit it to the specific API calls desired (eg PutObject, GetObject).
Basically:
If you wish to grant access to one user, put the policy on the IAM User
If you wish to grant access to 'everybody', use a bucket policy
Permissions granted to the IAM User are not impacted by S3 Block Public Access.
You use the bucket itself as a resource. If you want to do operations over objects (put, get etc.), you need to put objects path to the resource. So, in your case, you should update your policy like this:
{
"Version": "2012-10-17",
"Id": "Policy1594969692377",
"Statement": [
{
"Sid": "Stmt1594969687722",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::066788420637:user/transloadit2"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::bucketname",
"arn:aws:s3:::bucketname/*"
]
}
]
}

What should be bucket policy for a S3 that is owned by Coudfront OAI set but allow other AWS account to upload s3 objects

I have S3 that has restricted policy to serve private content. Only Cloudfront Origin Access Identity can access. But, other account should be allowed to upload new objects so that client can get new assets. What kind of policy should be set for this situation?
Currently my policy is like this
{
"Sid": "1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity SomeID12334"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket/*"
}
You can add multiple statements in your bucket policy to handle the permissions.
Provide the role ARN from another account to provide the access to do specific actions on bucket.
{
"Sid": "1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity SomeID12334"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket/*"
},
{
"Sid": "Stmt1570159952662",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<accountno>:role/rolename"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-bucket"
}

IAM bucket policy to allow cross-account Lambda function to write to S3

I'm having a tough time figuring out how to make this work. Our client runs a Lambda function to generate data to write to our bucket. Lambda assumes a role and because of that (I think) all our attempts to allow the client's entire account access to the bucket still result in an AccessDenied error.
In looking at our logs I see the AccessDenied is returned for the STS assumed-role. However, S3 console won't allow me to add a policy for a wildcard Principal, and the assumed role's session ID changes each session.
My guess from the sparse documentation is that we need to provide a trust relationship to the lambda.amazonaws.com service. But I can't find any documentation anywhere on how to limit that to just access from a specific Lambda function or account.
I would like to have something like this but with further constraints on the Principal so that it's not accessible by any account or Lambda function.
{
"Version": "2012-10-17",
"Id": "Policy11111111111111",
"Statement": [
{
"Sid": "Stmt11111111111111",
"Effect": "Allow",
"Principal": {
"Service": [
"lambda.amazonaws.com"
]
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::bucket-name-here/*",
"arn:aws:s3:::bucket-name-here"
]
}
]
}
UPDATE
This policy doesn't even work. It still returns an AccessDenied. The user listed in the logs is in the form of arn:aws:sts::111111222222:assumed-role/role-name/awslambda_333_201512111822444444.
So at the point I'm at a loss as to how to even allow a Lambda function to write to an S3 bucket.
We resolved this eventually with help from the IAM team.
IAM roles do not inherit any permission from the account so they need permissions assigned explicitly to the assumed role for the Lambda script.
In our case the Lambda script was also trying to grant the destination bucket owner full control of the copied file. The role assumed by the Lambda function was missing permissions for s3:PutObjectAcl.
After we added the permission the lambda function began working correctly.
The destination policy that we have working now is something like this:
{
"Version": "2012-10-17",
"Id": "Policy11111111111111",
"Statement": [
{
"Sid": "Stmt11111111111111",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:ListBucket*",
"Resource": "arn:aws:s3:::bucket-name",
"Condition": {
"StringLike": {
"aws:userid": "ACCOUNT-ID:awslambda_*"
}
}
},
{
"Sid": "Stmt11111111111111",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::bucket-name/*",
"Condition": {
"StringLike": {
"aws:userid": "ACCOUNT-ID:awslambda_*"
}
}
},
{
"Sid": "Stmt11111111111111",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::0000000000000:root"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::bucket-name"
},
{
"Sid": "Stmt11111111111111",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::0000000000000:root"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::bucket-name/*"
}
]
}
To Allow Cross account lambda function to get access of s3 bucket
following policy we need to add to s3 bucket policy externally
{
"Sid": "AWSLambda",
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com",
"AWS": "arn:aws:iam::<AccountID>:root"
},
"Action": "s3:GetObject",
"Resource": "<AWS_S3_Bucket_ARN>/*"
}
Following Template will help you to allow cross account Lambda function to access s3 bucket
Parameters:
LamdaAccountId:
Description: AccountId to which allow access
Type: String
Resources:
myBucket:
Type: 'AWS::S3::Bucket'
Properties: {}
Metadata:
'AWS::CloudFormation::Designer':
id: e5eb9fcf-5fe2-468c-ad54-b9b41ba1926a
myPolicy:
Type: 'AWS::S3::BucketPolicy'
Properties:
Bucket: !Ref myBucket
PolicyDocument:
Version: 2012-10-17
Statement:
- Sid: Stmt1580304800238
Action: 's3:*'
Effect: Allow
Resource:
- !Sub 'arn:aws:s3:::${myBucket}/*'
Principal:
Service: lambda.amazonaws.com
AWS:
- !Sub '${LamdaAccountId}'

Why Doesn't My AWS S3 Bucket Policy Override My IAM Policy?

I have a user in my IAM account called "testuser" who has administrator privileges, like so:
{
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
]
}
And then I have a policy on my S3 bucket that denies this user access, like so:
{
"Statement": [
{
"Effect": "Deny",
"Principal": {
"AWS": "my-account-id:user/testuser"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-bucket-name/*"
}
]
}
So, the explicit deny in the S3 bucket policy should override the allow from the IAM policy right? But when I log in as testuser, I still have access to everything in that bucket - I even have access to change or remove the bucket policy for that bucket (and every other bucket too). Why isn't my explicit deny doing anything?
Try using the full ARN form for the user ID in the bucket policy:
"Principal": {
"AWS":["arn:aws:iam::accountid:user/testuser"]
}