S3 Bucket: Cross Account Resource Sharing with Encryption
S3 buckets are object storage solutions on AWS. There are instances in this project, where data has been extracted in a particular AWS bucket under a certain AWS account and it makes no sense to extract the same data again in a different account. It is expensive and time-consuming. Also, there are other dedicated resources created for such extraction which is expensive and hard to manage.
To solve this problem, the application team wants to share the data in S3 across AWS accounts.
Challenges:
- Buckets are encrypted and the encryption key is located in the account of the bucket.
S3 Bucket (digital-HelloWorld-private) is in Account A. It has default encryption enabled with key a KMS key on the same account. Account B wants to access data from the S3 bucket. It has an instance profile/Role applied to the EC2 (s3-test).
Step 1: Allow the s3-test role to access the bucket with the necessary action in the bucket’s policy.
{
"Version": "2012-10-17",
"Id": "Policy1579885418491",
"Statement": [
{
"Sid": "crossAccountAccess",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<ACCOUNT-B-ID>:role/s3-test"
},
"Action": [
"s3:ListBucket",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::digital-helloworld-private/*",
"arn:aws:s3:::digital-helloworld-private"
]
},
{
"Sid": "DenyIncorrectEncryptionHeader",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::digital-helloworld-private/*",
"Condition": {
"StringNotEquals": {
"s3:x-amz-server-side-encryption": "aws:kms"
}
}
},
{
"Sid": "DenyUnEncryptedObjectUploads",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::digital-helloworld-private/*",
"Condition": {
"Null": {
"s3:x-amz-server-side-encryption": "true"
}
}
}
]
}
Step 2: Edit the access on the KMS key and give access to the S3-test role.
{
"Version": "2012-10-17",
"Id": "key-consolepolicy-3",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<ACCOUNT-A-ID>:root"
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allow access for Key Administrators",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<ACCOUNT-A-ID>:user/awsCLI"
},
"Action": [
"kms:Create*",
"kms:Describe*",
"kms:Enable*",
"kms:List*",
"kms:Put*",
"kms:Update*",
"kms:Revoke*",
"kms:Disable*",
"kms:Get*",
"kms:Delete*",
"kms:TagResource",
"kms:UntagResource",
"kms:ScheduleKeyDeletion",
"kms:CancelKeyDeletion"
],
"Resource": "*"
},
{
"Sid": "Allow use of the key",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::<ACCOUNT-B-ID>:role/s3-test",
"arn:aws:iam::<ACCOUNT-A-ID>:user/awsCLI"
]
},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "*"
},
{
"Sid": "Allow attachment of persistent resources",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<ACCOUNT-A-ID>:user/awsCLI"
},
"Action": [
"kms:CreateGrant",
"kms:ListGrants",
"kms:RevokeGrant"
],
"Resource": "*",
"Condition": {
"Bool": {
"kms:GrantIsForAWSResource": "true"
}
}
}
]
}
This will enable the EC2 machine is Account B to do the action permitted by the s3 bucket policy.