|
| 1 | +""" |
| 2 | +Generate a JSON dump of IAM permissions for a given role. |
| 3 | +""" |
| 4 | + |
| 5 | +import json |
| 6 | +import re |
| 7 | + |
| 8 | +from argparse import ArgumentParser |
| 9 | +from collections import defaultdict |
| 10 | + |
| 11 | +import boto3 |
| 12 | + |
| 13 | + |
| 14 | +def list_role_policies(client, role_name): |
| 15 | + inline_policies = [] |
| 16 | + paginator = client.get_paginator('list_role_policies') |
| 17 | + for page in paginator.paginate(RoleName=role_name): |
| 18 | + inline_policies.extend(page['PolicyNames']) |
| 19 | + return inline_policies |
| 20 | + |
| 21 | + |
| 22 | +def get_role_policy(client, role_name, policy_name): |
| 23 | + response = client.get_role_policy(RoleName=role_name, PolicyName=policy_name) |
| 24 | + return response['PolicyDocument']['Statement'] |
| 25 | + |
| 26 | + |
| 27 | +def list_attached_role_policies(client, role_name): |
| 28 | + attached_policies = [] |
| 29 | + paginator = client.get_paginator('list_attached_role_policies') |
| 30 | + for page in paginator.paginate(RoleName=role_name): |
| 31 | + attached_policies.extend(page['AttachedPolicies']) |
| 32 | + return attached_policies |
| 33 | + |
| 34 | + |
| 35 | +def get_attached_role_policy(client, policy_arn): |
| 36 | + response = client.get_policy(PolicyArn=policy_arn) |
| 37 | + default_version_id = response['Policy']['DefaultVersionId'] |
| 38 | + version_response = client.get_policy_version( |
| 39 | + PolicyArn=policy_arn, |
| 40 | + VersionId=default_version_id |
| 41 | + ) |
| 42 | + return version_response['PolicyVersion']['Document']['Statement'] |
| 43 | + |
| 44 | + |
| 45 | +def main(account, role): |
| 46 | + client = boto3.client('iam') |
| 47 | + policy_map = defaultdict(lambda: defaultdict(dict)) |
| 48 | + |
| 49 | + # Get inline policies for the role |
| 50 | + for policy_name in list_role_policies(client, role): |
| 51 | + permissions = get_role_policy(client, role, policy_name) |
| 52 | + policy_map['inline'][policy_name] = permissions |
| 53 | + |
| 54 | + # # Get attached policies for the role |
| 55 | + for attached_policy in list_attached_role_policies(client, role): |
| 56 | + policy_name = attached_policy['PolicyName'] |
| 57 | + policy_arn = attached_policy['PolicyArn'] |
| 58 | + permissions = get_attached_role_policy(client, policy_arn) |
| 59 | + policy_map['attached'][policy_name] = permissions |
| 60 | + |
| 61 | + json_text = json.dumps(policy_map, indent=2) |
| 62 | + print(re.sub(account, "${account_id}", json_text)) |
| 63 | + |
| 64 | + |
| 65 | +if __name__ == "__main__": |
| 66 | + parser = ArgumentParser(description="Export IAM policies for a given role and account") |
| 67 | + parser.add_argument("account", help="Account ID to replace in output with ${account_id}") |
| 68 | + parser.add_argument("role", help="Role to export") |
| 69 | + args = parser.parse_args() |
| 70 | + main(args.account, args.role) |
0 commit comments