3
votes

I am trying to put a text file from Lambda which is in Account B to S3 bucket in account A. S3 bucket(test-bucket) is having AWS-KMS encryption with aws/s3 Managed Key enabled. 1. I added below permissions in Account A- S3 bucket (test-bucket):

   ```
    {"Version": "2012-10-17",
         "Id": "ExamplePolicy",
         "Statement": [
             {
                 "Sid": "ExampleStmt",
                 "Effect": "Allow",
                 "Principal": {
                     "AWS": "arn:aws:iam::AccountB:role/Lambda-Role"
                 },
                 "Action": "s3:*",
                 "Resource": "arn:aws:s3:::test-bucket/*"
             }
         ]
        }
  1. Added below inline policy to my Lambda execution role in Account B:
    {"Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "VisualEditor0",
                "Effect": "Allow",
                "Action": [
                    "kms:Decrypt",
                    "kms:Encrypt",
                    "kms:GenerateDataKey",
                    "kms:DescribeKey",
                    "kms:ReEncrypt*"
                ],
                "Resource": [
                    "arn:aws:kms:us-west-2:AccountA:key/AWS-KMS-ID"
                ]
            }
        ]
    }
    

This is my Lambda Code:

    res = s3.put_object(
                    Body=message,
                    Key=file_name,
                    Bucket='test-bucket',
                    ACL='bucket-owner-full-control'
                )
    

Getting below error while running this code from Account B Lambda:

    An error occurred (AccessDenied) when calling the PutObject operation: Access Denied

Since the S3 bucket is encrypted by AWS Managed Key so I cannot edit the KMS policy what we do in case of Customer Managed Key.

Someone please guide me what am I missing.

3
I suspect that the IAM Role used by Lambda-B does not have permission to use the KMS Key associated with Bucket-A. The Lambda Role you have shown (#2) is in Account-B, but Account-B cannot grant permission on resources in Account-A. I wonder whether you can add permissions to the KMS Key itself to allow the IAM Role in Account-B to use it? - John Rotenstein
@JohnRotenstein Yes..we can add permission to the KMS key itself but that's possible if its a Customer Managed Key. In my case S3 bucket is KMS encrypted with AWS Managed key(aws/s3) which of not have option of edit. - AWS_Developer
@JohnRotenstein Any suggestions? - AWS_Developer
Frankly, I don't think it would be possible because key access would be required, but that can only be granted to an entity in the same account. It is possible that the Lambda function in Account-B would need to assume an IAM Role from Account-A so that it can be granted permission to use KMS for that bucket. - John Rotenstein

3 Answers

1
votes

Try granting your lambda function s3:PutObject action permission. So the inline policy of your lambda role should be something like

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "VisualEditor0",
      "Effect": "Allow",
      "Action": [
        "kms:Decrypt",
        "kms:Encrypt",
        "kms:GenerateDataKey",
        "kms:DescribeKey",
        "kms:ReEncrypt*"
      ],
      "Resource": [
        "arn:aws:kms:us-west-2:AccountA:key/AWS-KMS-ID"
      ]
    },
    {
      "Effect": "Allow",
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::test-bucket/*"
    }
  ]
}
1
votes

I've been troubleshooting this for a couple of hours myself.

I don't believe this is possible with the default "AWS Managed Key" when using SSE-KMS. Instead you have to create a CMK and grant the cross account user access to this key.

HTH

0
votes

Cross account access cannot be granted for AWS Managed Key. Need to use customer managed key or default encryption.

This can be useful- https://aws.amazon.com/premiumsupport/knowledge-center/s3-bucket-access-default-encryption/