Provisioning AWS KMS-Encrypted Buckets with Cross Account Access

Overview of Activities Required for each Account

Activities for account-a

Activities for account-b

Prerequisites: AWS CLI Credentials for Admin Tasks

[profile account-a-admin]
region = <region>
aws_access_key_id = <access key id of account-a admin user>
aws_secret_access_key = <aws secret key for account-a admin user>
[profile account-b-admin]
region = <region>
aws_access_key_id = <access key id of account-b admin user>
aws_secret_access_key = <aws secret key for account-b admin user>

Executing Activities Required for account-a

{
"Version": "2012-10-17",
"Id": "key-policy-account-a-bucket",
"Statement": [
{
"Sid": "Enable IAM user permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::account-a:root"
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allow use of the key",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::account-b:root"
},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "*"
}
]
}
$ aws --profile account-a-admin \
create-key \
--tags TagKey=Purpose,TagValue=AWS-KMS-Key \
--description "Key used for s3://account-a-bucket encryption" \
--key-usage "ENCRYPT_DECRYPT" \
--policy '{
"Version": "2012-10-17",
"Id": "key-policy-account-a-bucket",
"Statement": [
{
"Sid": "Enable IAM user permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::account-a:root"
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allow use of the key",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::account-b:root"
},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "*"
}
]
}'
{
"KeyMetadata": {
"AWSAccountId": "account-a",
"KeyId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"Arn": "arn:aws:kms:<region>:account-a:key/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",

"CreationDate": "2021-04-06T18:21:45+10:00",
"Enabled": true,
"Description": "Key used for s3://account-a-bucket bucket encryption",
"KeyUsage": "ENCRYPT_DECRYPT",
"KeyState": "Enabled",
"Origin": "AWS_KMS",
"KeyManager": "CUSTOMER",
"CustomerMasterKeySpec": "SYMMETRIC_DEFAULT",
"EncryptionAlgorithms": [
"SYMMETRIC_DEFAULT"
]
}
}
$ aws --profile account-a-admin \
kms create-alias \
--alias-name alias/s3-account-a-bucket-encryption \
--target-key-id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
$ aws --profile account-a-admin \
s3 mb s3://account-a-bucket
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::account-b:root"
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::account-a-bucket"
},
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::account-b:root"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::account-a-bucket/*"
},
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::account-b:root"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::account-a-bucket/*"
}
]
}
$ aws --profile account-a-admin \
s3api put-bucket-policy \
--bucket account-a-bucket \
--policy '{ \
"Version": "2012-10-17", \
"Statement": [ \
{ \
"Effect": "Allow", \
"Principal": { \
"AWS": "arn:aws:iam::account-b:root" \
}, \
"Action": "s3:ListBucket", \
"Resource": "arn:aws:s3:::account-a-bucket" \
}, \
{ \
"Effect": "Allow", \
"Principal": { \
"AWS": "arn:aws:iam::account-b:root" \
}, \
"Action": "s3:GetObject", \
"Resource": "arn:aws:s3:::account-a-bucket/*" \
}, \
{ \
"Effect": "Allow", \
"Principal": { \
"AWS": "arn:aws:iam::account-b:root" \
}, \
"Action": "s3:PutObject", \
"Resource": "arn:aws:s3:::account-a-bucket/*" \
} \
] \
}'
$ aws --profile account-a-admin \
s3api put-bucket-encryption \
--bucket account-a-bucket \
--server-side-encryption-configuration '{
"Rules": [
{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "aws:kms",
"KMSMasterKeyID": "arn:aws:kms:<region>:account-a:key/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
},
"BucketKeyEnabled": true
}
]
}'
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListBucketContents",
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::account-a-bucket",
]
},
{
"Sid": "UploadDownloadBucketPermissions",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject""
],
"Resource": [
"arn:aws:s3:::account-a-bucket/*"
]
},
{
"Sid": "EncryptDecryptBucketContents",
"Effect": "Allow",
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": [
"arn:aws:kms:<region>:account-a:key/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
]
}
]
}
$ aws --profile account-a-admin \
iam put-user-policy \
--user-name ann \
--policy-name access-s3-account-a-bucket \
--policy-document file://access-s3-account-a-bucket.json

Executing Activities Required for account-b

$ aws --profile account-b-admin \
iam put-user-policy \
--user-name dilip \
--policy-name access-s3-account-a-bucket \
--policy-document file://access-s3-account-a-bucket.json

Conclusion

--

--

Learner. Interests include Cloud and Devops technologies.

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store