The new key policy will not allow you to update the key policy in the future

12,387

Solution 1

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.

Solution 2

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 

Solution 3

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.

Solution 4

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"
   }
}
Share:
12,387
Rabadash8820
Author by

Rabadash8820

The first thing I learned to program was my TI-84 calculator. Now I can program other things.

Updated on June 05, 2022

Comments

  • Rabadash8820
    Rabadash8820 almost 2 years

    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.

  • Rabadash8820
    Rabadash8820 about 7 years
    omg I would've been staring at that for days! You're right, Resource: "*" was all I needed. I think its ridiculous that you have to include a Resource line in resource-based policies, when you don't have to put a Principal line in user policies... but ah well, thanks for the quick answer!
  • prime
    prime almost 6 years
    Do we need all kms permissions ? (i.e why Action: kms:* ? )
  • Rabadash8820
    Rabadash8820 almost 6 years
    @prime You do not need all kms permissions. As with any IAM policy, you can specify as many or as few actions as you need. The link in @spg's answer actually provides an example of a key policy with more specific Action permissions.
  • scubbo
    scubbo almost 5 years
    Hmm - this didn't work for me, I'm still getting the same error.
  • vladimirror
    vladimirror over 2 years
    This went over my head / somehow I didn't realize this was my case as well by reading your solution. The "current user" means the user that creates the KMS key must have an access to the key + any other users you want. In terraform this is the user used to create terraform resources, possibly the root user.
  • AronNeewart
    AronNeewart almost 2 years
    Even though defining a user as "admins" in the kms.Key CDK gives plenty of actions it was still not enough. Action: kms:* + Resource: "*" made the trick for me. This kinda seems like a bug.