3

我有一个账户 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 的数据

关注这篇文章:https ://docs.aws.amazon.com/kms/latest/developerguide/key-policy-modifying.html#key-policy-modifying-external-accounts

  • 修改账户 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 的角色。

任何指针表示赞赏。

4

0 回答 0