S3 Cross account Replication with KMS
Tags: aws, s3, crossaccount, s3replication
Published: 2022-07-07 14:28:22


This post describes how can we replicate objects to a bucket owned by a different AWS account? What if the objects are encrypted? 

This article discusses a method to configure replication for S3 objects from a bucket in one AWS account to a bucket in another AWS account, using server-side encryption using Key Management Service (KMS).
**Setup Requirements **

_**Two AWS accounts:**_ We need two AWS accounts with their account IDs.  

_Source and destination buckets:_ We need an S3 bucket in the source account where the objects are created/uploaded and an S3 bucket in the destination account to store the replicated objects.  

_Source and destination KMS keys:_ We need KMS keys created in both source and destination accounts.  

- Some of the requirements for configuring replication are: 
- Both source and destination buckets must have versioning enabled. 
- S3 service must be allowed permissions to replicate objects from the source bucket to the destination bucket on your behalf. 

Let’s refer to the source AWS account as account A and the destination AWS account as account B. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rnm71gtynezrbfl4pvfz.jpeg)
 

**Configuration needed on account A:**

**1.** Create AssumeRole and allow S3 service 

`{ 
   "Version": "2012-10-17", 
   "Statement": [ 
     { 
       "Action": "sts:AssumeRole", 
       "Principal": { 
         "Service": "s3.amazonaws.com" 
       }, 
       "Effect": "Allow", 
       "Sid": "VisualEditor0" 
     } 
   ] 
 } `



**2.**
Create IAM policy allowing KMS keys to encrypt and decrypt

`{ 
   "Version": "2012-10-17", 
   "Statement": [ 
     { 
       "Action": [ 
         "s3:ListBucket", 
         "s3:GetReplicationConfiguration", 
         "s3:GetObjectVersionForReplication", 
         "s3:GetObjectVersionAcl", 
         "s3:GetObjectVersionTagging", 
         "s3:GetObjectVersion", 
         "s3:ObjectOwnerOverrideToBucketOwner" 
       ], 
       "Effect": "Allow", 
       "Resource": [ 
         "<accountA-S3-Bucket-ARN>", 
         "<accountA-S3-Bucket-ARN>/*" 
       ] 
     }, 
     { 
       "Action": [ 
         "s3:ReplicateObject", 
         "s3:ReplicateDelete", 
         "s3:ReplicateTags", 
         "s3:GetObjectVersionTagging", 
         "s3:ObjectOwnerOverrideToBucketOwner" 
       ], 
       "Effect": "Allow", 
       "Resource": "<accountB-S3-Bucket-ARN>/*" 
     }, 
     { 
       "Action": [ 
         "kms:Decrypt" 
       ], 
       "Effect": "Allow", 
       "Resource": "<accountA-KMS-Key-ARN>" 
     }, 
     { 
       "Action": [ 
         "kms:Encrypt" 
       ], 
       "Effect": "Allow", 
       "Resource": "<accountB-KMS-Key-ARN>" 
     } 
   ] 
 } `


**3.**
Set up replication configuration on S3 bucket and add replication rule through AWS console UI or IAC.

**Configuration needed on account B:**


1. Configure KMS key policy to allow S3 service to encrypt data in accountB bucket during replication 

`{ 
   "Version": "2012-10-17", 
   "Statement": [ 
     { 
       "Sid": "VisualEditor0", 
       "Effect": "Allow", 
       "Principal": { 
         "AWS": [ 
           "<accountA-IAM-Role-ARN>" 
         ] 
       }, 
       "Action": [ 
         "kms:Encrypt", 
         "kms:ReEncrypt*", 
         "kms:GenerateDataKey*", 
         "kms:DescribeKey" 
       ], 
       "Resource": [ 
         "*" 
       ] 
     }, 
     { 
       "Effect": "Allow", 
       "Principal": { 
         "AWS": [ 
           "arn:aws:iam::<accountB-AWS-AccountID>:root" 
         ] 
       }, 
       "Action": [ 
         "kms:*" 
       ], 
       "Resource": [ 
         "*" 
       ] 
     } 
   ] 
 } `


**2.**Configure S3 bucket policy to grant accountA permissions to perform replication actions
 

`{ 
   "Version": "2012-10-17", 
   "Statement": [ 
     { 
       "Sid": "VisualEditor0", 
       "Effect": "Allow", 
       "Principal": { 
         "AWS": [ 
           "arn:aws:iam::<accountA-AWS-AccountID>:root" 
         ] 
       }, 
       "Action": [ 
         "s3:GetBucketVersioning", 
         "s3:PutBucketVersioning", 
         "s3:ReplicateObject", 
         "s3:ObjectOwnerOverrideToBucketOwner" 
       ], 
       "Resource": [ 
         "<accountB-S3-Bucket-ARN>", 
         "<accountB-S3-Bucket-ARN>/*" 
       ] 
     } 
   ] 
 }` 

This way, the objects can be replicated across different accounts.