Skip to main content

Overview

The IAM Audit tool follows the principle of least privilege. It requires specific permissions in two locations:
  1. Management Account - to list Organization accounts and assume roles
  2. Member Accounts - to read IAM users, access keys, and CloudTrail events
Never use overly permissive policies like IAMFullAccess or ReadOnlyAccess for audit operations. The policies below provide exactly what’s needed — nothing more.

Management Account Permissions

The identity running the audit from your management account needs two core permissions:
1

List Organization Accounts

The organizations:ListAccounts action retrieves all active accounts in your AWS Organization.
2

Assume Audit Role

The sts:AssumeRole action allows cross-account access to member accounts using temporary credentials.

Management Account Policy

Attach this policy to the IAM user or role executing the audit:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "organizations:ListAccounts",
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": "sts:AssumeRole",
      "Resource": "arn:aws:iam::*:role/NOMBRE-DEL-ROL-EN-CHILD-ACCOUNTS"
    }
  ]
}
Replace NOMBRE-DEL-ROL-EN-CHILD-ACCOUNTS with your actual audit role name (e.g., IAMAuditRole or AWSControlTowerExecution).

Member Account Permissions

Each member account requires a role with read-only IAM and CloudTrail permissions.

Required Actions

The audit role queries the following AWS APIs:
ActionPurpose
iam:ListUsersEnumerate all IAM users in the account
iam:ListAccessKeysList access keys for each user
iam:GetAccessKeyLastUsedRetrieve last usage timestamp and service
iam:ListMFADevicesCheck MFA configuration status
iam:GetLoginProfileDetermine console access status
cloudtrail:LookupEventsQuery IAM events for remediation tracking

Member Account Policy

Deploy this policy to the audit role in every member account:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iam:ListUsers",
        "iam:ListAccessKeys",
        "iam:GetAccessKeyLastUsed",
        "iam:ListMFADevices",
        "iam:GetLoginProfile",
        "cloudtrail:LookupEvents"
      ],
      "Resource": "*"
    }
  ]
}
IAM is a global service, but CloudTrail events are regional. The tool queries us-east-1 by default for CloudTrail data.

Trust Relationship

The audit role in member accounts must trust your management account.

Trust Policy Example

Attach this trust relationship to the audit role in member accounts:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::MANAGEMENT_ACCOUNT_ID:root"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "sts:ExternalId": "optional-external-id"
        }
      }
    }
  ]
}
Replace MANAGEMENT_ACCOUNT_ID with your actual AWS Organizations management account ID. Consider adding an ExternalId condition for additional security.

Security Best Practices

The tool uses sts:AssumeRole to generate temporary credentials that expire automatically. Never store long-term access keys for audit operations.
The management account policy restricts sts:AssumeRole to a specific role name across accounts. This prevents lateral movement to other roles.
The member account policy grants zero write permissions. The tool cannot modify IAM users, keys, or CloudTrail configurations.
All AssumeRole operations are logged in CloudTrail. Review these events regularly to detect unauthorized audit runs.

Validation

Before running the full audit, test your permissions:
# Verify Organizations access
aws organizations list-accounts --profile mgmt-profile

# Test role assumption in a single account
aws sts assume-role \
  --role-arn arn:aws:iam::123456789012:role/IAMAuditRole \
  --role-session-name TestAudit \
  --profile mgmt-profile
If both commands succeed, your permissions are correctly configured.

Next Steps

AWS Organization Setup

Deploy the audit role to member accounts using CloudFormation StackSets

Control Tower Integration

Use the pre-existing AWSControlTowerExecution role for audits

Build docs developers (and LLMs) love