Skip to content

Instantly share code, notes, and snippets.

@gauravtoshniwal1989
Created August 14, 2024 09:01
Show Gist options
  • Save gauravtoshniwal1989/8cd0daa51a055a4f20e92f7235e8213a to your computer and use it in GitHub Desktop.
Save gauravtoshniwal1989/8cd0daa51a055a4f20e92f7235e8213a to your computer and use it in GitHub Desktop.
Use this script (carefully) to find IAM Policies not attached to any entity
import boto3
from datetime import datetime as dt
import os
from tqdm import tqdm
import json
import datetime
def datetime_handler(x):
if isinstance(x, dt):
return x.isoformat()
raise TypeError("Unknown type")
class AWSIAMDiscovery:
def __init__(self, region_name, aws_profile):
self.session = boto3.Session(profile_name=aws_profile, region_name=region_name)
self.iam_client = self.session.client("iam")
def get_iam_users(self):
users = []
paginator = self.iam_client.get_paginator("list_users")
for page in tqdm(paginator.paginate(), desc="Fetching IAM Users"):
for user in page["Users"]:
user_info = {
"UserName": user["UserName"],
"UserId": user["UserId"],
"Arn": user["Arn"],
"CreateDate": user["CreateDate"],
"PasswordLastUsed": user.get("PasswordLastUsed", "N/A"),
"AccessKeys": [],
"AttachedPolicies": [],
"Groups": [],
}
# Get access keys
access_keys = self.iam_client.list_access_keys(
UserName=user["UserName"]
)["AccessKeyMetadata"]
user_info["AccessKeys"] = [
{"AccessKeyId": key["AccessKeyId"], "Status": key["Status"]}
for key in access_keys
]
# Get attached policies
attached_policies = self.iam_client.list_attached_user_policies(
UserName=user["UserName"]
)["AttachedPolicies"]
user_info["AttachedPolicies"] = [
policy["PolicyName"] for policy in attached_policies
]
# Get group memberships
groups = self.iam_client.list_groups_for_user(
UserName=user["UserName"]
)["Groups"]
user_info["Groups"] = [group["GroupName"] for group in groups]
users.append(user_info)
return users
def get_iam_roles(self):
roles = []
paginator = self.iam_client.get_paginator("list_roles")
for page in tqdm(paginator.paginate(), desc="Fetching IAM Roles"):
for role in page["Roles"]:
role_info = {
"RoleName": role["RoleName"],
"RoleId": role["RoleId"],
"Arn": role["Arn"],
"CreateDate": role["CreateDate"],
"AssumeRolePolicyDocument": role["AssumeRolePolicyDocument"],
"AttachedPolicies": [],
}
# Get attached policies
attached_policies = self.iam_client.list_attached_role_policies(
RoleName=role["RoleName"]
)["AttachedPolicies"]
role_info["AttachedPolicies"] = [
policy["PolicyName"] for policy in attached_policies
]
roles.append(role_info)
return roles
def get_iam_policies(self):
policies = []
paginator = self.iam_client.get_paginator("list_policies")
for page in tqdm(
paginator.paginate(Scope="Local"), desc="Fetching IAM Policies"
):
for policy in page["Policies"]:
policy_info = {
"PolicyName": policy["PolicyName"],
"PolicyId": policy["PolicyId"],
"Arn": policy["Arn"],
"CreateDate": policy["CreateDate"],
"UpdateDate": policy["UpdateDate"],
"PolicyDocument": None,
"AttachedEntities": {"Users": [], "Groups": [], "Roles": []},
}
# Get policy document
policy_version = self.iam_client.get_policy_version(
PolicyArn=policy["Arn"], VersionId=policy["DefaultVersionId"]
)
policy_info["PolicyDocument"] = policy_version["PolicyVersion"][
"Document"
]
# Get attached entities
entities = self.iam_client.list_entities_for_policy(
PolicyArn=policy["Arn"]
)
policy_info["AttachedEntities"]["Users"] = [
user["UserName"] for user in entities["PolicyUsers"]
]
policy_info["AttachedEntities"]["Groups"] = [
group["GroupName"] for group in entities["PolicyGroups"]
]
policy_info["AttachedEntities"]["Roles"] = [
role["RoleName"] for role in entities["PolicyRoles"]
]
policies.append(policy_info)
return policies
def get_unattached_policies(self, policies):
return [
policy
for policy in policies
if not any(policy["AttachedEntities"].values())
]
def discover_all(self):
iam_users = self.get_iam_users()
iam_roles = self.get_iam_roles()
iam_policies = self.get_iam_policies()
unattached_policies = self.get_unattached_policies(iam_policies)
print(f"\nFound {len(unattached_policies)} unattached policies:")
for policy in unattached_policies:
print(f"- {policy['PolicyName']} (ARN: {policy['Arn']})")
delte_unattached_policies = input(
"Do you want to delete them? (yes_really_sure/n): "
)
if delte_unattached_policies.lower() == "yes_really_sure":
for policy in unattached_policies:
self.iam_client.delete_policy(PolicyArn=policy["Arn"])
print(f"Deleted policy: {policy['PolicyName']} (ARN: {policy['Arn']})")
return iam_users, iam_roles, iam_policies
# Usage
if __name__ == "__main__":
discoverer = AWSIAMDiscovery("ap-south-1", os.getenv("AWS_PROFILE"))
users, roles, policies = discoverer.discover_all()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment