首页 > 解决方案 > 使用别名访问 KMS 加密存储桶

问题描述

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

    {
      "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"
            }
       } 
    }

我的 IAM 角色的政策是

        {
            "Sid": "AllowUseOfKmsKey",
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt",
                "kms:DescribeKey",
                "kms:Encrypt",
                "kms:GenerateDataKey*",
                "kms:ReEncrypt*"
            ],
            "Resource": "*",
            "Condition": {
                "StringLike": {
                    "kms:RequestAlias": "alias/my_kms_alias"
                }
            }
        }

但是,当我执行 PUT 操作时,我得到一个 access denied: An error occurred (AccessDenied) when calling the PutObject operation: Access Denied。但是,如果我删除ConditionIAM 角色策略,则此方法有效。

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

标签: amazon-web-servicesdevopsamazon-kms

解决方案


正如@Marcin 指出的那样,您不需要同时拥有密钥策略和角色策略。
如果您想将此密钥用于另一个帐户,那么最好有关于密钥的策略。

正如您提供的文档所解释的,当您使用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"
}

推荐阅读