IAM & Identity Security
Dangerous IAM Misconfigurations
IAM misconfigurations are behind most cloud breaches. Understanding common mistakes helps you avoid them and recognize them during security assessments.
The Most Dangerous Patterns
1. Overly Permissive Policies ("Admin for Everyone")
The most common and dangerous misconfiguration:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}]
}
Why it's dangerous:
- Any compromised credential = full account access
- Violates least privilege principle
- Common in development environments that make it to production
How to find:
# AWS CLI - Find policies with * actions
aws iam list-policies --scope Local --query 'Policies[*].Arn' | \
xargs -I {} aws iam get-policy-version --policy-arn {} --version-id v1 | \
grep -l '"Action": "\*"'
2. Public Trust Policies
IAM roles that anyone can assume:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": "*",
"Action": "sts:AssumeRole"
}]
}
Impact: Any AWS account in the world can assume this role.
Correct approach:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "unique-external-id"
}
}
}]
}
3. Long-lived Access Keys
Static credentials that never rotate:
# Access keys older than 90 days
aws iam list-access-keys --user-name developer
# Output shows creation date from 2023...
Risks:
- Keys leaked in code repositories
- Keys stored on compromised laptops
- No expiration = unlimited attack window
Solution: Use IAM roles and temporary credentials:
# Instead of hardcoded credentials
import boto3
# Use instance profile (no credentials in code)
session = boto3.Session()
s3 = session.client('s3')
# Or assume a role
sts = boto3.client('sts')
credentials = sts.assume_role(
RoleArn='arn:aws:iam::123456789012:role/MyRole',
RoleSessionName='MySession'
)
4. Missing MFA Requirements
Allowing sensitive operations without MFA:
{
"Effect": "Allow",
"Action": ["iam:*", "s3:*"],
"Resource": "*"
}
Should be:
{
"Effect": "Allow",
"Action": ["iam:*", "s3:*"],
"Resource": "*",
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
}
5. Confused Deputy Problem
Cross-account access without External ID:
Vulnerable trust policy:
{
"Principal": {
"AWS": "arn:aws:iam::111111111111:root"
},
"Action": "sts:AssumeRole"
}
Attack scenario:
- You grant access to a third-party service (Account A)
- Attacker also uses that service
- Attacker tricks service into assuming your role
- Attacker gains access to your account
Prevention:
{
"Principal": {
"AWS": "arn:aws:iam::111111111111:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "your-unique-id-here"
}
}
}
Azure-Specific Misconfigurations
Excessive Custom Role Permissions
{
"Name": "CustomAdmin",
"Actions": [
"*"
],
"AssignableScopes": [
"/subscriptions/subscription-id"
]
}
Missing Conditional Access
No MFA requirement for privileged roles:
- Global Administrator accessing from any location
- No impossible travel detection
- No device compliance requirement
Service Principal Secrets
Long-lived secrets instead of certificate authentication:
# Service principal with password credential (risky)
az ad sp create-for-rbac --name "MyApp" --password "WeakPassword123"
# Better: Use certificate authentication
az ad sp create-for-rbac --name "MyApp" --cert @cert.pem
GCP-Specific Misconfigurations
Primitive Roles on Production
Using Owner/Editor instead of predefined roles:
# BAD: Primitive role with excessive permissions
gcloud projects add-iam-policy-binding my-project \
--member="user:developer@example.com" \
--role="roles/editor"
# GOOD: Specific predefined role
gcloud projects add-iam-policy-binding my-project \
--member="user:developer@example.com" \
--role="roles/cloudsql.viewer"
Service Account Key Export
Downloading service account keys creates long-lived credentials:
# Creates downloadable key (avoid this)
gcloud iam service-accounts keys create key.json \
--iam-account=sa@project.iam.gserviceaccount.com
Better approach: Workload Identity for GKE, attached service accounts for Compute.
Detection Checklist
| Misconfiguration | Detection Method |
|---|---|
| Wildcard policies | Policy analysis tools (Prowler, ScoutSuite) |
| Public principals | Trust policy review |
| Old access keys | IAM credential report |
| No MFA | Credential report, Console audit |
| Unused permissions | IAM Access Analyzer (AWS) |
| Overprivileged roles | Permission boundary analysis |
Next, we'll explore credential management best practices to prevent these issues. :::