How to Audit Your IAM Setup Before Someone Else Does It for You

IAM is one of those areas where problems compound silently over time. Permissions get added when someone needs them and never get removed. Roles get copied from old projects with broad permissions because it was easier than figuring out what was actually needed. As someone who has conducted IAM audits on several AWS accounts and found access keys that were created years before the person who made them left the company, I learned the systematic approach that finds the actual problems. Today I’ll share it.

AWS IAM audit workflow showing credential report and access analyzer

Start With the Credential Report

The IAM credential report gives you a complete picture of all IAM users and the status of their credentials. Generate it:

aws iam generate-credential-report
aws iam get-credential-report --output text --query Content | base64 -d > credential-report.csv

Look for: users with console passwords and no MFA enabled, access keys that haven’t been used in 90+ days, access keys that were never used, and users who haven’t logged in for 90+ days. These are your immediate action items. That’s what makes the credential report endearing to anyone who has done this exercise — it converts vague security concerns into a specific list of things to fix.

Find Overly Permissive Policies

Policies with wildcards on actions or resources are the most common source of excessive permissions. Query for them:

# Find customer-managed policies with wildcards
aws iam list-policies --scope Local --query 'Policies[*].Arn' --output text | \
  tr '\t' '\n' | while read arn; do
    version=$(aws iam get-policy --policy-arn $arn --query 'Policy.DefaultVersionId' --output text)
    doc=$(aws iam get-policy-version --policy-arn $arn --version-id $version \
      --query 'PolicyVersion.Document' --output json)
    if echo "$doc" | grep -q '"Action": "\*"'; then
      echo "Wildcard actions: $arn"
    fi
  done

Also check for Resource: "*" on sensitive actions like s3:GetObject, secretsmanager:GetSecretValue, and iam:*. These should almost always be scoped to specific resources.

Check IAM Access Analyzer

If you haven’t enabled IAM Access Analyzer, enable it now — it’s free for analyzing resources within your account. Access Analyzer identifies resources that are accessible from outside your account. This catches unintended external access that wouldn’t show up in a manual policy review.

aws accessanalyzer create-analyzer \
  --analyzer-name "account-analyzer" \
  --type ACCOUNT

Use Access Advisor for Least Privilege

IAM Access Advisor shows the last time each service was accessed by a user or role. Use it to identify services in a policy that are never actually used:

aws iam generate-service-last-accessed-details --arn arn:aws:iam::ACCOUNT:role/your-role
aws iam get-service-last-accessed-details --job-id <job-id>

If a role has permissions to 15 services but has only ever called 4 of them in the last 90 days, the other 11 permissions are candidates for removal. This is the most reliable way to make a least-privilege argument based on actual usage data rather than guesses. I’m apparently someone who finds it easier to remove permissions when I can point to the data rather than just saying “we probably don’t need this.”

Check for Root Account Usage

aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=Username,AttributeValue=root \
  --start-time $(date -d '90 days ago' --iso-8601=seconds) \
  --query 'Events[*].{Time:EventTime,Event:EventName}'

Root account activity should be near zero. Root should have MFA enabled and should only be used for the small set of tasks that can’t be delegated.

What to Fix First

Priority order after your audit: (1) Disable or delete unused access keys and users. (2) Enable MFA on all users with console access. (3) Remove wildcard action policies or scope them to specific resources. (4) Review and remediate Access Analyzer findings. (5) Remove unused permissions identified via Access Advisor. Probably should have led with this section, honestly — each of these reduces your attack surface with minimal operational impact, and none of them require changing how your applications work.

Jason Michael

Jason Michael

Author & Expert

Jason covers aviation technology and flight systems for FlightTechTrends. With a background in aerospace engineering and over 15 years following the aviation industry, he breaks down complex avionics, fly-by-wire systems, and emerging aircraft technology for pilots and enthusiasts. Private pilot certificate holder (ASEL) based in the Pacific Northwest.

48 Articles
View All Posts

Leave a Reply

Your email address will not be published. Required fields are marked *

Stay in the loop

Get the latest stigcloud updates delivered to your inbox.