Using AWS Lambda + Python to rotate IAM Access Keys Automatically

You found this topic because you are trying to automate IAM access keys rotation. Cool. I’ll keep that short and simple since you have googled enough to reach here.

https://unsplash.com/photos/9-ohfp-Dicg

What do you need to know?

IAM — Identity and access management (IAM) is the process used in businesses and organizations to grant or deny employees and others authorization to secure systems.

And this — https://docs.aws.amazon.com/general/latest/gr/aws-access-keys-best-practices.html

Or In other words —

Access keys are long-term credentials for an IAM user. As a best practice, AWS recommends frequent key rotation. Sometimes even for audit purposes.

Cut to the lambda code —

AWS Lambda code:

This is written in python 3.8

import boto3
from botocore.exceptions import ClientError
import datetime
import json
iam_client = boto3.client('iam')
def list_access_key(user, days_filter, status_filter):
keydetails=iam_client.list_access_keys(UserName=user)
key_details={}
user_iam_details=[]

# Some user may have 2 access keys.
for keys in keydetails['AccessKeyMetadata']:
if (days:=time_diff(keys['CreateDate'])) >= days_filter and keys['Status']==status_filter:
key_details['UserName']=keys['UserName']
key_details['AccessKeyId']=keys['AccessKeyId']
key_details['days']=days
key_details['status']=keys['Status']
user_iam_details.append(key_details)
key_details={}

return user_iam_details
def time_diff(keycreatedtime):
now=datetime.datetime.now(datetime.timezone.utc)
diff=now-keycreatedtime
return diff.days
def create_key(username):
access_key_metadata = iam_client.create_access_key(UserName=username)
access_key = access_key_metadata['AccessKey']['AccessKeyId']
secret_key = access_key_metadata['AccessKey']['SecretAccessKey']
def disable_key(access_key, username):
try:
iam_client.update_access_key(UserName=username, AccessKeyId=access_key, Status="Inactive")
print(access_key + " has been disabled.")
except ClientError as e:
print("The access key with id %s cannot be found" % access_key)
def delete_key(access_key, username):
try:
iam_client.delete_access_key(UserName=username, AccessKeyId=access_key)
print (access_key + " has been deleted.")
except ClientError as e:
print("The access key with id %s cannot be found" % access_key)
def lambda_handler(event, context):
# details = iam_client.list_users(MaxItems=300)
# print(details)
user='xxxxx'
user_iam_details=list_access_key(user=user,days_filter=90,status_filter='Active')
for _ in user_iam_details:
disable_key(access_key=_['AccessKeyId'], username=_['UserName'])
delete_key(access_key=_['AccessKeyId'], username=_['UserName'])
create_key(username=_['UserName'])

return {
'statusCode': 200,
'body': list_access_key(user=user,days_filter=0,status_filter='Active')
}

Also, if you want to do this for all the IAM roles — then simply iterate it over the list of users like this —

details = iam_client.list_users(MaxItems=300)
users = details['Users']
for user in users:
user_iam_details=list_access_key(user=user, days_filter=90, status_filter='Inactive')
for _ in user_iam_details:
disable_key(access_key=_['AccessKeyId'], username=_['UserName'])
delete_key(access_key=_['AccessKeyId'], username=_['UserName'])
create_key(username=_['UserName'])

Alright, I know its a big one! But here are the permissions you need to run this program.

Permissions Required:

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"iam:ListUsers",
"iam:CreateAccessKey",
"iam:DeleteAccessKey",
"iam:GetAccessKeyLastUsed",
"iam:GetUser",
"iam:ListAccessKeys",
"iam:UpdateAccessKey"
],
"Resource": "*"
}
]
}

Simply paste the above configuration into the lambda role that you are using.

Automating this —

Attach a cloud watch event or event bridge to this lambda. Select Schedule to run this “daily” — cron( 0 1 * * * ) and BOOM! You are all set to run this machine to automatically rotate the IAM keys. Super freaking easy.

Up next— Taking this one step further and automating it for multiple accounts. Stay tuned!

Data Engineer, Programmer, Thinker

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store