使用别名访问 KMS 加密的 Bucket

问题描述

假设我有一个用 KMS 密钥加密的存储桶,KMS 密钥策略是这样的

session_tokens

我的 IAM 角色的政策是

    {
      "Effect" : "Allow","Principal" : {
        "AWS" : "arn:aws:iam:::my_role_here"
      },"Action" : [
        "kms:Encrypt","kms:Decrypt","kms:ReEncrypt*","kms:GenerateDataKey*","kms:DescribeKey"
      ],"Resource" : "arn:aws:kms:::long_kms_id","Condition": {
         "StringLike": {
            "kms:RequestAlias": "alias/my_kms_alias"
            }
       } 
    }

但是,当我执行 PUT 操作时,我收到拒绝访问的消息: { "Sid": "AllowUSEOfKmsKey","Effect": "Allow","Action": [ "kms:Decrypt","kms:DescribeKey","kms:Encrypt","kms:ReEncrypt*" ],"Resource": "*","Condition": { "StringLike": { "kms:RequestAlias": "alias/my_kms_alias" } } } 。但是,如果我删除 IAM 角色策略中的 An error occurred (AccessDenied) when calling the PutObject operation: Access Denied,这会起作用。

我一直在关注此 doc,但似乎没有任何工作或解释清楚。如果我给它一个 KMS 别名,我如何确保我想要访问我的 S3 存储桶的角色能够访问它?

解决方法

正如@Marcin 指出的,您不需要同时拥有密钥策略和角色策略。
如果你想把这个key用在另一个账号上,那么最好在Key上有这个策略。

正如您提供的文档所解释的那样,当您使用 kms:RequestAlias 时,请求用户确实需要明确使用别名。

请参阅下面的示例。我的密钥策略允许我帐户中的所有内容。

{
    "Version": "2012-10-17","Id": "key-default-1","Statement": [
        {
            "Sid": "Enable IAM User Permissions","Effect": "Allow","Principal": {
                "AWS": "arn:aws:iam::123412341234:root"
            },"Action": "kms:*","Resource": "*"
        }
    ]
}

但是我的角色没有任何允许使用这个键的语句,所以它会失败。

$ aws s3api put-object --bucket mybucket --key key1 --body ./test.txt --ssekms-key-id arn:aws:kms:us-east-1:123412341234:key/66053e20-c9e6-4df9-901a-c6aed5e51ea5 --server-side-encryption "aws:kms" --region us-east-1

An error occurred (AccessDenied) when calling the PutObject operation: Access Denied

我将以下政策添加到我的角色中。

{
    "Version": "2012-10-17","Statement": [
        {
            "Effect": "Allow","Action": [
                "kms:Decrypt","kms:GenerateDataKey*","kms:DescribeKey"
            ],"Resource": "*","Condition": {
                "StringLike": {
                    "kms:RequestAlias": "alias/test-leo"
                }
            }
        }
    ]
}

现在我将强制使用我的密钥(不是别名)。它也会失败,因为我没有使用别名,我使用的是 Key。

$ aws s3api put-object --bucket mybucket --key key2 --body ./test.txt --ssekms-key-id arn:aws:kms:us-east-1:123412341234:key/66053e20-c9e6-4df9-901a-c6aed5e51ea5 --server-side-encryption "aws:kms" --region us-east-1

An error occurred (AccessDenied) when calling the PutObject operation: Access Denied

当您查看 CloudTrail 时,您会看到如下所示的错误跟踪:

"eventTime": "2021-05-26T13:42:24Z","eventSource": "kms.amazonaws.com","eventName": "GenerateDataKey","awsRegion": "us-east-1","sourceIPAddress": "AWS Internal","userAgent": "AWS Internal","errorCode": "AccessDenied","errorMessage": "User: arn:aws:sts::123412341234:assumed-role/myrole/i-12adc5581f1a9b9dd is not authorized to perform: kms:GenerateDataKey on resource: arn:aws:kms:us-east-1:123412341234:key/66053e20-c9e6-4df9-901a-c6aed5e51ea5",

现在我将强制使用我的密钥别名(不是密钥 ARN)。之所以有效,是因为我在命令中使用了密钥别名 ARN。

$ aws s3api put-object --bucket mybucket --key key3 --body ./test.txt --ssekms-key-id arn:aws:kms:us-east-1:123412341234:alias/test-leo --server-side-encryption "aws:kms" --region us-east-1
{
    "SSEKMSKeyId": "arn:aws:kms:us-east-1:123412341234:key/66053e20-c9e6-4df9-901a-c6aed5e51ea5","ETag": "\"ab544583c58d325231bb7b11e8472a1b\"","ServerSideEncryption": "aws:kms"
}