我有一个账户 A,它有一个 DynamoDB 表,其中的内容使用 KMS 密钥加密,也在账户 A 中。
我想授予对账户 B 的访问权限,以便它能够读取 DynamoDB 数据并使用相同的 KMS 密钥对其进行解密。
第一步:跨账户访问 DynamoDB
我使用了这篇文章:https ://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_cross-account-with-roles.html 。
- 在账户 A 中创建了一个角色,将账户 B 的 IAM 用户指定为可信实体
- 在账户 B 中创建了一个 IAM 用户,该用户具有 AssumeRole 策略来访问账户 A 中的角色
- 对于在账户 B 的上下文中运行的代码,创建了 DynamoDBMapper,它使用 STSAssumeRoleSessionCredentialsProvider 来承担角色
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();
这行得通!
第二步:使用KMS加密/解密数据(非跨账户)
为此使用了aws-dynamodb-encryption-java库。在创建 DynamoDBMapper 时,传入从 KMS Material Provider 派生的 AttributeEncryptor:
AWSKMS kms = AWSKMSClientBuilder.standard()
.withRegion(region)
.withCredentials(awsCredentialsProvider)
.build();
EncryptionMaterialsProvider encryptionProvider = new DirectKmsMaterialProvider(kms, keyId);
return new DynamoDBMapper(client, dynamoDBMapperConfig, new AttributeEncryptor(encryptionProvider));
这也有效!
第三步:允许账户 B 解密来自 DynamoDB 的数据
- 修改账户 A 中的密钥策略以授予账户 B 的根访问权限
- 在账户 B 中创建了一个 IAM 策略,以拥有能够访问账户 A 中的 KMS 密钥的适当权限。
从代码的角度来看,我使用与第二步相同的代码来创建 AWSKMS 实例,尽管使用的是在第 3 步中创建的 IAM 策略。我收到以下错误:
com.amazonaws.services.kms.model.NotFoundException: Key 'arn:aws:kms:us-east-1:<Account B>:key/<KMS Key Id>' does not exist
为什么要在账户 B 中查找密钥?是因为我还需要 Assume Role 才能访问 KMS 密钥吗?但是文档没有提到这一点。此外,我还没有在账户 B 中创建任何 IAM 策略来承担 KMS 的角色。
任何指针表示赞赏。