A practical guide to implementing IAM best practices using Service Control Policies
The Challenge
Organizations with multiple AWS accounts need consistent IAM permission management to maintain security and operational efficiency. Direct policy attachments to individual users create scalability issues, security visibility gaps, and operational overhead. Manual enforcement across hundreds of accounts becomes impractical and creates governance gaps. Organizations need automated enforcement that promotes IAM best practices organization-wide.
This best practice is supported by CIS AWS Foundations Benchmark v3.0.0 IAM.2 control, which requires that IAM users should not have IAM policies attached directly.
Direct User Policies vs Group-Based Management
Direct user policy attachments create several operational and security challenges compared to group-based permission management:
Direct User Policy Problems:
- Scale Management: Managing permissions for 1000 users requires 1000 individual policy configurations
- Security Visibility: Difficult to audit who has what permissions across the organization
- Permission Creep: Tends to accumulate permissions over time without proper review
- Operational Inefficiency: Role changes require individual policy updates for each user
Group-Based Benefits:
- Scalable Management: Managing permissions for 1000 users through standardized groups
- Clear Visibility: Easy to see all permissions by reviewing group memberships
- Standardized Permissions: Job function-based permission sets prevent over-privileging
- Operational Efficiency: Role changes accomplished by moving users between groups
Implementation Approach
Service Control Policies provide organization-wide enforcement by denying IAM actions that attach policies directly to users. This forces use of IAM groups or roles for permission management, following AWS security best practices. The solution deploys consistently across all accounts and automatically applies to new accounts when configured with automatic deployment.
Service Control Policy
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyDirectUserPolicyAttachment",
"Effect": "Deny",
"Action": [
"iam:AttachUserPolicy",
"iam:DetachUserPolicy",
"iam:PutUserPolicy",
"iam:DeleteUserPolicy"
],
"Resource": "*"
}
]
}
Deployment Strategy
Deploy using AWS Organizations Service Control Policies from the management account. Target organizational units based on governance requirements and apply to accounts that need IAM best practice enforcement.
# Create SCP
aws organizations create-policy \
--name "DenyDirectUserPolicies" \
--description "Prevent direct policy attachment to IAM users" \
--type SERVICE_CONTROL_POLICY \
--content file://deny-user-policies.json
# Attach to organizational unit
aws organizations attach-policy \
--policy-id p-1234567890abcdef \
--target-id ou-1234567890abcdef
What This Policy Blocks
The SCP prevents the following IAM actions:
- iam:AttachUserPolicy - Prevents attaching managed policies directly to users
- iam:DetachUserPolicy - Prevents detaching managed policies from users
- iam:PutUserPolicy - Prevents creating inline policies on users
- iam:DeleteUserPolicy - Prevents deleting inline policies from users
What Still Works
The SCP preserves normal IAM operations that follow best practices:
- Adding users to IAM groups
- Attaching policies to IAM groups
- Creating and using IAM roles
- Attaching policies to IAM roles
- All other IAM management operations
Operations and Maintenance
The SCP enforcement is persistent and requires no ongoing maintenance once deployed. Users and administrators must adapt to group-based permission management, which provides better long-term scalability and security visibility.
AWS Security Hub provides built-in detective controls to monitor accounts with direct user policy attachments through CIS compliance checks.
Testing and Validation
Validate the SCP effectiveness by testing blocked and allowed operations:
Blocked Operations (should fail):
# This should be denied
aws iam attach-user-policy \
--user-name testuser \
--policy-arn arn:aws:iam::aws:policy/ReadOnlyAccess
Allowed Operations (should succeed):
# This should work
aws iam add-user-to-group \
--user-name testuser \
--group-name ReadOnlyGroup
# This should also work
aws iam attach-role-policy \
--role-name MyRole \
--policy-arn arn:aws:iam::aws:policy/ReadOnlyAccess
Limitations and Considerations
This approach enforces IAM best practices but requires organizational change management:
Organizational Impact:
- Existing direct user policies must be migrated to group-based management
- Users and administrators need training on group-based permission model
- Some legacy applications may need architecture updates
Technical Considerations:
- SCP affects all users and roles, including administrative accounts
- Consider exempting specific administrative roles if needed using condition statements
- Test thoroughly in non-production environments before organization-wide deployment
This implementation supports security best practices and satisfies CIS AWS Foundations Benchmark v3.0.0 IAM.2 control requirements.