Search code examples
amazon-web-servicesaws-cloudformationamazon-ecsamazon-kms

AWS KMS key cannot be used by ECS container because access is denied


Initial state: I would like to decrypt values using KMS key inside ECS container. In order to do this TaskDefinition has ExecutionRoleArn which references the following role RoleECSTaskContainer. The setup of the role and KMS key looks like this:

    KMSKeyEncryption:
        Type: AWS::KMS::Key
        Properties:
          Enabled: true
          EnableKeyRotation: false
          KeyPolicy:
            Version: 2012-10-17
            Statement:
              - Principal:           
                  AWS:arn of the users/roles who are allowed to manage this key
                Effect: Allow
                Action:
                  - kms:Create*
                  - kms:Describe*
                  - kms:Enable*
                  - kms:List*
                  - kms:Put*
                  - kms:Update*
                  - kms:Revoke*
                  - kms:Disable*
                  - kms:Get*
                  - kms:Delete*
                  - kms:ScheduleKeyDeletion
                  - kms:CancelKeyDeletion
                  - kms:Encrypt*
                  - kms:Decrypt*
                Resource: "*"
              - Principal:
                  AWS: ecs-tasks.amazonaws.com
                Effect: Allow
                Action:
                  - kms:Decrypt*
                Resource: "*"
      PolicyDecryptKms:
        Type: AWS::IAM::ManagedPolicy
        Properties:
          ManagedPolicyName: DecryptKmsPolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Sid: AllowDecryptValues
                Effect: Allow
                Action:
                  - kms:Decrypt*
                Resource: !GetAtt KMSKeyEncryption.Arn
      RoleECSTaskContainer:
        Type: AWS::IAM::Role
        Properties:
          AssumeRolePolicyDocument:
            Version: 2008-10-17
            Statement:
              - Effect: Allow
                Principal:
                  Service: ecs-tasks.amazonaws.com
                Action: sts:AssumeRole
          RoleName: ECSTaskContainerRole
          ManagedPolicyArns:
            - !Ref PolicyDecryptKms

When the container is trying to decrypt values using KMS key it gets the following exception:

User: arn:aws:sts::123123123:assumed-role/ECSTaskContainerRole/bc9a5782-9sf8-312a-8z76-0ef29a6e5631 is not authorized to perform: kms:Decrypt on resource: arn:aws:kms:eu-west-1:123123123:key/8c9h2f44-bjvb-4l2d-fkj11-fjdahjEr564182

After some investigation, I found out that it starts working if I change a bit the key policy to allow all principals to decrypt like this:

Principal: "*"
Effect: Allow
Action:
  - kms:Decrypt*
Resource: "*"

But this is not a safe way to define key policy because I am allowing everyone to decrypt values using this KMS key.

I assume that I am wrong using ecs-tasks.amazonaws.com as principal. Is this correct? If so which service should I use in this case?


Solution

  • There are two ways to control access to your KMS keys:

    1. By using the key policy - which lets you define access control in a single policy.
    2. By using IAM policies in combination with the key policy - controlling access this way enables you to manage all of the permissions for your IAM identities in IAM.

    You can use the key policy alone to control access. However, IAM policies by themselves are not sufficient to allow access to a CMK. You must give an AWS account full access to the CMK to enable IAM policies.

    {
      "Sid": "Enable IAM User Permissions",
      "Effect": "Allow",
      "Principal": {"AWS": "arn:aws:iam::111122223333:root"},
      "Action": "kms:*",
      "Resource": "*"
    }
    

    So it depends how you would like to manage your policies. I usually prefer KMS key policies for simplicity. So I'd just set the key policy to grant kms:decrypt permission to the role and remove the managed IAM policy.

    KMSKeyEncryption:
      Type: AWS::KMS::Key
      Properties:
        KeyPolicy:
          Version: 2012-10-17
          Statement:
          ...
             - Principal:
                 AWS: !GetAtt RoleECSTaskContainer.Arn
               Effect: Allow
               Action:
                 - kms:Decrypt*
               Resource: "*"
    
    RoleECSTaskContainer:
      Type: AWS::IAM::Role
      Properties:
        AssumeRolePolicyDocument:
          Version: 2008-10-17
          Statement:
            - Effect: Allow
              Principal:
                Service: ecs-tasks.amazonaws.com
              Action: sts:AssumeRole
        RoleName: ECSTaskContainerRole