<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: kalyani Uppara</title>
    <description>The latest articles on Forem by kalyani Uppara (@kalyani_uppara).</description>
    <link>https://forem.com/kalyani_uppara</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2856323%2Fe3ef5382-bd9e-47d9-811a-13c57c5b9aca.jpg</url>
      <title>Forem: kalyani Uppara</title>
      <link>https://forem.com/kalyani_uppara</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/kalyani_uppara"/>
    <language>en</language>
    <item>
      <title>Secure Your AWS Account: Automate IAM Expiry Notifications with Lambda + SNS</title>
      <dc:creator>kalyani Uppara</dc:creator>
      <pubDate>Wed, 08 Oct 2025 05:09:35 +0000</pubDate>
      <link>https://forem.com/kalyani_uppara/secure-your-aws-account-automate-iam-expiry-notifications-with-lambda-sns-45j0</link>
      <guid>https://forem.com/kalyani_uppara/secure-your-aws-account-automate-iam-expiry-notifications-with-lambda-sns-45j0</guid>
      <description>&lt;p&gt;🛡️ &lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In today’s cloud-first world, &lt;strong&gt;Identity and Access Management (IAM)&lt;/strong&gt; is your AWS account’s first line of defense. Yet, it’s common for IAM &lt;strong&gt;passwords and access keys&lt;/strong&gt; to remain active well beyond their intended lifespan — posing serious security risks. Manually tracking and rotating these credentials is tedious and error-prone.&lt;/p&gt;

&lt;p&gt;This post walks you through building a &lt;strong&gt;fully automated IAM expiry notification system&lt;/strong&gt; using &lt;strong&gt;AWS Lambda, Amazon SNS, and Amazon EventBridge&lt;/strong&gt;. The setup continuously scans IAM users, detects credentials past expiration, and sends &lt;strong&gt;real-time alerts&lt;/strong&gt; to help you stay secure — all with zero manual effort.&lt;/p&gt;

&lt;p&gt;🎯 &lt;strong&gt;Purpose&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The goal of this automation is to &lt;strong&gt;enhance your AWS security posture&lt;/strong&gt; by proactively monitoring IAM user credentials — specifically &lt;strong&gt;passwords and access keys&lt;/strong&gt; — and alerting administrators when they exceed a predefined age threshold.&lt;br&gt;
This ensures &lt;strong&gt;regular credential rotation&lt;/strong&gt;, enforces &lt;strong&gt;security best practices&lt;/strong&gt;, and reduces the risk of &lt;strong&gt;unauthorized access&lt;/strong&gt; due to stale or forgotten IAM credentials.&lt;/p&gt;

&lt;p&gt;📌 &lt;strong&gt;Scope&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This automation covers:&lt;/p&gt;

&lt;p&gt;🔍 Scanning all IAM users in the AWS account&lt;/p&gt;

&lt;p&gt;⏰ Detecting expired access keys and outdated passwords&lt;/p&gt;

&lt;p&gt;📢 Sending automated notifications via &lt;strong&gt;Amazon SNS&lt;/strong&gt; (e.g., email alerts)&lt;/p&gt;

&lt;p&gt;🗓️ Scheduling periodic checks using &lt;strong&gt;Amazon EventBridge&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;⚙️ Running everything in a &lt;strong&gt;serverless AWS Lambda function&lt;/strong&gt; — no manual intervention after deployment&lt;/p&gt;

&lt;p&gt;⚠️ Note: This solution focuses purely on &lt;strong&gt;monitoring and alerting&lt;/strong&gt;. It does &lt;strong&gt;not&lt;/strong&gt; deactivate or delete keys automatically — giving administrators control over remediation.&lt;/p&gt;

&lt;p&gt;🏗️ &lt;strong&gt;Architecture Overview&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The architecture of this solution is simple, serverless, and fully automated — designed to run on a schedule without any manual triggers. It leverages three core AWS services that work together to monitor IAM credentials and send expiry notifications.&lt;/p&gt;

