Overview
Theiam_audit.py module provides a programmatic interface for auditing IAM users and access keys across AWS Organizations. All functions are designed to work with boto3 clients and temporary credentials obtained through sts:AssumeRole.
Core Functions
get_accounts()
Retrieves all active accounts from an AWS Organization.Boto3 Organizations client authenticated with the management account
- Uses pagination to handle organizations with many accounts
- Filters to only return accounts with
Status == 'ACTIVE' - Located at: iam_audit.py:8-19
assume_role()
Asumes a role in a target AWS account and returns temporary credentials.Boto3 session with credentials for the source account
Target AWS account ID where the role will be assumed
Name of the IAM role to assume (e.g., ‘AWSControlTowerExecution’, ‘IAMAuditRole’)
Session name for CloudTrail auditing (e.g., ‘SecurityAudit’, ‘CloudTrailAudit’)
- Uses STS
assume_roleAPI - Constructs ARN:
arn:aws:iam::{account_id}:role/{role_name} - Credentials are temporary and expire automatically
- Located at: iam_audit.py:21-28
get_iam_users_with_keys()
Lists all IAM users with access keys in a target account, including security metadata.Boto3 IAM client authenticated with the target account (via assumed role)
AWS account ID being audited
Human-readable account name for reporting
List of finding dictionaries, one per access key found:
AWS account ID
Account name
IAM user name
‘Configurada’ or ‘No configurada’ (console access enabled/disabled)
Timestamp of last console login, or ‘Nunca’
Access key ID (e.g., AKIAIOSFODNN7EXAMPLE)
‘Active’ or ‘Inactive’
ISO timestamp when the access key was created
ISO timestamp of last usage, or ‘Nunca utilizada’
Last AWS service used with this key, or ‘N/A’
‘Virtual’, ‘Hardware’, or ‘None’
- Uses pagination for accounts with many IAM users
- Queries multiple IAM APIs per user:
list_access_keys- Get all access keyslist_mfa_devices- Check MFA statusget_login_profile- Check console accessget_access_key_last_used- Get usage metadata
- Handles
NoSuchEntityExceptionfor users without console access - Returns one finding per access key (users can have multiple keys)
- Located at: iam_audit.py:30-83
This function calls the IAM API multiple times per user. In accounts with hundreds of users, expect longer execution times due to API rate limits.
get_cloudtrail_events()
Retrieves IAM-related CloudTrail events across multiple accounts for remediation tracking.Boto3 session with credentials for the management account
List of account dictionaries (output from
get_accounts())Name of the IAM role to assume in each account
Start of the time range for CloudTrail lookup
End of the time range for CloudTrail lookup
List of CloudTrail event dictionaries:
IAM event name (e.g., ‘DeleteAccessKey’, ‘CreateUser’)
ISO timestamp when the event occurred
IAM user who triggered the event, or ‘N/A’
AWS account ID where the event occurred
Account name
List of affected resource names
DeleteUserDeleteAccessKeyDeleteLoginProfileCreateAccessKeyCreateUser
- Uses CloudTrail
lookup_eventsAPI with pagination - Region locked to
us-east-1(see Limitations) - Assumes role in each account to query CloudTrail
- Errors in individual accounts are caught and logged, but don’t stop execution
- Located at: iam_audit.py:85-120
main()
Orchestrates the complete audit workflow across all accounts. Function Signature:- Parses CLI arguments (
--profile,--role) - Initializes boto3 session with specified profile
- Retrieves all active accounts from AWS Organizations
- Fetches CloudTrail events for all accounts
- Iterates through each account:
- Assumes the audit role
- Queries IAM users and access keys
- Aggregates findings
- Returns consolidated findings and events
- Uses hardcoded date range:
start_date = datetime(2026, 2, 18) - Continues on errors (failed accounts are logged but don’t stop the audit)
- Located at: iam_audit.py:128-167
When run as a script,
main() also generates two CSV reports:iam_audit_report_YYYYMMDD_HHMMSS.csv- IAM findingscloudtrail_events_YYYYMMDD_HHMMSS.csv- CloudTrail events
CLI Arguments
When runningiam_audit.py as a script:
AWS CLI profile name for the management account
IAM role name to assume in each child account (e.g., ‘AWSControlTowerExecution’)
CSV Output Format
IAM Audit Report
Filename:iam_audit_report_YYYYMMDD_HHMMSS.csv
Fields:
account_id- AWS account IDaccount_name- Account nameusername- IAM user namepassword_status- Console access statuspassword_last_used- Last console loginaccess_key_id- Access key IDstatus- Active/Inactivecreated_date- Key creation datelast_used_date- Last key usageservice_name- Last service usedmfa_status- MFA status (Virtual/Hardware/None)
CloudTrail Events Report
Filename:cloudtrail_events_YYYYMMDD_HHMMSS.csv
Fields:
eventTime- Event timestampeventName- IAM event nameusername- User who triggered the eventaccount_id- Account IDaccount_name- Account nameresources- Comma-separated list of affected resources
Error Handling
All functions implement error handling:- Account access errors: Logged to console, execution continues with remaining accounts
- Missing login profile: Caught via
NoSuchEntityException, setspassword_status = 'No configurada' - CloudTrail errors: Logged per-account, doesn’t stop the audit
