amazon-web-servicesamazon-s3replication

S3 Cross-Region Replication Not Working Despite Valid IAM Role and Bucket Policies


I'm attempting to configure cross-region replication between two S3 buckets in different AWS accounts and regions, but replication is not occurring. There are no relevant errors in CloudTrail or visible issues in the replication status metrics.

IAM Role Trust Policy (Account A)

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "s3.amazonaws.com"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "aws:SourceAccount": "ACCOUNT_A_ID"
        },
        "ArnLike": {
          "aws:SourceArn": "arn:aws:s3:::source-bucket-name"
        }
      }
    },
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "s3.amazonaws.com"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "aws:SourceAccount": "ACCOUNT_B_ID"
        },
        "ArnLike": {
          "aws:SourceArn": "arn:aws:s3:::destination-bucket-name"
        }
      }
    }
  ]
}

IAM Role Inline Policy (Account A)

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "s3:GetObject",
        "s3:GetObjectVersion",
        "s3:GetObjectVersionAcl",
        "s3:GetObjectVersionTagging",
        "s3:GetObjectRetention",
        "s3:GetObjectLegalHold",
        "s3:ListBucket"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::source-bucket-name",
        "arn:aws:s3:::source-bucket-name/*"
      ]
    },
    {
      "Action": [
        "s3:ReplicateObject",
        "s3:ReplicateDelete",
        "s3:ReplicateTags"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::destination-bucket-name",
        "arn:aws:s3:::destination-bucket-name/*"
      ]
    },
    {
      "Action": [
        "kms:Decrypt",
        "kms:ReEncryptFrom"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:kms:us-east-1:ACCOUNT_A_ID:key/source-kms-key-id"
    },
    {
      "Action": [
        "kms:Encrypt",
        "kms:ReEncryptTo"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:kms:us-west-2:ACCOUNT_B_ID:key/destination-kms-key-id"
    }
  ]
}

Source Bucket Policy (Account A)

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyInsecureTransport",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::source-bucket-name",
        "arn:aws:s3:::source-bucket-name/*"
      ],
      "Condition": {
        "Bool": {
          "aws:SecureTransport": "false"
        }
      }
    },
    {
      "Sid": "AllowReplicationRoleAccess",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::ACCOUNT_A_ID:role/replication-role-name"
      },
      "Action": [
        "s3:GetObjectVersion",
        "s3:GetObjectVersionAcl",
        "s3:GetObjectVersionTagging",
        "s3:ListBucket",
        "s3:GetReplicationConfiguration"
      ],
      "Resource": [
        "arn:aws:s3:::source-bucket-name",
        "arn:aws:s3:::source-bucket-name/*"
      ]
    }
  ]
}

Destination Bucket Policy (Account B)

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowReplicationFromSourceAccount",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::ACCOUNT_A_ID:root"
      },
      "Action": [
        "s3:ReplicateObject",
        "s3:ReplicateDelete",
        "s3:ReplicateTags",
        "s3:ObjectOwnerOverrideToBucketOwner"
      ],
      "Resource": [
        "arn:aws:s3:::destination-bucket-name",
        "arn:aws:s3:::destination-bucket-name/*"
      ]
    }
  ]
}

What I’ve Verified The IAM role is correctly referenced in the replication configuration

KMS permissions are present for both encryption and decryption in both regions

s3:GetObjectRetention and s3:GetObjectLegalHold permissions are granted due to Object Lock

Both buckets are versioned and have replication enabled in the S3 console

No Deny statements are interfering other than the expected secure transport rule

Despite all this, no objects are replicating and no errors are visible. Has anyone encountered a similar issue or can spot anything I’m missing?

Edit: I also forgot to mention that the replication configuration uses the destination KMS key (or attempts to)

Thanks!


Solution

  • Replication between buckets belonging to different AWS Accounts would require:

    Therefore, a few things to note:

    I'd recommend focussing on KMS permissions, since they are likely to cause the most problems.

    I notice that Replicating encrypted objects (SSE-S3, SSE-KMS, DSSE-KMS, SSE-C) - Amazon Simple Storage Service says:

    Amazon S3 doesn't replicate objects that are encrypted with SSE-KMS

    This is likely because KMS keys are stored in Accounts and your use-case involves replicating objects between Accounts. It would not be a good idea for Account B to rely on KMS keys from Account A for encrypting objects. If possible, rely on SSE-S3 that is now enabled by default. If you do require SSE-KMS, review the recommended configuration settings carefully.

    You could also temporarily remove the Deny policy to ensure that it is not causing the problem.

    If problems persists, see Receiving replication failure events with Amazon S3 Event Notifications - Amazon Simple Storage Service to obtain information about failed replication activities.