&lt;p&gt;⚙️ &lt;strong&gt;How It Works&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Amazon EventBridge (Scheduler):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Triggers the Lambda function automatically at a predefined interval (e.g., daily).&lt;/li&gt;
&lt;li&gt;Ensures continuous monitoring of IAM credentials without human intervention.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. AWS Lambda (Logic Engine):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Executes the core logic to:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fetch all IAM users in the AWS account.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Retrieve each user’s password and access key metadata.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Calculate the age of credentials.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Compare against a defined threshold (e.g., 85 days).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Identifies users with credentials nearing or past expiry.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3.Amazon SNS (Notification System):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sends out real-time notifications (email or other subscribed endpoints).&lt;/li&gt;
&lt;li&gt;Alerts administrators or security teams when credentials exceed the threshold.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🧠 &lt;strong&gt;Workflow Summary&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;EventBridge triggers the Lambda function on schedule.&lt;/li&gt;
&lt;li&gt;Lambda queries IAM to fetch user credentials and calculates their age.&lt;/li&gt;
&lt;li&gt;If a password or key is older than the threshold, Lambda compiles the details.&lt;/li&gt;
&lt;li&gt;Lambda publishes the alert message to an SNS topic.&lt;/li&gt;
&lt;li&gt;SNS sends an email or message to the subscribed recipients.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This lightweight design ensures &lt;strong&gt;high reliability, zero maintenance&lt;/strong&gt;, and &lt;strong&gt;no additional infrastructure cost&lt;/strong&gt;, making it ideal for organizations of any size that want to enhance IAM security visibility.&lt;/p&gt;

&lt;p&gt;⚙️ &lt;strong&gt;Implementation Steps&lt;/strong&gt; &lt;/p&gt;
&lt;h3&gt;
  
  
  Step 1: Create an SNS Topic
&lt;/h3&gt;

&lt;p&gt;We’ll start by setting up an &lt;strong&gt;Amazon SNS topic&lt;/strong&gt; — this will act as the notification channel for sending expiry alerts via email (or any other supported protocol).&lt;/p&gt;

&lt;p&gt;🧭 &lt;strong&gt;Steps:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.Navigate to SNS in the AWS Console&lt;/strong&gt;&lt;br&gt;
Open the AWS Management Console and search for &lt;strong&gt;SNS (Simple Notification Service).&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.Create a New Topic&lt;/strong&gt;&lt;br&gt;
Click on “Create topic” to begin the setup.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.Select Topic Type&lt;/strong&gt;&lt;br&gt;
Choose &lt;strong&gt;Standard&lt;/strong&gt; as the topic type and provide a descriptive name.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4.Create the Topic&lt;/strong&gt;&lt;br&gt;
Scroll down and click &lt;strong&gt;“Create topic”&lt;/strong&gt; at the bottom-right corner of the page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5.Add a Subscription&lt;/strong&gt;&lt;br&gt;
Once the topic is created, click on &lt;strong&gt;“Create subscription.”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6.Configure the Subscription&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Topic ARN&lt;/strong&gt;: Select the topic you just created.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Protocol&lt;/strong&gt;: Choose *&lt;em&gt;Email *&lt;/em&gt;(you can also use SMS, Lambda, or HTTP endpoints).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Endpoint&lt;/strong&gt;: Enter your email address (or the recipient’s email).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;7.Confirm the Subscription&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check your email inbox for a confirmation message from AWS.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;“Confirm subscription”&lt;/strong&gt; in the email to activate it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After confirmation, the SNS topic will be ready to receive messages and forward them as &lt;strong&gt;email alerts&lt;/strong&gt; to the subscribed recipients.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 2: Create the Lambda Function
&lt;/h3&gt;

&lt;p&gt;Next, we’ll set up the &lt;strong&gt;AWS Lambda function&lt;/strong&gt; that performs the actual check for IAM password and access key expiry, and sends notifications via SNS.&lt;/p&gt;

&lt;p&gt;🧭 &lt;strong&gt;Steps:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.Navigate to Lambda in the AWS Console&lt;/strong&gt;&lt;br&gt;
    Open the &lt;strong&gt;AWS Lambda service&lt;/strong&gt; from the console.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.Create a New Function&lt;/strong&gt;&lt;br&gt;
    Click &lt;strong&gt;“Create function”&lt;/strong&gt; to begin setup.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.Configure Basic Settings&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;    Choose &lt;strong&gt;Author from scratch&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;    Provide a name.&lt;/li&gt;
