Back to Checks
Inline IAM policy does not allow kms:* privileges
iam_inline_policy_no_full_access_to_kms
Service: iamSeverity: medium
OfficialBuilt-inVerified
Categories:identity-access
Resource Type:AwsIamPolicy
IAM inline policies are analyzed to identify statements that grant unrestricted AWS KMS access via the wildcard action kms:*.
Risk
Granting kms:* enables decryption of protected data, modification of key policies and grants, and disabling or deleting keys.
Impacts:
- Confidentiality via unauthorized decryption
- Integrity through key/grant tampering
- Availability if keys are disabled or deleted, breaking encrypted workloads
Run this check with Prowler
Run in Prowler CloudRun
prowler aws --checks iam_inline_policy_no_full_access_to_kmsRecommendation
Replace kms:* with least-privilege, action-scoped permissions limited to required operations and specific key ARNs. Enforce separation of duties for key admins vs users. Prefer managed policies over inline and apply guardrails (permissions boundaries/SCPs). Add conditions to constrain service, region, and encryption context.
Remediation
Terraform
# Inline IAM policy without kms:* full access
resource "aws_iam_user_policy" "<example_resource_name>" {
name = "<example_resource_name>-policy"
user = "<example_resource_name>"
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Action = [
"kms:Encrypt" # CRITICAL: replace 'kms:*' with specific action(s) to remove full access
]
Resource = "*"
}]
})
}NativeIaC
# CloudFormation: Inline IAM policy without kms:* full access
Resources:
<example_resource_name>:
Type: AWS::IAM::User
Properties:
Policies:
- PolicyName: <example_resource_name>-policy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- kms:Encrypt # CRITICAL: replace 'kms:*' with only required KMS action(s) to remove full access
Resource: "*"Other
1In the AWS Console, open IAM and go to Users, Roles, or Groups (where the inline policy is attached)
2Select the entity, go to the Permissions tab, and open the inline policy that allows KMS
3Click Edit policy and switch to the JSON editor
4Replace any "Action": "kms:*" with only the specific KMS action(s) required (e.g., "kms:Encrypt")
5Save changes
Check Code
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.iam.iam_client import iam_client
from prowler.providers.aws.services.iam.lib.policy import check_full_service_access
critical_service = "kms"
class iam_inline_policy_no_full_access_to_kms(Check):
def execute(self):
findings = []
for policy in iam_client.policies.values():
if policy.type == "Inline":
report = Check_Report_AWS(metadata=self.metadata(), resource=policy)
report.region = iam_client.region
report.resource_id = f"{policy.entity}/{policy.name}"
report.status = "PASS"
resource_type_str = report.resource_arn.split(":")[-1].split("/")[0]
resource_attached = report.resource_arn.split("/")[-1]
report.status_extended = f"{policy.type} policy {policy.name}{' attached to ' + resource_type_str + ' ' + resource_attached if policy.attached else ''} does not allow '{critical_service}:*' privileges."
if policy.document and check_full_service_access(
critical_service, policy.document
):
report.status = "FAIL"
report.status_extended = f"{policy.type} policy {policy.name}{' attached to ' + resource_type_str + ' ' + resource_attached if policy.attached else ''} allows '{critical_service}:*' privileges."
findings.append(report)
return findings