Skip to main content

Lambda Function Setup Guide for IAM Event Notifications in Slack

 

Overview

This document provides a step-by-step guide to creating a Lambda function that sends notifications to Slack when:

  • A new IAM user is created.
  • A permission (policy) is attached to an IAM user.

  • Lambda Function Setup Guide for IAM Event Notifications in Slack

Prerequisites

  1. AWS Account with necessary permissions to create and configure Lambda, IAM, CloudTrail, and CloudWatch Logs.
  2. Slack workspace with permissions to create a new app and generate an incoming webhook URL.

Architecture

 IAM event -> CloudTrail -> CloudWatch Logs -> Lambda Function -> Slack

[Good Read: Step-by-Step Guide to Cloud Migration With DevOps ]

Step 1: Setup CloudTrail

  1. Go to CloudTrail Console:
  • Navigate to the AWS Management Console.
  • Go to the CloudTrail service.

2. Create or Configure a Trail:

  • Create a new trail or use an existing one.
  • Ensure that the trail is configured to log management events.
  • Enable the trail to send logs to CloudWatch Logs.

Step 2: Setup CloudWatch Logs

  1. Create Log Group:
  • Navigate to CloudWatch in the AWS Management Console.
  • Create a new log group or use an existing one to receive CloudTrail logs

Step 3: Create Lambda Function

  1. Create a Lambda Function:
  • Go to the AWS Lambda Console.
  • Create a new Lambda function with a suitable name, runtime (Python 3.8+), and role with the necessary permissions.

2. Add the Following Code:

import json

import os

import base64

import gzip

import urllib3

webhook_url = os.environ.get('WEBHOOK_URL')

def send_slack_message(message):

    http = urllib3.PoolManager()

    payload = {

        "blocks": message

    }

    encoded_payload = json.dumps(payload).encode('utf-8')

    response = http.request(

        'POST',

        webhook_url,

        body=encoded_payload,

        headers={'Content-Type': 'application/json'},

    )

    return response.status

def create_slack_message(event_detail):

    event_name = event_detail['eventName']

    actor_name = event_detail['userIdentity']['userName']

    if event_name == 'CreateUser':

        user_name = event_detail['requestParameters']['userName']

        title = "New IAM User Created"

        message = f"A new IAM user `{user_name}` has been created by `{actor_name}`."

        color = "#36a64f"

    elif event_name in ['AttachUserPolicy', 'PutUserPolicy']:

        user_name = event_detail['requestParameters']['userName']

        policy_name = event_detail['requestParameters']['policyArn']

        title = "Policy Attached to IAM User"

        message = f"Policy `{policy_name}` has been attached to user `{user_name}` by `{actor_name}`."

        color = "#FFA500"

    slack_message = [

        {

            "type": "section",

            "text": {

                "type": "mrkdwn",

                "text": f":rotating_light: *{title}* :rotating_light:"

            }

        },

        {

            "type": "section",

            "fields": [

                {

                    "type": "mrkdwn",

                    "text": f"*Event Name:*\n{event_name}"

                },

                {

                    "type": "mrkdwn",

                    "text": f"*User Name:*\n{user_name}"

                },

                {

                    "type": "mrkdwn",

                    "text": f"*Performed By:*\n{actor_name}"

                }

            ]

        },

        {

            "type": "section",

            "text": {

                "type": "mrkdwn",

                "text": message

            }

        },

        {

            "type": "divider"

        }

    ]

    return slack_message

def parse_event(event):

    if 'awslogs' in event:

        log_data = event['awslogs']['data']

        compressed_payload = base64.b64decode(log_data)

        uncompressed_payload = gzip.decompress(compressed_payload)

        log_events = json.loads(uncompressed_payload)['logEvents']

        for log_event in log_events:

            message = log_event['message']

            log_entry = json.loads(message)

            if log_entry['eventName'] in ['CreateUser', 'AttachUserPolicy', 'PutUserPolicy']:

                slack_message = create_slack_message(log_entry)

                send_slack_message(slack_message)

def lambda_handler(event, context):

    try:

        parse_event(event)

    except Exception as e:

        print(f"Error parsing event: {e}")

    return {

        'statusCode': 200,

        'body': json.dumps('Notification sent!')

    }

# Example test event

