Back to Checks
Cloud KMS key does not grant access to allUsers or allAuthenticatedUsers
kms_key_not_publicly_accessible
Service: kmsSeverity: critical
OfficialBuilt-inVerified
Categories:internet-exposedidentity-access
Resource Type:AwsKmsKey
KMS keys are assessed for excessive access in key policies or grants, including * principals and broadly scoped permissions to multiple identities.
Risk
Broad access to a KMS key enables unauthorized kms:Decrypt and data-key generation, breaking confidentiality. With admin rights, attackers can change policies or schedule deletion, undermining control integrity and threatening availability of data dependent on the key.
Run this check with Prowler
Run in Prowler CloudRun
prowler aws --checks kms_key_not_publicly_accessibleRecommendation
Apply least privilege to KMS keys:
- Restrict principals to specific roles and accounts
- Prefer narrow, time-bound grants
- Separate key administration from usage
- Use conditions to limit context
- Review regularly and remove wildcard or cross-account exposure
Remediation
CLI
aws kms put-key-policy --key-id <example_resource_id> --policy-name default --policy '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"arn:aws:iam::<account_id>:root"},"Action":"kms:\*","Resource":"\*"}]}'Terraform
# Restrict KMS key policy to the account root to avoid any public ("*") principals
data "aws_caller_identity" "current" {}
resource "aws_kms_key" "<example_resource_name>" {
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = { AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root" } # Critical: limit to account root to remove public access
Action = "kms:*"
Resource = "*"
}
]
})
}NativeIaC
# CloudFormation: restrict KMS key policy to account root (removes any public access)
Resources:
<example_resource_name>:
Type: AWS::KMS::Key
Properties:
KeyPolicy:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
AWS: arn:aws:iam::<account_id>:root # Critical: only account root can access; prevents public "*" principals
Action: kms:*
Resource: '*'Other
1Open AWS Console > Key Management Service (KMS)
2Select the affected key and go to the Key policy tab
3Click Edit and remove any statement with Principal set to "\*" (or AWS: "\*")
4Ensure a statement exists that allows only arn:aws:iam::<account_id>:root
5Save changes
Check Code
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.iam.lib.policy import is_policy_public
from prowler.providers.aws.services.kms.kms_client import kms_client
class kms_key_not_publicly_accessible(Check):
def execute(self):
findings = []
for key in kms_client.keys:
if (
key.manager == "CUSTOMER"
and key.state == "Enabled"
and key.policy is not None
): # only customer KMS have policies
report = Check_Report_AWS(metadata=self.metadata(), resource=key)
report.status = "PASS"
report.status_extended = f"KMS key {key.id} is not exposed to Public."
# If the "Principal" element value is set to { "AWS": "*" } and the policy statement is not using any Condition clauses to filter the access, the selected AWS KMS master key is publicly accessible.
if is_policy_public(
key.policy,
kms_client.audited_account,
not_allowed_actions=[],
):
report.status = "FAIL"
report.status_extended = (
f"KMS key {key.id} may be publicly accessible."
)
findings.append(report)
return findingsReferences
- https://www.trendmicro.com/trendaivisiononecloudriskmanagement/knowledge-base/gcp/CloudKMS/publicly-accessible-kms-cryptokeys.html
- https://support.icompaas.com/support/solutions/articles/62000232904-1-9-ensure-cloud-kms-cryptokeys-are-not-accessible-to-anonymous-or-public-users-automated-
- https://docs.aws.amazon.com/kms/latest/developerguide/determining-access.html