Implementing Real-time Slack Alerts for IAM Key Expiration Using AWS Lambda
In this article, we will explore how to set up an alert system for IAM (Identity Access Management) secret rotation using the AWS Lambda (Amazon Web Service) service. We have accomplished this task by leveraging AWS Boto and Python scripting. By AWS compliance standards, it is necessary to rotate the IAM user’s secret key and access key every 90 days. Failure to do so will result in non-compliance being displayed on our trust dashboards. Therefore, we must be promptly notified with a daily alert in case the underlying threshold is breached through the messaging platform employed for organizational communication. In our specific scenario, Slack is our chosen communication platform and alert monitoring platform. Consequently, we have opted to develop an AWS Lambda function using Python and boto3. This function will provide an alert as soon as our keys surpass the age of 70 days. Hence, we will have an additional 20 days to perform the necessary key rotation for each environment wherever they are used.
Prerequisites
Before proceeding with the setup, ensure that you have the following:
- An active AWS cloud account.
- Basic knowledge of AWS services.
- IAM user: Create an IAM user with appropriate permissions to manage resources.
- Python Installed: Make sure Python is installed on your system for scripting and interaction with AWS services.
Create an IAM Role
Below are the steps for creating an IAM role:
1. Click the Create Role button and select the AWS service option for the trusted entity type. Similarly, select Lambda for common use cases, as shown below. Continue with the role creation by clicking on the Next button as shown below:
2. Continue to add the role permissions as shown below image:
First, search for the permission policies to be added to the search box. For example, we have added the policy IAMReadonlyAccess. Repeat this for all required permissions:
- IAMReadOnlyAccess
- AmazonS3ReadOnlyAccess
- AWSLambdaBasicExecutionRole
- AmazonEventBridgeSchedulerFullAccess
Writing a Python Script Using Boto
Below is a Python script that facilitates the verification of your IAM key’s age:
from urllib import response
from datetime import date
import requests
import boto3
import json
import sys
import random
import os
min_age = 70
max_age = 90
user_list = []
maxage_users = []
slackchannel = os.environ['slackchannel']
hook_url = os.environ['hook_url']
account_id = boto3.client("sts").get_caller_identity()["Account"]
vault_user = (f'vaultuser-{account_id}')
days_remain_all = []
def lambda_handler(event, context):
client = boto3.client('iam')
response = client.list_users()
for x in response['Users']:
if x['UserName'] != vault_user:
user_list.append(x['UserName'])
for username in user_list:
res = client.list_access_keys(UserName=username)
accesskeydate = res['AccessKeyMetadata'][0]['CreateDate'].date()
currentdate = date.today()
active_days = currentdate - accesskeydate
days_remain = max_age - (active_days.days)
if active_days.days > min_age:
maxage_users.append(username)
days_remain_all.append(days_remain)
slack_notif()
def slack_notif():
url = hook_url
message = (f'Found users "{maxage_users}" in account "{account_id}" User keys expires in: "{days_remain_all}" days')
title = (f"IAM Key Rotation:zap:")
slack_data = {
"username": "IAM_Key_Rotation",
"icon_emoji": ":satellite:",
"channel" : slackchannel,
"attachments": [
{
"color": "#9733EE",
"fields": [
{
"title": title,
"value": message,
"short": "false",
}
]
}
]
}
byte_length = str(sys.getsizeof(slack_data))
headers = {'Content-Type': "application/json", 'Content-Length': byte_length}
if maxage_users:
response = requests.post(url, data=json.dumps(slack_data), headers=headers)
if response.status_code != 200:
raise Exception(response.status_code, response.text)from datetime import date
To utilize this script, follow these steps:
- Fork the provided code repository to your preferred platform.
- Configure the script within your Lambda function’s settings.
- Modify the environment variables in the script to align with your specific needs.
Creating a Lambda Function for Automation
In the search bar, enter Lambda to view the listed service, and click on Lambda. You will be able to see the option to create a new Lambda function. After clicking on the Create Function tab, you will be presented with the following window:
In the first step, Select Author from scratch, as we already have a Python script written. The second step is to provide the lambda function name as per the requirement. Then select the Runtime version to Python 3.10 and architecture to x86_64. Next, choose the IAM role we created in the second step for this function and then click the Create Function tab:
After successfully creating the Lambda function, proceed to configure the following environment variables within our Python script:
hook_url: Set the value to your Slack channel’s hook URL.
slackchannel: Set the value to your Slack channel's name.
Make sure you have the trigger setup as mentioned below. You can verify this in your Lambda function’s configuration by checking the Triggers tab, as illustrated below:
Create a Scheduled Trigger as an EventBridge for the Lambda Function
We need to ensure that the Lambda function triggers automatically every day. To achieve this, we will set up an Amazon EventBridge trigger. To begin, navigate to the EventBridge service in the AWS Management Console. Click on the Create Rule button and follow steps as illustrated below:
Search for Amazon EventBridge in the console and click on Rules:
Fill up the details for creating the rule, such as the rule’s name, the description, and the schedule on which you want the rule to be executed:
As shown in the example, we have selected a recurring schedule because we wanted to run this job every 12 hours:
Select the time frame that fits your requirements. We have selected UTC as a time zone:
We have to select the execution target. For example, we have created this rule to trigger the Lambda function; hence, we have chosen AWS lambda Invoke API:
Now, we have to select a particular Lambda function and copy the function’s code as shown below:
Testing the Output Using Lambda
After successfully creating the Lambda function and uploading your code following the above-mentioned steps, proceed with deploying the code. Once deployed, you can initiate a test run. This action should trigger a message to be sent to the designated Slack channel, as detailed in the step Displaying the results on Slack:
Displaying the Results on Slack
We have received the following alert as part of the above automation so that we can take care of rotation before the time:
Conclusion
In this article, we have addressed a straightforward scenario: setting up an AWS Lambda Function to consistently trigger Slack alerts for IAM users’ keys that surpass 70 days in age. This enables us to proactively rotate the keys before they reach the 90-day mark. Our approach involves utilizing Boto and Python for the implementation and Amazon EventBridge to schedule the execution trigger. While the initial configuration involving various objects might appear complex, I encourage you to replicate the provided code and generate your scripts based on it. As you work with the foundational code, you will find subsequent configurations significantly more manageable. You are welcome to experiment with this foundation to streamline the process according to your specific requirements.
References
For additional insights, please visit these articles: