Recently I was asked to scour multiple AWS accounts to find any users or host role that had the S3FullAccess policy applied. So I came up with the following that will go through all users and roles to identify the ones with the S3FullAccess policy assigned.
You can use this as a skeleton to search for any policy across many accounts at once.
Sure does beat using the GUI and visually checking each user and role.
For this example, I opted to just create a simple Text File with the output. It was simple and all that was needed. I’m sure you could change that to use any sort of output format if you wish. You could also add more sophistication my making the target group a passed in parameter instead of how I hard coded it into this example. So I hope this is enough to get you started.
import boto3 import json def iam_list(account=None, id=None, secret=None): # fout is the output string in this function. I will add to this string and return it to the main(). fout = '\n\n-'.ljust(50, '-') + '\n' + account + '\n-'.ljust(50, '-') + '\n\n' # Create session into local account using assumed role or with id/key pairs iamres = boto3.resource('iam', region_name='us-east-1', aws_access_key_id=id, aws_secret_access_key=secret ) iamclient = boto3.client('iam', region_name='us-east-1', aws_access_key_id=id, aws_secret_access_key=secret ) ec2client = boto3.client('ec2', region_name='us-east-1', aws_access_key_id=id, aws_secret_access_key=secret ) s3full = iamres.Policy('arn:aws:iam::aws:policy/AmazonS3FullAccess') fout += 'S3FullAccess Policy is attached to ' + str(s3full.attachment_count) + ' items.\n' # Do the Attached Groups fout += '\nAttached Groups:\n' for each_attachment in s3full.attached_groups.all(): fout += 'Group:\n' fout += ' ' + each_attachment.group_name + '\n' fout += ' With Members:\n' for each_member in each_attachment.users.all(): fout += ' ' + each_member.name + ' with arn: ' + each_member.arn + '\n' # Do the Attached Users fout += '\nAttached Users:\n' for each_attachment in s3full.attached_users.all(): fout += ' ' + each_attachment.user_name + ' with ' + each_attachment.arn + '\n' # Do the Attached Roles fout += '\nAttached Roles:\n' for each_attached_role in s3full.attached_roles.all(): fout += ' ' + each_attached_role.role_name + ' with ' + each_attached_role.arn + '\n' fout += ' In Use on these hosts:\n' hostcount = 0 for each_profile in each_attached_role.instance_profiles.all(): ec2list = ec2client.describe_instances() # I need the attached role name after the last / to match the ec2 iaminstanceprofile['Arn'] targetarn = each_attached_role.arn.split('/')[-1] for each_res in ec2list['Reservations']: for each_ec2 in each_res['Instances']: try: target1 = each_ec2['IamInstanceProfile'] targetec2arn = target1['Arn'] splittargetec2arn = targetec2arn.split('/')[-1] if targetarn == splittargetec2arn: hostcount += 1 for each_tag in each_ec2['Tags']: if each_tag['Key'] == 'Name': fout += ' ' + each_tag['Value'] + '\n' except: pass if hostcount ==0: fout += ' Not Found on any Host\n' fout += '\n' return fout def main(): outstr = '' outstr += iam_list(account='account1', id='account1key', secret='account1secretkey') outstr += iam_list(account='account2', id='account2key', secret='account2secretkey') outstr += iam_list(account='account3', id='account3key', secret='account3secretkey') # Add more accounts as needed. with open("/home/ubuntu/iam_group_report_report.txt", "w") as the_file: the_file.write(outstr) if __name__== "__main__": main()