Skip to main content

Prerequisites

Before deploying audit roles, ensure:
1

AWS Organization exists

Your accounts must be organized under an AWS Organization with a designated management account.
2

Member accounts are active

Only ACTIVE accounts are queried. Suspended accounts are automatically skipped.
3

Management account access

You need credentials with organizations:ListAccounts and sts:AssumeRole permissions in the management account.

Deployment Strategy

You have two options for deploying audit roles: Deploy the audit role to all member accounts simultaneously from the management account.
AWSTemplateFormatVersion: '2010-09-09'
Description: 'IAM Audit Role for multi-account security auditing'

Parameters:
  ManagementAccountId:
    Type: String
    Description: AWS Organizations management account ID
  
Resources:
  IAMAuditRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: IAMAuditRole
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              AWS: !Sub 'arn:aws:iam::${ManagementAccountId}:root'
            Action: 'sts:AssumeRole'
      ManagedPolicyArns: []
      Policies:
        - PolicyName: IAMAuditPolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - 'iam:ListUsers'
                  - 'iam:ListAccessKeys'
                  - 'iam:GetAccessKeyLastUsed'
                  - 'iam:ListMFADevices'
                  - 'iam:GetLoginProfile'
                  - 'cloudtrail:LookupEvents'
                Resource: '*'

Outputs:
  RoleArn:
    Description: ARN of the IAM Audit Role
    Value: !GetAtt IAMAuditRole.Arn
# Create StackSet in management account
aws cloudformation create-stack-set \
  --stack-set-name IAMAuditRoleStackSet \
  --template-body file://iam-audit-role.yaml \
  --parameters ParameterKey=ManagementAccountId,ParameterValue=123456789012 \
  --capabilities CAPABILITY_NAMED_IAM \
  --profile mgmt-profile

# Deploy to all member accounts
aws cloudformation create-stack-instances \
  --stack-set-name IAMAuditRoleStackSet \
  --deployment-targets OrganizationalUnitIds=ou-xxxx-xxxxxxxx \
  --regions us-east-1 \
  --profile mgmt-profile

Option 2: Manual Deployment

For smaller Organizations or testing, deploy the role manually in each account using the AWS Console or CLI.

Role Naming Conventions

Consistent role names simplify audit execution. Choose a standard:
Role NameUse Case
IAMAuditRoleDedicated audit role (recommended for production)
SecurityAuditRoleGeneric security operations
AWSControlTowerExecutionControl Tower environments (pre-existing)
The role name you choose must match the --role parameter when running the audit:
python iam_audit.py --profile mgmt-profile --role IAMAuditRole

AWS CLI Profile Configuration

The audit tool uses AWS CLI named profiles to authenticate against the management account.

Configure Management Account Profile

Add credentials to ~/.aws/credentials:
[mgmt-profile]
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
region = us-east-1
Or configure using the CLI:
aws configure --profile mgmt-profile
Use IAM Identity Center (SSO) profiles for enhanced security:
aws configure sso --profile mgmt-profile

Testing Role Assumption

Verify the audit role is correctly deployed and accessible:

Test Single Account

# Replace with actual account ID and role name
aws sts assume-role \
  --role-arn arn:aws:iam::123456789012:role/IAMAuditRole \
  --role-session-name TestAudit \
  --profile mgmt-profile
Expected output:
{
  "Credentials": {
    "AccessKeyId": "ASIAIOSFODNN7EXAMPLE",
    "SecretAccessKey": "...",
    "SessionToken": "...",
    "Expiration": "2026-03-05T21:30:00Z"
  },
  "AssumedRoleUser": {
    "AssumedRoleId": "AROAIOSFODNN7EXAMPLE:TestAudit",
    "Arn": "arn:aws:sts::123456789012:assumed-role/IAMAuditRole/TestAudit"
  }
}

Test IAM Permissions

After assuming the role, verify IAM read access:
# Export temporary credentials from assume-role output
export AWS_ACCESS_KEY_ID="ASIAIOSFODNN7EXAMPLE"
export AWS_SECRET_ACCESS_KEY="..."
export AWS_SESSION_TOKEN="..."

# List IAM users
aws iam list-users

Troubleshooting Common Issues

Symptom: An error occurred (AccessDenied) when calling the AssumeRole operationCauses:
  • Trust relationship missing or incorrect in member account
  • Management account ID doesn’t match the trusted principal
  • sts:AssumeRole permission missing in management account
Solution:
  1. Verify trust policy in member account includes your management account ID
  2. Check management account has sts:AssumeRole for the correct role ARN
  3. Confirm role name matches exactly (case-sensitive)
Symptom: NoSuchEntity: The role with name IAMAuditRole cannot be foundCauses:
  • Role not deployed to all member accounts
  • StackSet deployment still in progress
Solution:
  1. Check StackSet deployment status:
    aws cloudformation list-stack-instances \
      --stack-set-name IAMAuditRoleStackSet \
      --profile mgmt-profile
    
  2. Redeploy to failed accounts
  3. The audit tool will skip accounts where the role is missing — this is expected behavior for partial deployments
Symptom: Audit runs successfully but finds zero users in accounts known to have IAM usersCauses:
  • Missing iam:ListUsers permission in audit role
  • IAM principal running audit lacks permission to assume role
Solution:
  1. Verify the audit role policy matches the permissions documentation
  2. Test IAM API calls manually using temporary credentials from assume-role
Symptom: CSV report generated but cloudtrail_events file is emptyCauses:
  • cloudtrail:LookupEvents permission missing
  • No IAM events in the queried time range
  • CloudTrail not enabled in member accounts
Solution:
  1. Confirm CloudTrail is enabled in at least us-east-1 (IAM events are global but stored regionally)
  2. Check the date range in iam_audit.py (default: Feb 18, 2026 to current)
  3. Verify cloudtrail:LookupEvents is in the audit role policy

Deployment Checklist

Before running your first audit:
  • CloudFormation StackSet deployed to all target accounts
  • Trust relationships configured with management account ID
  • IAM permissions policy attached to audit role
  • AWS CLI profile configured for management account
  • Test role assumption successful in at least one member account
  • Test IAM read permissions with temporary credentials

Next Steps

Run Your First Audit

Execute the audit tool across your Organization

Control Tower Integration

Skip role deployment by using Control Tower’s pre-existing execution role

Build docs developers (and LLMs) love