🔐 Check Which IAM Users Don’t Have MFA Enabled Using Boto3

Table of contents
Multi-Factor Authentication (MFA) is a critical security measure for AWS IAM users. However, AWS doesn’t provide a direct method via Boto3 to list users without MFA enabled. But we can still solve this by combining the following two Boto3 methods:
list_users()
– to fetch all IAM users.list_mfa_devices()
– to check if each user has any MFA devices assigned.
Here’s a simple Python script that lists IAM users who do not have MFA enabled.
import boto3
aws_console = boto3.session.Session(profile_name="default")
aws_service = boto3.client("iam")
user_with_mfa_disabled = []
users_list = aws_service.list_users()
for usr in users_list['Users']:
iam = boto3.client('iam')
mfa_devices_lst = iam.list_mfa_devices(UserName=usr['UserName'])
if mfa_devices_lst['MFADevices'] == []:
user_with_mfa_disabled.append(usr['UserName'])
else:
continue
users_count = len(user_with_mfa_disabled)
print(f"There are {users_count} users whose MFA has not been enabled are -",user_with_mfa_disabled)
How This Works – Explained Line by Line
import boto3
Imports the Boto3 SDK, which allows us to interact with AWS services via Python.
aws_console = boto3.session.Session(profile_name="default")
aws_service = boto3.client("iam")
Creates a new session using the AWS CLI default profile. This profile must already have valid access/secret keys configured using aws configure -profile default
aws_console
is a variable which login into the AWS console using the default profile
I have set AWS Credentials , having user access key, secret key in default profile, I am using that profile here, hence using the profile_name default.
aws_service
- Creates an IAM client using the session. Since IAM is a global service, no region needs to be specified. In case no region is mentioned, default profile region is considered. If you want to run the script for a particular region, you need to mention the region.
user_with_mfa_disabled = []
I have declared an empty list here.
users_list = aws_service.list_users()
Here, I have initiated the list_users() method of Boto3, to fetch all IAM Users in the AWS account and store it in variable users_list
. Upon printing this, I’ll get a list of Users.
Sample output according to boto3 docs -
{
'Users': [
{
'Path': 'string',
'UserName': 'string',
'UserId': 'string',
'Arn': 'string',
'CreateDate': datetime(2015, 1, 1),
'PasswordLastUsed': datetime(2015, 1, 1),
'PermissionsBoundary': {
'PermissionsBoundaryType': 'PermissionsBoundaryPolicy',
'PermissionsBoundaryArn': 'string'
},
'Tags': [
{
'Key': 'string',
'Value': 'string'
},
]
},
],
'IsTruncated': True|False,
'Marker': 'string'
}
In here, I have to fetch the UserName detail which I’ll be able to get from Users
list.
for usr in users_list['Users']:
iam = boto3.client('iam')
mfa_devices_lst = iam.list_mfa_devices(UserName=usr['UserName'])
In here, I am iterating through the for loop of users fetched through list_users() methodusers_list['Users']
→ will list down all the user details
{
'Path': 'string',
'UserName': 'string',
'UserId': 'string',
'Arn': 'string',
'CreateDate': datetime(2015, 1, 1),
'PasswordLastUsed': datetime(2015, 1, 1),
'PermissionsBoundary': {
'PermissionsBoundaryType': 'PermissionsBoundaryPolicy',
'PermissionsBoundaryArn': 'string'
},
'Tags': [
{
'Key': 'string',
'Value': 'string'
},
]
}
In here, we have to fetch the UserName
parameter value.
for usr in users_list['Users']:
iam = boto3.client('iam')
mfa_devices_lst = iam.list_mfa_devices(UserName=usr['UserName'])
This for loop, loops through the map of each users in the Users
list.
We’ll be fetching the UserName of each users.
Inside this for loop ,I have initiated another method list_mfa_devices()
this method will list all the mfa and their details.
{
'MFADevices': [
{
'UserName': 'string',
'SerialNumber': 'string',
'EnableDate': datetime(2015, 1, 1)
},
],
'IsTruncated': True|False,
'Marker': 'string'
}
This is the response of the list_mfa_devices()
method. In here, the ‘MFADevices
’ parameter gives me the device info in case mfa device is found.
For this we need to pass the UserName in the list_mfa_devices()
method to get the output.
Note:
If you omit UserName
, it returns MFA devices for the current IAM user (i.e., whoever is running the script, here default profile user).
mfa_devices_lst = iam.list_mfa_devices(UserName=usr['UserName'])
This line will list all the MFA devices info for the particular username passed from above usr
variable of for loop.
if mfa_devices_lst['MFADevices'] == []:
user_with_mfa_disabled.append(usr['UserName'])
else:
continue
Here, we’ll check if the value of mfa_devices_lst['MFADevices']
is empty list like [], if its so it means for that particular IAM user, no MFA is configured since no MFA detail was found.
So we’ll continue adding such users to the empty list user_with_mfa_disabled
which we created earlier.
If MFADevice details found, we’ll not add the user to the list and continue processing further.
users_count = len(user_with_mfa_disabled)
print(f"There are {users_count} users whose MFA has not been enabled are -",user_with_mfa_disabled)
Once we come out of the for loop,
we’ll count the number of users in the empty list and print the number of users whose MFA is not enabled along with the list containing those users.
This script is a quick and effective way to audit IAM users in your AWS account and ensure MFA is enabled. You can run it periodically or integrate it into a larger compliance automation pipeline.
Hope you find this helpful!
Subscribe to my newsletter
Read articles from Sonal Kumar directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
