How can I prevent IAM policies from allowing a user or role to access a KMS key in AWS KMS?

Last updated: 2023-01-26

I want to secure my AWS Key Management Service (AWS KMS) KMS key from access by AWS Identity and Access Management (IAM) identities. However, the default KMS key policy allows IAM identities in the account to access the KMS key with IAM permissions.

Short description

The default KMS key policy contains the following statement:

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

In the preceding example, the Effect and Principal elements don't refer to the AWS root user account. The Amazon Resource Names (ARN) allows permissions to the KMS key with this IAM policy. If you attach the required permissions to the IAM entity, then any principal in the AWS account 111122223333 has root access to the KMS key.

Resolution

You can prevent IAM entities from accessing the KMS key and allow the root user account to manage the key. This also prevents the root user account from losing access to the KMS key.

Replace the Sid "Enable IAM User Permissions" in the default KMS key policy with the Sid "EnableRootAccessAndPreventPermissionDelegation". Also, add a Condition element similar to the one in the following policy:

Important: Replace the account 111122223333 with your account number, and be sure that the condition key aws:PrincipalType is set to Account.

{
    "Sid": "EnableRootAccessAndPreventPermissionDelegation",
    "Effect": "Allow",
    "Principal": {
        "AWS": "arn:aws:iam::111122223333:root"
    },
    "Action": "kms:*",
    "Resource": "*",
    "Condition": {
        "StringEquals": {
            "aws:PrincipalType": "Account"
        }
    }
}

You can add key administrator IAM users or roles to allow managing the key in the statement with Sid "Allow access for Key Administrators". You can also allow IAM users or roles to use the key for cryptographic operations and with other AWS services. Add the IAM user or role ARNs to the statements with the Sid “Allow use of the key” and “Allow attachment of persistent resources”.

Note: You must create the key with the modified policy with the root user account. Or, use a principal that’s allowed in the statement “Allow access for Key Administrators”. This prevents the "MalformedPolicyDocumentException" policy error.

The modified default KMS key policy is similar to the following:

{
    "Id": "key-consolepolicy-1",
    "Version": "2012-10-17",
    "Statement":
    [
        {
            "Sid": "EnableRootAccessAndPreventPermissionDelegation",
            "Effect": "Allow",
            "Principal":
            {
                "AWS": "arn:aws:iam::111122223333:root"
            },
            "Action": "kms:*",
            "Resource": "*",
            "Condition":
            {
                "StringEquals":
                {
                    "aws:PrincipalType": "Account"
                }
            }
        },
        {
            "Sid": "Allow access for Key Administrators",
            "Effect": "Allow",
            "Principal":
            {
                "AWS":
                [
                    "arn:aws:iam::111122223333:user/KMSAdminUser",
                    "arn:aws:iam::111122223333:role/KMSAdminRole"
                ]
            },
            "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"
            ],
            "Resource": "*"
        },
        {
            "Sid": "Allow use of the key",
            "Effect": "Allow",
            "Principal":
            {
                "AWS":
                [
                    "arn:aws:iam::111122223333:user/ExampleUser",
                    "arn:aws:iam::111122223333:role/ExampleRole"
                ]
            },
            "Action":
            [
                "kms:Encrypt",
                "kms:Decrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "kms:DescribeKey"
            ],
            "Resource": "*"
        },
        {
            "Sid": "Allow attachment of persistent resources",
            "Effect": "Allow",
            "Principal":
            {
                "AWS":
                [
                    "arn:aws:iam::111122223333:user/ExampleUser",
                    "arn:aws:iam::111122223333:role/ExampleRole"
                ]
            },
            "Action":
            [
                "kms:CreateGrant",
                "kms:ListGrants",
                "kms:RevokeGrant"
            ],
            "Resource": "*",
            "Condition":
            {
                "Bool":
                {
                    "kms:GrantIsForAWSResource": "true"
                }
            }
        }
    ]
}

The key policy allows the following permissions:

  • The AWS root user account full access to the key.
  • The principals KMSAdminUser and KMSAdminRole to perform management operations on the key.
  • The principals ExampleUser and ExampleRole to use the key.

Did this article help?


Do you need billing or technical support?