AWS Security Hub · KMS
KMS.1: IAM policies should not allow decrypt on all KMS keys
Written and reviewed by Emnode · Last reviewed
What does AWS Security Hub KMS.1 check?
KMS.1 fails when the default version of a customer-managed IAM policy (attached or unattached) allows kms:Decrypt or kms:ReEncryptFrom on a wildcard Resource. It checks managed policies specifically and ignores conditions and inline policies.
Why does KMS.1 matter?
A managed policy with decrypt on "*" lets every principal it's attached to decrypt data under any key, including, in a multi-tenant system, other tenants' data. Such grants slip through reviews because reviewers focus on the actions, not the Resource. One DataPipelineRole that only ever touched two keys carried Decrypt on "*" through three reviews; scoping it to the two real ARNs took eight minutes.
How do I fix KMS.1?
- List customer-managed policies and read each document for kms:Decrypt or kms:ReEncryptFrom with Resource: "*".
- Identify the keys each principal actually uses.
- Rewrite the Resource element to the specific key ARNs and verify nothing breaks.
- Note KMS.1 only evaluates the policy's default version; bump and clean up old versions too.
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.1 a false positive?
The control reads only the Resource element and explicitly ignores the Condition block, so a managed policy that grants kms:Decrypt on Resource "*" but tightly constrains it with conditions (kms:ViaService to bind use to one service, aws:PrincipalOrgID, or an encryption-context match) fails KMS.1 even though the effective access is properly scoped. This is a genuine pattern: when the exact key ARNs aren't known at authoring time (keys created per-tenant, or cross-account keys you can't enumerate), a wildcard Resource plus a sharp Condition is the documented way to express least privilege. If the conditions truly bound the grant, suppress the finding with a note pointing to the constraining condition keys rather than swapping in an ARN list you'd have to keep chasing, but confirm the conditions actually narrow access, since the control gives no credit for them either way.