if __name__ == "__main__":

    test_event = {

        'awslogs': {

            'data': base64.b64encode(gzip.compress(json.dumps({

                'logEvents': [

                    {

                        'message': json.dumps({

                            'eventName': 'CreateUser',

                            'requestParameters': {

                                'userName': 'NewTestUser'

                            },

                            'userIdentity': {

                                'userName': 'AdminUser',

                            }

                        })

                    }

                ]

            }).encode())).decode()

        }

    }

    lambda_handler(test_event, None)

Set Environment variable

  • Set the WEBHOOK_URL environment variable to the Slack webhook URL you created.

Step 4: Configure CloudWatch Logs Filter Pattern

  1. Create Metric Filter:
  • Go to the CloudWatch Console.
  • Select the log group that receives CloudTrail logs.
  • Create a new metric filter with the following pattern:
  • { ($.eventName = “CreateUser”) || ($.eventName = “AttachUserPolicy”) || ($.eventName = “PutUserPolicy”) }
  • Provide a name for the filter and configure it.

Step 5: Add CloudWatch Logs Trigger to Lambda

  1. Add Trigger:
  • Go to the Lambda Console.
  • Select your Lambda function.
  • In the “Function overview” section, click “Add trigger”.
  • Select “CloudWatch Logs” as the trigger type.
  • Choose the log group that contains the CloudTrail logs.
  • Specify the filter pattern created earlier.
  • Click “Add”.

Step 6: Test the Setup

  1. Generate Test Events:
  • Create a new IAM user or attach a policy to an existing user to generate test events.

2. Verify Slack Notifications:

  • Check your Slack channel to ensure notifications are being received as expected.

You can check more info about: Lambda Function Setup Guide for IAM Event Notifications in Slack.

Comments

Popular posts from this blog

How to Perform Penetration Testing on IoT Devices: Tools & Techniques for Business Security

The Internet of Things (IoT) has transformed our homes and workplaces but at what cost?   With billions of connected devices, hackers have more entry points than ever. IoT penetration testing is your best defense, uncovering vulnerabilities before cybercriminals do. But where do you start? Discover the top tools, techniques, and expert strategies to safeguard your IoT ecosystem. Don’t wait for a breach, stay one step ahead.   Read on to fortify your devices now!  Why IoT Penetration Testing is Critical  IoT devices often lack robust security by design. Many run on outdated firmware, use default credentials, or have unsecured communication channels. A single vulnerable device can expose an entire network.  Real-world examples of IoT vulnerabilities:   Mirai Botnet (2016) : Exploited default credentials in IP cameras and DVRs, launching massive DDoS attacks. Stuxnet (2010): Targeted industrial IoT systems, causing physical damage to nuclear centrifu...

Infrastructure-as-Prompt: How GenAI Is Revolutionizing Cloud Automation

Forget YAML sprawl and CLI incantations. The next frontier in cloud automation isn't about writing more code; it's about telling the cloud what you need. Welcome to the era of Infrastructure-as-Prompt (IaP), where Generative AI is transforming how we provision, manage, and optimize cloud resources. The Problem: IaC's Complexity Ceiling Infrastructure-as-Code (IaC) like Terraform, CloudFormation, or ARM templates revolutionized cloud ops. But it comes with baggage: Steep Learning Curve:  Mastering domain-specific languages and cloud provider nuances takes time. Boilerplate Bloat:  Simple tasks often require verbose, repetitive code. Error-Prone:  Manual coding leads to misconfigurations, security gaps, and drift. Maintenance Overhead:  Keeping templates updated across environments and providers is tedious. The Solution: GenAI as Your Cloud Co-Pilot GenAI models (like GPT-4, Claude, Gemini, or specialized cloud models) understand n...

How Security-First CI/CD Pipelines Help Mitigate Business Risk

Businesses today must adapt quickly, rolling out software updates and new features at an unprecedented pace. To accomplish this, many turn to Continuous Integration and Continuous Delivery (CI/CD) pipelines. However, this pursuit of speed can introduce significant security risks if it's not approached with caution. This is where the concept of DevSecOps comes into play. It’s an essential strategy for organizations aiming to strike the right balance between speed and security. Historically, security has often been an afterthought, resulting in delays and making systems more vulnerable to cyber threats. DevSecOps changes this narrative by embedding security practices within every stage of the software development lifecycle. In this blog, we will delve into the tangible ROI of adopting DevSecOps , highlighting how a security-first mindset in CI/CD not only minimizes business risks but also reduces downtime and leads to measurable cost savings. Additionally, we’ll examine how automatin...