KMS keys should not be publicly accessible
Checks whether a customer managed KMS key's policy lets everyone ("*") use the key with no condition that pins the caller and no Deny that closes it; such a key is open to any AWS account. A pass does not mean the key is unshared: grants and named external accounts are not read.
- service
- KMS
- severity
- Critical
- scope
- evaluated in every region
How to fix it
- Overwrites existing settings: The CLI and Terraform routes replace the whole key policy, so start from the current policy rather than sending only the statements you changed.
- Can't be undone: Keep the statement giving your own account access: if every principal the policy names is later deleted, only AWS Support can restore access to the key.
- Can break clients: Callers that relied on the open statement are refused as soon as the policy is saved, so name every account and role that still needs the key first.
In the console
Key Management Service → Customer managed keys → the key → Key policy
- Principal
- Named accounts, roles or users; not "*" or {"AWS": "*"} in an Allow, and no Allow with NotPrincipal
- Condition
- Keep "*" only with a fixed kms:CallerAccount, aws:PrincipalOrgID or aws:SourceVpce; aws:SourceIp never counts
With the AWS CLI
aws kms put-key-policy --key-id <key-id> --policy file://key-policy.json --region <region>With Terraform
resource "aws_kms_key_policy" "this" {
key_id = var.key_id
policy = data.aws_iam_policy_document.no_public_access.json
}
See which of your accounts this check is failing on.
Book a live scan