问题描述
我使用我的 AWS KMS CMK 来加密和 AWS SecretsManager Secret,但我的同事可以看到密钥值!!
- 我的 KMS CMK 政策规定我只能执行
kms:Decrypt
。 - 我的同事(在我的 CMK 上没有这些权限)能够...
- 打开 AWS 控制台到 SecretsManager >>>
- 点击
Retrieve Secret Value
>>> - 看看我的秘密价值!
知道为什么吗?
技术细节:
我正在使用 AWS SAM CLI 来部署它。
这是我的 AWS SAM 模板:
AWstemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Parameters:
SecretValue:
Type: String
KmsCmkId:
Type: String
Resources:
MySecret:
Type: AWS::SecretsManager::Secret
Properties:
SecretString:
Ref: SecretValue
KmsKeyId: !Ref KmsCmkId
我用这个构建和部署它:
sam build ; sam deploy --guided --parameter-overrides SecretValue=ABC KmsCmkId=REDACTED
我迄今为止的调试:
-
我搜索了
serverfault.com
,但基本上没有结果。我搜索了 Stack Overflow 只找到了一篇帖子,似乎是相关的,但问题没有阐明,解决方案不是我的情况:AWS KMS CMK encrypt and decrypt with symmetric and asymmetric -
我正在使用 对称 CMK,因为 SecretsManager 需要它。 (SecretsManager 不允许使用非对称 CMK 来加密秘密值。
-
我确认单击 AWS SecretsManager 控制台中的
Retrieve Secret Value
按钮确实执行了带有secretsmanager:GetSecretValue
的 API 调用。 -
AWS 表示
secretsmanager:GetSecretValue
应该只在调用方也在用于加密密钥的 CMK 上具有kms:Decrypt
时才有效(这是有道理的)。 (见https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html) -
我确认我的对称 KMS CMK 确实是用于加密密钥的 CMK。
-
我的同事没有以 root 帐户登录 AWS。他以自己的帐户登录。他碰巧拥有大量权限,因为他是管理员,但我认为没有理由允许他使用我的 CMK。
-
注意:注意不要将
kms:Get*
操作与secretsmanager:Get*
操作混淆。 -
这是我的 KMS CMK 的政策:
{
"Id": "key-consolepolicy-3","Version": "2012-10-17","Statement": [
{
"Sid": "Enable IAM User Permissions","Effect": "Allow","Principal": {
"AWS": "arn:aws:iam::REDACTED:root"
},"Action": "kms:*","Resource": "*"
},{
"Sid": "Allow access for Key Administrators","Principal": {
"AWS": [
"arn:aws:iam::REDACTED:user/MY_COWORKER"
]
},"Action": [
"kms:Create*","kms:Describe*","kms:Enable*","kms:List*","kms:Put*","kms:Update*","kms:Revoke*","kms:disable*","kms:Get*","kms:Delete*","kms:TagResource","kms:UntagResource","kms:ScheduleKeyDeletion","kms:CancelKeyDeletion"
],{
"Sid": "Allow use of the key","Principal": {
"AWS": "arn:aws:iam::REDACTED:user/ME"
},"Action": [
"kms:Encrypt","kms:Decrypt","kms:ReEncrypt*","kms:GenerateDataKey*","kms:DescribeKey"
],{
"Sid": "Allow attachment of persistent resources","Action": [
"kms:CreateGrant","kms:ListGrants","kms:RevokeGrant"
],"Resource": "*","Condition": {
"Bool": {
"kms:GrantIsForAWSResource": "true"
}
}
}
]
}
解决方法
非常感谢@JohnRotenstein 为我指明了正确的方向,并在上面回答了我的问题!
解决方案背景 1
正如约翰所问的那样,当我在上面说我的同事在我们的账户上“是管理员”时,我的意思是他的 IAM 用户账户具有 AWS 托管策略 Administrator Access
,可以“完全访问”(据我所知)AWS 中的所有内容或几乎所有内容(包括 KMS !!)。
解决方案背景 2
确实,在我上面的问题中,我的密钥策略(这是默认的密钥策略)包含以下声明:
{
"Sid": "Enable IAM User Permissions","Effect": "Allow","Principal": {
"AWS": "arn:aws:iam::REDACTED:root"
},"Action": "kms:*","Resource": "*"
},
根据 @JohnRotenstein 的评论和 these AWS docs,此政策声明允许 IAM 政策访问和使用此密钥 - 如果这些政策指定了正确的权限。
因此(据我所知),这将允许相当多的人(任何可以在我公司账户上编辑 IAM 策略的人)能够给自己一个策略,允许他们对我的账户做任何他们想做的事情KMS钥匙! (这不安全!)
我需要解决这个问题。 (下面的解决方案!)
解决方案背景 3
在“默认 KMS 密钥策略”(我在上面的问题中发布)中,您会看到密钥管理员可以kms:Put*
。允许他们kms:PutKeyPolicy
,这将允许他们更改策略以给自己(或任何人)kms:Decrypt
,这将允许他们解密我的 Secrets Manager 秘密并获得秘密价值!
我也需要压制这个......
解决方案
关键政策如下:
-
确保仅我的 Lambda 函数可以(通过我提供给执行 Lambda 函数的 IAM 角色的策略声明)使用 IAM 策略来使用此密钥,并且他们可以只做
kms:Decrypt
-
只允许关键用户(我)进行加密和解密操作(当然,Lambda 函数除外;见上文)
-
虽然密钥管理员不能使用我的密钥来加密或解密事物(或
kms:PutKeyPolicy
),但他们可以执行所有管理任务,例如删除 KMS 密钥或其授权。
{
"Id": "mount-houlis-secure-kms-key-policy","Version": "2012-10-17","Statement": [
{
"Sid": "Allow use of the key","Principal": {
"AWS": THE_ARN_OF_THE_IAM_USER_WHO_OWNS_THE_SECRET____WHICH_IS_ME
},"Action": [
"kms:Encrypt","kms:Decrypt","kms:ReEncrypt*","kms:GenerateDataKey*","kms:DescribeKey","kms:GetKeyPolicy","kms:PutKeyPolicy"
],"Resource": "*"
},{
"Sid": "Admins","Principal": {
"AWS": [
ARNS_OF_VARIOUS,KEY_ADMINISTRATORS,AND_ME
]
},"Action": [
"kms:CancelKeyDeletion","kms:CreateAlias","kms:DeleteAlias","kms:DisableKey","kms:DisableKeyRotation","kms:EnableKey","kms:EnableKeyRotation","kms:GetKeyRotationStatus","kms:ListGrants","kms:ListKeyPolicies","kms:ListResourceTags","kms:ListRetirableGrants","kms:RetireGrant","kms:RevokeGrant","kms:ScheduleKeyDeletion","kms:TagResource","kms:UntagResource","kms:UpdateAlias","kms:UpdateKeyDescription"
],{
"Sid": "Allow Lambda function to do Action secretsmanager:GetSecretValue","Principal": {
"AWS": ARN_OF_THE_ROLE_THAT_YOUR_LAMBDA_FUNCTION_EXECUTES_AS____SHOULD_BE_arn:aws:iam::ACCOUNT_NUMBER:role/your-lambda-function-role-name
},"Action": "kms:Decrypt","Resource": "*"
}
]
}