&lt;li&gt;    Select &lt;strong&gt;Python latest&lt;/strong&gt; runtime.&lt;/li&gt;
&lt;li&gt;    Choose &lt;strong&gt;x86_64&lt;/strong&gt; as the architecture.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4.Assign Permissions&lt;/strong&gt;&lt;br&gt;
Lambda needs an execution role with specific IAM permissions to fetch IAM data and publish notifications to SNS.&lt;br&gt;
Create a &lt;strong&gt;&lt;code&gt;new IAM Role&lt;/code&gt;&lt;/strong&gt; with the following policy and attach it to your Lambda function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "sns:Publish",
                "iam:GetAccessKeyLastUsed",
                "iam:ListUsers",
                "iam:GetUser",
                "iam:ListAccessKeys",
                "iam:GetAccountPasswordPolicy",
                "iam:GenerateCredentialReport",
                "iam:GetCredentialReport"
            ],
            "Resource": "*"
        }
    ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5.Create the Function&lt;/strong&gt;&lt;br&gt;
Click &lt;strong&gt;“Create function”&lt;/strong&gt; to finalize setup.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6.Add the Code&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Once the function is created, open it in the console.&lt;/li&gt;
&lt;li&gt;In the code editor, replace the default code with the following Python script:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import boto3
import datetime
import csv
import io
from dateutil import parser

sns_client = boto3.client('sns')
iam_client = boto3.client('iam')

SNS_TOPIC_ARN = 'Paste your SNS Topic ARN Here'

def lambda_handler(event, context):
    iam_client.generate_credential_report()
    report_response = iam_client.get_credential_report()
    report_csv = report_response['Content'].decode('utf-8')
    csv_reader = csv.DictReader(io.StringIO(report_csv))

    max_password_age = 90
    expired_items = []

    now = datetime.datetime.now(datetime.timezone.utc)

    for row in csv_reader:
        username = row['user']
        if username in ['&amp;lt;root_account&amp;gt;', '']:
            continue

        user_creation_time = row['user_creation_time']
        password_last_changed = row['password_last_changed']

        # ✅ Password check
        if password_last_changed not in ['not_supported', 'N/A']:
            pwd_changed_dt = parser.isoparse(password_last_changed)
            password_age_days = (now - pwd_changed_dt).days
            if password_age_days &amp;gt; max_password_age:
                expired_items.append({
                    'UserName': username,
                    'Type': 'Password',
                    'UserCreationTime': user_creation_time,
                    'PasswordLastChanged': pwd_changed_dt.strftime('%Y-%m-%d %H:%M:%S'),
                    'Age': password_age_days
                })

        # ✅ Access key check
        try:
            access_keys = iam_client.list_access_keys(UserName=username)['AccessKeyMetadata']
            for key in access_keys:
                if key['Status'] == 'Active':
                    key_id = key['AccessKeyId']
                    key_created_dt = key['CreateDate']
                    key_age_days = (now - key_created_dt).days

                    if key_age_days &amp;gt; max_password_age:
                        try:
                            usage = iam_client.get_access_key_last_used(AccessKeyId=key_id)
                            last_used = usage.get('AccessKeyLastUsed', {}).get('LastUsedDate')
                            last_used_str = last_used.strftime('%Y-%m-%d %H:%M:%S') if last_used else "Never Used"
                        except Exception:
                            last_used_str = "Unknown"

                        expired_items.append({
                            'UserName': username,
                            'Type': 'AccessKey',
                            'AccessKeyId': key_id,
                            'UserCreationTime': user_creation_time,
                            'AccessKeyCreationTime': key_created_dt.strftime('%Y-%m-%d %H:%M:%S'),
                            'AccessKeyLastUsed': last_used_str,
                            'Age': key_age_days
                        })
        except Exception as e:
            print(f"Error listing keys for user {username}: {e}")

    # ✅ Send SNS notification
    if expired_items:
        message = "The following IAM credentials are older than the allowed max password age:\n\n"
        for item in expired_items:
            if item['Type'] == 'Password':
                message += (
                    f"User: {item['UserName']}, User Creation Time: {item['UserCreationTime']}, "
                    f"Password Last Changed: {item['PasswordLastChanged']}, Age: {item['Age']} days\n"
                )
            else:
                message += (
                    f"User: {item['UserName']}, User Creation Time: {item['UserCreationTime']}, "
                    f"AccessKeyId: {item['AccessKeyId']}, Access Key Creation Time: {item['AccessKeyCreationTime']}, "
                    f"Access Key Last Used: {item['AccessKeyLastUsed']}, Age: {item['Age']} days\n"
                )

        sns_client.publish(
            TopicArn=SNS_TOPIC_ARN,
            Subject="IAM User and Access Keys Credentials Expiry Alert",
            Message=message
        )
    else:
        sns_client.publish(
            TopicArn=SNS_TOPIC_ARN,
            Subject="IAM User and Access Keys Compliance Notification",
            Message="All IAM user passwords and access keys are compliant (within 90 days)."
        )

    return {
        'statusCode': 200,
        'body': 'Lambda function executed successfully!'
    }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;7.Deploy and Test&lt;/strong&gt;&lt;br&gt;
