Skip to main content
emnode
Compliance Critical severity

AWS Security Hub · KMS

KMS.5: A KMS key policy allows public access

Written and reviewed by Emnode · Last reviewed

What does AWS Security Hub KMS.5 check?

KMS.5 fails when a KMS key policy allows public access, for example a statement with Principal "*" that is not constrained by conditions, letting any AWS principal use the key.

Why does KMS.5 matter?

A publicly accessible KMS key undermines encryption entirely: if outsiders can call Decrypt or re-encrypt with your key, the data it protects is no longer confidential, and key usage can be abused. Key policies are the primary access control for KMS, so a wildcard there is a direct path to your encrypted data.

How do I fix KMS.5?

  1. Edit the key policy and remove or tightly scope any Principal "*" statements.
  2. Restrict key use to specific accounts/roles, adding conditions like kms:ViaService or aws:PrincipalOrgID where appropriate.
  3. Use IAM Access Analyzer for KMS to confirm no external principal retains access.

Remediation script · bash

# Stop the irreversible clock first: cancel any scheduled deletion, then re-enable.
for k in $(aws kms list-keys --query 'Keys[].KeyId' --output text); do
  state=$(aws kms describe-key --key-id "$k" \
    --query 'KeyMetadata.KeyState' --output text)
  if [ "$state" = "PendingDeletion" ]; then
    aws kms cancel-key-deletion --key-id "$k"
    aws kms enable-key --key-id "$k"   # cancel leaves it Disabled
    echo "$k: deletion cancelled and re-enabled"
  fi
done

# Turn rotation on for eligible customer-managed symmetric keys.
for k in $(aws kms list-keys --query 'Keys[].KeyId' --output text); do
  read -r mgr spec <<<"$(aws kms describe-key --key-id "$k" \
    --query 'KeyMetadata.[KeyManager,KeySpec]' --output text)"
  if [ "$mgr" = "CUSTOMER" ] && [ "$spec" = "SYMMETRIC_DEFAULT" ]; then
    aws kms enable-key-rotation --key-id "$k"
  fi
done

Full walkthrough (console steps, edge cases and verification) in the lesson Manage KMS encryption keys.

Is KMS.5 a false positive?

KMS.5 returns FAILED in two cases that aren't real public exposure. First, if AWS Config can't read the key policy (because an SCP, RCP, or the key policy itself blocks the Config role's kms:GetKeyPolicy call), the control fails for want of data, not because the key is open; the fix is to restore the Config role's read access, not to touch the key policy. Second, the control doesn't evaluate conditions that use wildcards or policy variables, so a key whose Principal "*" statement is genuinely constrained by such a condition still fails because the constraint is treated as if it weren't there. Confirm which case you're in: rewrite the condition to fixed values where you can, and where you can't, suppress with a note recording why the access is in fact restricted rather than loosening a key that is already safe.

Part of the learning path Lock down access
  • KMS.1 IAM policies should not allow decrypt on all KMS keys
  • KMS.2 Decrypt is granted on all KMS keys
  • KMS.3 A KMS key is scheduled for deletion and will take data with it
  • KMS.4 KMS key rotation should be enabled