Skip to content

Instantly share code, notes, and snippets.

@taeyu7720
Forked from DavidWittman/audit_iam_accounts.py
Created June 1, 2018 13:23
Show Gist options
  • Save taeyu7720/1edb9088569ec49bc6ab7370a1bf1fa3 to your computer and use it in GitHub Desktop.
Save taeyu7720/1edb9088569ec49bc6ab7370a1bf1fa3 to your computer and use it in GitHub Desktop.

Revisions

  1. @DavidWittman DavidWittman created this gist Apr 14, 2016.
    101 changes: 101 additions & 0 deletions audit_iam_accounts.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,101 @@
    #!/usr/bin/env python

    # Parses the output from AWS credential reports and displays
    # users which have been inactive for 60+ days.
    #
    # Usage:
    # audit_iam_accounts.py credential_report.csv <days>
    #

    import csv
    import sys

    from datetime import datetime, timedelta

    from prettytable import PrettyTable


    class IAMUser(object):
    DATE_FORMAT = '%Y-%m-%dT%H:%M:%S+00:00'

    def __init__(self, data, inactive_days=60):
    self.data = data
    self.inactive_days = inactive_days

    self.mfa_active = self._parse_bool(data['mfa_active'])

    self.name = data['user']
    self.created_at = self._parse_date(data['user_creation_time'])
    self.password_last_used = \
    self._parse_date(data['password_last_used'])

    self.access_key_1_active = self._parse_bool(data['access_key_1_active'])
    self.access_key_1_last_used = \
    self._parse_date(data['access_key_1_last_used_date'])

    self.access_key_2_active = self._parse_bool(data['access_key_2_active'])
    self.access_key_2_last_used = \
    self._parse_date(data['access_key_2_last_used_date'])

    def _parse_bool(self, boolstring):
    if boolstring == 'true':
    return True
    else:
    return False

    def _parse_date(self, datestring):
    epoch = datetime.fromtimestamp(0)
    return (epoch if (datestring == 'N/A' or datestring == 'no_information')
    else datetime.strptime(datestring, self.DATE_FORMAT))

    def is_inactive(self):
    inactive_date = datetime.now() - timedelta(days=self.inactive_days)
    if (self.password_last_used < inactive_date and
    self.access_key_1_last_used < inactive_date and
    self.access_key_2_last_used < inactive_date):
    return True

    return False


    def main():
    filename = sys.argv[1]
    try:
    inactive_days = int(sys.argv[2])
    except:
    inactive_days = 60

    try:
    user_report = csv.DictReader(open(filename))
    except Exception as e:
    print("Error parsing CSV File: %s" % e)
    sys.exit(1)

    pt = PrettyTable()
    pt.field_names = [
    "User",
    "MFA Enabled",
    "Password Last Used",
    "Key 1 Last Used",
    "Key 2 Last Used"
    ]

    for user_data in user_report:
    user = IAMUser(user_data, inactive_days)
    if user.is_inactive():
    row = [user.name, user.mfa_active, user.password_last_used]
    if user.access_key_1_active:
    row.append(user.access_key_1_last_used)
    else:
    row.append('inactive')
    if user.access_key_2_active:
    row.append(user.access_key_2_last_used)
    else:
    row.append('inactive')

    pt.add_row(row)

    print(pt)

    if __name__ == '__main__':
    main()