The title says it all. I am getting this error whenever I try to create a KMS key via an AWS CloudFormation template. I am creating the template as an IAM user with administrative permissions, and I want the key to be manageable by any IAM user in the same AWS account with KMS permissions. I am using the following YAML resource definition for the key:
LambdaKmsKey:
Type: AWS::KMS::Key
Properties:
Enabled: true
KeyPolicy:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: kms:*
Principal:
AWS: <Principle>
And yet, NONE of the following values for <Principal>
are working, even if I try to create the stack as the root user!
!Join [ "", [ "arn:aws:iam::", !Ref "AWS::AccountId", ":root" ] ]
!Join [ "", [ "arn:aws:sts::", !Ref "AWS::AccountId", ":root" ] ]
!Ref "AWS::AccountId"
I can't just hardcode my user name for the Principal because I want this template to be instantiable by anyone with stack creation permissions. Does anyone know how to resolve this enormously frustrating situation? Thanks in advance.
EDIT:
I should mention that I no longer define KMS Key policies in CloudFormation Templates. In fact, I now avoid defining any security resources in my CF Templates at all, such as IAM entities, policies, and ACM certificates. My reasons for this are described in this GitHub issue.
Using the AWS Management Console policy viewIn the Key Policy section, choose Switch to policy view. Edit the key policy document, and then choose Save changes.
You cannot edit any properties of AWS managed keys or AWS owned keys. These keys are managed by the AWS services that created them. You can change the description of your customer managed key on the details page for the KMS key or by using the UpdateKeyDescription operation.
You can use this condition key to allow or deny access to all identities (IAM users and roles) in an AWS account. In key policies, you use the Principal element to specify the identities to which the policy statement applies.
A key policy is a resource policy for an AWS KMS key. Key policies are the primary way to control access to KMS keys. Every KMS key must have exactly one key policy. The statements in the key policy determine who has permission to use the KMS key and how they can use it.
You are missing the Resource: "*"
attribute. This worked for me:
LambdaKmsKey:
Type: AWS::KMS::Key
Properties:
Enabled: true
KeyPolicy:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: kms:*
Resource: "*"
Principal:
AWS: !Join [ "", [ "arn:aws:iam::", !Ref "AWS::AccountId", ":root" ] ]
The Resource: "*"
is required and is the only possible value:
Resource – (Required) In a key policy, you use "*" for the resource, which means "this CMK." A key policy applies only to the CMK it is attached to.
See https://aws.amazon.com/premiumsupport/knowledge-center/update-key-policy-future/ for an example.
In case this helps someone, be aware of the remark in https://aws.amazon.com/premiumsupport/knowledge-center/update-key-policy-future/
Important: Be sure that the key policy that you create allows the current user to administer the CMK.
I was having this issue while deploying my template from a pipeline and the proposed solutions did not work for me. The role used to deploy the template had the corresponding kms permissions, but it needed to be also in the principal of a the key policy!
- Effect: Allow
Action: kms:*
Resource: "*"
Principal:
AWS:
- !Sub arn:aws:iam::${AWS::AccountId}:role/PipelineRole
LambdaKmsKey:
Type: AWS::KMS::Key
Properties:
Description: Key for Lambda function
Enabled: True
KeyPolicy:
Version: '2012-10-17'
Id: key-consolepolicy-3
Statement:
- Sid: Enable IAM User Permissions
Effect: Allow
Principal:
AWS: arn:aws:iam::AwsAccountId:root
Action: kms:*
Resource: "*"
- Sid: Allow use of the key
Effect: Allow
Principal:
AWS:
Fn::GetAtt: [ IamRoleLambdaExecution, Arn ]
Action:
- kms:Decrypt
- kms:Encrypt
Resource: "*"
This policy is bit dangerous because it gives any user or role under the account with kms:decrypt permission to decrypt and view the key, which is not safe and it fails pen testing.
If you want to take away permission to decrypt.
LambdaKmsKey:
Type: AWS::KMS::Key
Properties:
Description: Key for Lambda function
Enabled: True
KeyPolicy:
Version: '2012-10-17'
Id: key-consolepolicy-3
Statement:
- Sid: Enable IAM User Permissions
Effect: Allow
Principal:
AWS: arn:aws:iam::AwsAccountId:role/sudo
Action:
- kms:Create*
- kms:Describe*
- kms:Enable*
- kms:List*
- kms:Put*
- kmzs:Update*
- kms:Revoke*
- kms:Disable*
- kms:Get*
- kms:Delete*
- kms:ScheduleKeyDeletion
- kms:CancelKeyDeletion
- kms:Encrypt
Resource: "*"
- Sid: Enable IAM User Permissions
Effect: Allow
Principal:
AWS: arn:aws:iam::AwsAccountId:role/admin
Action:
- kms:Create*
- kms:Describe*
- kms:Enable*
- kms:List*
- kms:Put*
- kmzs:Update*
- kms:Revoke*
- kms:Disable*
- kms:Get*
- kms:Delete*
- kms:ScheduleKeyDeletion
- kms:CancelKeyDeletion
- kms:Encrypt
Resource: "*"
- Sid: Enable IAM User Permissions
Effect: Allow
Principal:
AWS: arn:aws:iam::AwsAccountId:root
Action:
- kms:List*
- kms:Get*
- kms:Encrypt
Resource: "*"
- Sid: Allow use of the key
Effect: Allow
Principal:
AWS:
Fn::GetAtt: [ IamRoleLambdaExecution, Arn ]
Action:
- kms:Decrypt
- kms:Encrypt
Resource: "*"
This way I am giving all other permission except decrypt to sudo and admin roles(Make sure you have those roles present)
and I am giving list, get and encrypt permission to roles and users that has list, get and encrypt permissions.
I got the same error when I tried creating CMK through lambda. So I add the lambda role arn in key policy while creating the key.
{
"Sid": "Allow access for Key Administrators",
"Effect": "Allow",
"Principal": {
"AWS": "arn of lambda role"
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With