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?
There are two ways to control access to your KMS keys:
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