I have an account A, which has a DynamoDB Table with the contents encrypted using a KMS key, also in account A.
I want to give access to account B so that it is able to read DynamoDB data and decrypt it using the same KMS key.
First Step: DynamoDB Access Across Accounts
I used this article: https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_cross-account-with-roles.html.
- Created a Role in Account A which specifies Account B's IAM user as the trusted entity
- Created an IAM User in Account B which has AssumeRole policy to access the role in Account A
- For the code that runs in the context of Account B, created DynamoDBMapper which uses the STSAssumeRoleSessionCredentialsProvider for assuming the role
AWSSecurityTokenService stsClient =
AWSSecurityTokenServiceClient.builder()
.withCredentials(awsCredentialsProvider)
.withRegion(dynamoRegion)
.build();
STSAssumeRoleSessionCredentialsProvider arscp =
new STSAssumeRoleSessionCredentialsProvider.Builder(accessRole, accessRoleName)
.withStsClient(stsClient)
.build();
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard()
.withRegion(dynamoRegion)
.withCredentials(arscp)
.build();
This works!
Second Step: Using KMS to Encrypt/Decrypt Data (not cross-account)
Used the aws-dynamodb-encryption-java library for that. While creating DynamoDBMapper, pass in the AttributeEncryptor derived from KMS Material Provider:
AWSKMS kms = AWSKMSClientBuilder.standard()
.withRegion(region)
.withCredentials(awsCredentialsProvider)
.build();
EncryptionMaterialsProvider encryptionProvider = new DirectKmsMaterialProvider(kms, keyId);
return new DynamoDBMapper(client, dynamoDBMapperConfig, new AttributeEncryptor(encryptionProvider));
This also works!
Third Step: Allowing Account B to decrypt data from DynamoDB
Followed this article: https://docs.aws.amazon.com/kms/latest/developerguide/key-policy-modifying.html#key-policy-modifying-external-accounts
- Modified the Key policy in Account A to give access to root of Account B
- Created an IAM policy in Account B to have the appropriate permissions to be able to access the KMS key in Account A.
From code perspective, I am using the same code as in second step to create the AWSKMS instance, albeit with the IAM policy created in Step 3. I get the following error:
com.amazonaws.services.kms.model.NotFoundException: Key 'arn:aws:kms:us-east-1:<Account B>:key/<KMS Key Id>' does not exist
Why is trying to look for the key in Account B? Is it because I need to Assume Role to access the KMS key as well? But the documentation doesn't speak about that. Also, I have not created any IAM Policy in Account B to assume role for KMS.
Any pointers appreciated.