Click &lt;strong&gt;“Deploy”&lt;/strong&gt;, then &lt;strong&gt;“Test”&lt;/strong&gt; to execute the function.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verify the function runs successfully.&lt;/li&gt;
&lt;li&gt;You should receive an &lt;strong&gt;SNS email notification&lt;/strong&gt; indicating whether any IAM credentials have expired.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3: Create an Amazon EventBridge Scheduler
&lt;/h3&gt;

&lt;p&gt;The final step is to automate the Lambda function’s execution using &lt;strong&gt;Amazon EventBridge Scheduler&lt;/strong&gt;. This ensures that the IAM credential checks run on a regular basis without manual triggers.&lt;/p&gt;

&lt;p&gt;🧭&lt;strong&gt;Steps:&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;1.Open EventBridge in the AWS Console&lt;/strong&gt;&lt;br&gt;
Navigate to &lt;strong&gt;Amazon EventBridge&lt;/strong&gt; from the AWS Management Console.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.Access the Scheduler&lt;/strong&gt;&lt;br&gt;
In the left-hand menu, click on &lt;strong&gt;“Schedules.”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.Create a New Schedule&lt;/strong&gt;&lt;br&gt;
Click &lt;strong&gt;“Create schedule”&lt;/strong&gt; to start configuring your recurring rule.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4.Configure Schedule Details&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name&lt;/strong&gt;: Provide scheduler name&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Description&lt;/strong&gt;: Add a short description for reference.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Schedule Group&lt;/strong&gt;: Select Default.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Schedule Pattern&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Occurrence: Recurring schedule&lt;br&gt;
 Time zone: select based on timezone&lt;br&gt;
 Schedule type: Cron-based schedule&lt;br&gt;
 Cron expression: Example —cron(0 10 ? * 6 *)&lt;br&gt;
    This runs the Lambda function every Saturday at 10:00 AM.&lt;br&gt;
 Flexible time window: Off&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5.Set the Target Service&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Under Target, choose &lt;strong&gt;AWS Lambda function&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Select the Lambda function you created in the previous step.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;6.Assign Required Permissions&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;EventBridge needs permission to invoke the Lambda function.&lt;/li&gt;
&lt;li&gt;Use an existing IAM role or create a new one that allows &lt;strong&gt;lambda:InvokeFunction&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;7.Review and Create&lt;/strong&gt;&lt;br&gt;
Click Next, review your configuration, and then select &lt;strong&gt;“Create schedule.”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Your EventBridge Scheduler is now live and will automatically trigger the Lambda function on the defined schedule — keeping your IAM credential monitoring continuous and effortless.&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By automating IAM user password and access key expiry notifications using &lt;strong&gt;AWS Lambda, Amazon EventBridge, and Amazon SNS,&lt;/strong&gt; you can proactively maintain account security without manual oversight. This serverless approach ensures timely alerts, reduces the risk of credential misuse, and keeps your AWS environment compliant with best practices — all while staying simple, scalable, and cost-effective.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>security</category>
      <category>serverless</category>
      <category>automation</category>
    </item>
  </channel>
</rss>
