MEDIUM IAM · CIS 1.15

Direct user policies

Check ID: aws-iam-010

AWS-IAM-010 is an AWS security check performed by cloud-audit, an open-source AWS security scanner. Checks if IAM users have policies attached directly instead of through groups. Direct policy attachments bypass group-based access control and make permission auditing difficult.

Why it matters

Direct policy attachments create a permission management nightmare at scale. When policies are attached to individual users instead of groups, answering the question 'who has access to what?' requires checking every user individually rather than reviewing group memberships. This makes access reviews, compliance audits, and incident response significantly slower. In the 2021 Twitch source code leak post-mortem, investigators noted that direct user policies made it difficult to determine the full scope of compromised access. Group-based access control enables the principle of least privilege at scale: when an employee changes roles, you move them between groups instead of manually adjusting individual policy attachments. AWS IAM Access Analyzer's policy generation feature works more effectively with group-based policies.

Common causes

Quick-fix permissions are attached directly to users during incident response or debugging and never moved to groups afterward. Terraform configurations that use aws_iam_user_policy_attachment instead of aws_iam_group_policy_attachment because it is simpler to write. Lack of IAM governance standards means each team creates permissions in whatever way is fastest, resulting in a mix of group and direct attachments.

Detection

Run cloud-audit to detect this issue:

pip install cloud-audit
cloud-audit scan -R

The -R flag includes remediation details for every finding, including this one.

Remediation: AWS CLI

# Detach policies from user and attach to a group:
aws iam detach-user-policy --user-name USERNAME --policy-arn POLICY_ARN
# Then add user to appropriate group:
aws iam add-user-to-group --user-name USERNAME --group-name APPROPRIATE_GROUP

Remediation: Terraform

# Use group membership instead of direct policy attachment:
resource "aws_iam_group_membership" "user" {
  name  = "user-membership"
  users = ["username"]
  group = aws_iam_group.developers.name
}

Compliance mapping

This check maps to CIS 1.15 in the CIS AWS Foundations Benchmark. The CIS Benchmark provides prescriptive guidance for configuring security options for a subset of AWS services.

This check is part of cloud-audit - install with pip install cloud-audit