what permission do I need to copy object between two buckets in two different accounts? - amazon-web-services

I am using javascript SDK and a lambda function to copy a file from a source account to the current account where my lambda lives. I'm assuming a role for cross account access to the source account S3 bucket before I call copyObject api. But I'm getting Access Denied! Here is my cross account role:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::sourceBucket/*"
]
}
]
}
and here is my lambda permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::destinationbucket/*",
"Effect": "Allow"
},
{
"Action": [
"sts:*"
],
"Resource": "*",
"Effect": "Allow"
}
]
}
I think when I assume the cross account role I give up the lambda permissions and then I cannot copy file to the destination. Any help is much appreciated.

You appear to have:
A source bucket (Bucket-A) in Account-A
A destination bucket (Bucket-B) in Account-B
An AWS Lambda function in Account-B
An IAM Role (Role-A) in Account-A that the Lambda function can assume
Your requirement is to have the Lambda function copy objects from Bucket-A to Bucket-B.
When using the CopyObject command, the credentials must have:
Read permissions on Bucket-A
Write permissions on Bucket-B
However, while Role-A does have read permissions on Bucket-A, it does not have permission to write to Bucket-B.
Therefore, you have two choices:
Option 1: Add a Bucket Policy to Bucket-B that grants write permissions to Role-A, or
Option 2: Instead of using Role-A, the administrator of Bucket-A in Account-A can grant read permissions for Bucket-A to the IAM Role being used by the Lambda function by creating a Bucket Policy on Bucket-A . That is, the Lambda function does not assume Role-A. It just uses its own role to read directly from Bucket-A.
Option 2 is better, because it is involves less moving parts. That is, there is no need to assume a role. I suggest you try this method before using the AssumeRole method.
If you do wish to continue with using Role-A, then please note that the CopyObject() command will need to set the ACL to bucket-owner-full-control. If this is not done, the Account-B will not have permission to access/delete the copied objects. (If you use the second method, then the objects will be copied using Account-B credentials, so it is not required.)
Bottom line: For your describe scenario involving Role-A, add a Bucket Policy to Bucket-B that grants write permissions to Role-A.

Related

IAM Access Key permissions override an Explicit Deny in an IAM role?

I have an EC2 instance with a role with the following policy applied:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Deny",
"Action": [
"s3:PutObject"
],
"Resource": "*"
}
]
}
With just the role applied, it works as expected - I can view the bucket contents but can't copy objects to the bucket.
However, if I then add access keys for an IAM user with the AmazonS3FullAccess policy, the instance is able to copy objects to the bucket.
How is this allowed? My understanding is that any explicit deny in any of the associated policies is final.
This happens because hard coded credentials have higher priority then instance profile. Subsequently, your deny is not even considered in your scenario.
It would be better to put such deny in bucket policy, not instance role.

how I grant s3 bucket access with this particular role?

I've looked at some other solutions for similar questions, but here's the twist: I was given this and asked to grant s3 bucket for another account to put/get objects:
arn:aws:iam::[account number]:role/CustomerManaged/XMO-Custom-SPEG-DPM-Share-Role
I know the basics of how to change bucket policies in the JSON format. Do I need to create the JSON from this in the s3 bucket policy, or do I add this in IAM? I have seven tabs open for AWS doc pages but am getting lost in the weeds of what to do here.
In account B, which needs to access account A's bucket, set up an IAM role that includes the relevant permissions (e.g. s3:GetObject on s3://bucketa/prefix/*). For example:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::bucketa/prefix/*"
}
]
}
In account A, which owns the bucket, add an S3 bucket policy to bucketa that gives the relevant permissions to the account B role. For example:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::accountb:role/rolename"
},
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::bucketa/prefix/*"
]
}
]
}
Finally, in account B, given the relevant IAM users or roles permission to assume the account B role so that they can get cross-account access to the bucket.
Alternatively, rather then delegate permissions directly to an IAM role in account B, account A can set a principal of "AWS": "arn:aws:iam::accountb:root" in the bucket policy and this will allow account B administrators to delegate permission as they choose (see example).
For more, see How can I provide cross-account access to objects that are in Amazon S3 buckets?
It appears that your requirement is:
An IAM Role (Role-A) in Account-A wants to access...
An Amazon S3 Bucket (Bucket-B) in Account-B
You are an Administrator in Account-B
The simplest way to permit such access is to add a Bucket Policy to Bucket-B:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::ACCOUNT-A:role/CustomerManaged/XMO-Custom-SPEG-DPM-Share-Role"
},
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::bucket-name/*"
]
}
]
}
This policy says:
Allow the given IAM Role
Permission to put/get objects
In this bucket
There is no need to assume roles. Simply adding this bucket policy on Bucket-B allows Role-A to access the bucket.
Oh, and Role-A also needs to be granted sufficient S3 permissions to access the bucket, which might be via generic permissions (eg s3:GetObject on a Principal of *), or it could be specific to this bucket. Basically, Account-A has to grant it permission (via IAM), AND Account-B has to grant it permission (via the bucket policy).

aws s3 upload fail only at production envrionment, but success at local environment

I tried to upload image using aws-sdk, multer-s3.
In my local environment, uploading image was succeed, but in production environment(aws lambda), it fail with error status 403 forbidden.
But my aws credential key and secret-key is same as local environment. also i checked aws key in production environment successfully.
I think difference between two other environment is nothing.What am I missing?
I have even tried setting aws key in my router code like below, but it also failed.
AWS.config.accessKeyId = 'blabla';
AWS.config.secretAccessKey = 'blalbla';
AWS.config.region = 'ap-northeast-2';
and here is my policy
{
"Id": "Policy1536755128154",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1536755126539",
"Action": [
"s3:DeleteObject",
"s3:GetObject",
"s3:PutObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::elebooks-image/*",
"Principal": "*"
}
]
}
Update your attached s3 bucket policy to a user according to below policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation",
"s3:ListAllMyBuckets"
],
"Resource": "arn:aws:s3:::*"
},
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::YOUR-BUCKET",
"arn:aws:s3:::YOUR-BUCKET/*"
]
}
]
}
it's working on my server.
I haven't worked with AWS Lambda but I am familiar with S3. When you're using the AWS SDK in your local environment, you're probably using the root user with default full access, so it will just work.
With Lambda however, according to the following extract from the documentation, you need to make sure that the IAM role you specified when you created the Lambda function has the appropriate permissions to do an s3:putObject to that bucket.
Permissions for your Lambda function – Regardless of what invokes a Lambda function, AWS Lambda executes the function by assuming the IAM role (execution role) that you specify at the time you create the Lambda function. Using the permissions policy associated with this role, you grant your Lambda function the permissions that it needs. For example, if your Lambda function needs to read an object, you grant permissions for the relevant Amazon S3 actions in the permissions policy. For more information, see Manage Permissions: Using an IAM Role (Execution Role).
See Writing IAM policies: How to grant access to an S3 bucket

AWS S3 bucket access control

In AWS, I (joe.doe#accountXYZ) created a S3 bucket, thus I am this s3 bucket owner.
I want to configure this S3 bucket based on the IAM role, thus only some IAM roles, such as [role_xyz, role_abc, role_cde], can can read this bucket.
From the AWS console, it seems that I can not configure it.
Can anyone tell me whether it is possible to do that?
========
I understand that from the IAM role side you can configure a policy for this s3 resource. But my question here is on the s3 resource side, whether I can define a access policy based IAM roles.
It appears that your requirement is to permit certain specific roles access to a particular Amazon S3 bucket.
There are two ways to do this:
Option 1: Add permissions to the Role
This is the preferred option. You can add a policy to the IAM Role that grants access to the bucket. It would look similar to:
{
"Id": "Policy1",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Action": "s3:*",
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::mybucket",
"arn:aws:s3:::mybucket/*"
]
}
]
}
This is a good method because you just add the policy to the desired Role(s), without having to touch the actual buckets.
Option 2: Add a Bucket Policy
This involves putting the permissions on the bucket, which grants access to a specific role. This is less desirable because you would have to put the policy on every bucket and refer to every Role.
It would look something like:
{
"Id": "Policy1",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Action": "s3:*",
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::mybucket",
"arn:aws:s3:::my-bucket/*"
],
"Principal": "arn:aws:iam::123456789012:role/my-role"
}
]
}
Please note that these policies are granting s3:* permissions on the bucket, that might be too wide for your purposes. It is always best to only grant the specific, required permissions rather than granting all permissions.

Why aws lambda function is not able do read object from s3 bucket?

I am trying to read objects from S3 bucket using lambda function cross account, I have added resource based policy for aws lambda to access s3 bucket.
But still when i tested my lambda function am seeing access denied error
lambda function IAM role has the full access on s3 resources
Your situation appears to be:
An AWS Lambda function in Account A that is using a Role
An Amazon S3 bucket in Account B
You will need to grant access from Account B. The Lambda resource policy will not work because it is in Account A (and therefore cannot grant access to resources in Account B).
You simply need a Bucket Policy on the bucket that grants access to the Role being used by the Lambda function. The policy would look similar to:
{
"Id": "Policy1",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "GrantAccessToRole",
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::my-bucket/*",
"Principal": {
"AWS": [
"arn:aws:iam::1234567890:role/my-role"
]
}
}
]
}
Modify the policy to provide the access permissions desired (eg ListBucket).
The ARN for the role is visible in the IAM console when viewing the Role.