0
votes

I wanted the credential report for my aws account using boto3.Did so as follows:

iam = boto3.client('iam',aws_access_key_id=access_key_id,aws_secret_access_key=secret_key,region_name=region) 
creds=iam.get_credential_report()
print(creds)

It gives the output in the following format :

{'Content': b'user,arn,user_creation_time,password_enabled,password_last_used,password_last_changed,password_next_rotation,mfa_active,access_key_1_active,access_key_1_last_rotated,access_key_1_last_used_date,access_key_1_last_used_region,access_key_1_last_used_service,access_key_2_active,access_key_2_last_rotated,access_key_2_last_used_date,access_key_2_last_used_region,access_key_2_last_used_service,cert_1_active,cert_1_last_rotated,cert_2_active,cert_2_last_rotated\n<root_account>,arn:aws:iam::407203256002:root,2021-03-23T04:31:49+00:00,not_supported,2021-04-14T12:01:30+00:00,not_supported,not_supported,false,true,2021-03-31T05:36:58+00:00,2021-04-14T12:42:00+00:00,us-east-1,iam,false,N/A,N/A,N/A,N/A,false,N/A,false,N/A\nuser-01,arn:aws:iam::407203256002:user/user-01,2021-03-31T12:17:53+00:00,false,N/A,N/A,N/A,false,true,2021-03-31T12:17:55+00:00,N/A,N/A,N/A,false,N/A,N/A,N/A,N/A,false,N/A,false,N/A\nuser-02,arn:aws:iam::407203256002:user/user-02,2021-03-31T12:17:11+00:00,true,no_information,2021-03-31T12:17:14+00:00,2021-06-29T12:17:14+00:00,false,false,N/A,N/A,N/A,N/A,false,N/A,N/A,N/A,N/A,false,N/A,false,N/A\nuser_03,arn:aws:iam::407203256002:user/user_03,2021-04-07T12:00:50+00:00,false,N/A,N/A,N/A,false,true,2021-04-07T12:00:52+00:00,N/A,N/A,N/A,false,N/A,N/A,N/A,N/A,false,N/A,false,N/A', 'ReportFormat': 'text/csv', 'GeneratedTime': datetime.datetime(2021, 4, 14, 12, 48, 22, tzinfo=tzutc()), 'ResponseMetadata': {'RequestId': '5a82a64b-9e15-456f-a5db-95c6ae3918b1', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': '5a82a64b-9e15-456f-a5db-95c6ae3918b1', 'content-type': 'text/xml', 'content-length': '2129', 'vary': 'accept-encoding', 'date': 'Wed, 14 Apr 2021 12:50:39 GMT'}, 'RetryAttempts': 0}}

Is there a way to change it into dictionary format ?

2

2 Answers

2
votes

Yes. You can use the python csv module to convert into a dict, but you'll need to wash the credential report a little bit first:

import csv

iam = boto3.client('iam',aws_access_key_id=access_key_id,aws_secret_access_key=secret_key,region_name=region) 
creds = iam.get_credential_report()

# First go from bytes to a list of strings
content = creds["Content"].decode("utf-8")   
content_lines = content.split("\n")         

# Initiate the reader, convert that to a list and turn that into a dict
creds_reader = csv.DictReader(content_lines, delimiter=",")
creds_dict = dict(enumerate(list(creds_reader)))
print(creds_dict)

The result would be similar to this:

{0: {'user': '<root_account>', 'arn': 'arn:aws:iam::12456789088:root'....
{1: {'user': 'admin', 'arn': 'arn:aws:iam::12456789088:root'....
2
votes

The result of iam.get_credential_report() is actually already a (nested) dict, but the piece of interest, the 'Content', is typically in CSV form (as bytes, not str). To see it for yourself:

>>> list(creds.keys())
['Content', 'ReportFormat', 'GeneratedTime', 'ResponseMetadata']

You can observe that the content is in CSV format:

>>> creds['ReportFormat']
'text/csv'

Finally, you can use pandas and io to convert this into a nice and usable DataFrame:

import io
import pandas as pd

df = pd.read_csv(io.BytesIO(creds['Content']))

Or, if you already know which columns are dates and you want to do some date/time analyses:

df = pd.read_csv(
    io.BytesIO(creds['Content']),
    parse_dates=['user_creation_time', 'password_last_used']  # etc.
)