A serverless AWS security monitoring stack that detects and alerts on any AWS root account console login — in real time.
Root account logins are a high-severity security signal. This project wires together CloudTrail, EventBridge, Lambda, and SNS to ensure every root login triggers an immediate email alert, with zero polling or manual log digging.
Architecture
- Root user logs in to the AWS console.
- CloudTrail records the
ConsoleLoginevent and writes it to an S3 bucket. CloudTrail is configured as a multi-region trail so logins from any region are captured. - EventBridge continuously evaluates CloudTrail events against a rule that matches
aws.signinevents whereuserIdentity.typeisRoot. All other logins are ignored. - When the rule matches, EventBridge invokes the Lambda function with the full event payload.
- Lambda (
handler.py) parses the event — extracting account ID, region, source IP, user agent, timestamp, and whether the login succeeded — and formats a plain-English alert message. - Lambda publishes the alert to the SNS topic.
- SNS delivers the message to all subscribed endpoints. The default subscription is email.
- The security team receives an email within seconds of the root login occurring.
- All Lambda execution logs are shipped to CloudWatch Logs and retained for 7 days for post-incident review.
| Resource | Name | Purpose |
|---|---|---|
aws_cloudtrail |
{project_name}-trail |
Captures all API & console events across all regions |
aws_s3_bucket |
{project_name}-cloudtrail-logs-{account_id} |
Stores raw CloudTrail log files |
aws_cloudwatch_event_rule |
{project_name}-rule |
EventBridge rule filtering root logins |
aws_lambda_function |
{project_name}-notifier |
Parses event and publishes the alert |
aws_sns_topic |
{project_name}-alerts |
Fan-out alert delivery |
aws_sns_topic_subscription |
Delivers alerts to the configured email address | |
aws_cloudwatch_log_group |
/aws/lambda/{project_name}-notifier |
Lambda execution logs (7-day retention) |
aws_iam_role |
{project_name}-lambda_role |
Lambda execution role (SNS publish + CloudWatch Logs) |
- Terraform >= 1.0
- AWS credentials configured (
aws configureor environment variables) - An IAM user or role with permissions to create the resources above
git clone <repo-url>
cd iam-root-login-observabilityEdit terraform.tfvars:
aws_region = "us-east-1"
project_name = "root-login-observability"
notification_email = "your-security-team@example.com"Or pass them at apply time:
terraform apply \
-var="notification_email=your-security-team@example.com" \
-var="aws_region=us-east-1"terraform init
terraform plan
terraform applyAfter apply completes, AWS sends a confirmation email to the address you provided. You must click the confirmation link before alerts will be delivered.
terraform destroy| Name | Description | Default |
|---|---|---|
aws_region |
AWS region to deploy resources | us-east-1 |
project_name |
Prefix used for all resource names | root-login-observability |
notification_email |
Email address that receives root login alerts | (required) |
| Name | Description |
|---|---|
sns_topic_arn |
ARN of the SNS alert topic |
lambda_function_name |
Name of the Lambda notifier function |
cloudtrail_name |
Name of the CloudTrail trail |
When a root login is detected, the email looks like this:
Subject: AWS Root Account Login Detected
ROOT ACCOUNT LOGIN DETECTED
Account ID : 123456789012
Region : us-east-1
Time : 2026-05-14T08:32:11Z
Source IP : 203.0.113.42
User Agent : Mozilla/5.0 (Macintosh; ...)
Login Result: Success
Root account usage is discouraged. If this was not you,
immediately rotate your credentials and review your account.
This alert was generated by the IAM Root Login Observability stack.
- The S3 bucket enforces
bucket-owner-full-controlon all CloudTrail writes and blocks public access by default via the bucket policy. - The Lambda IAM role follows least privilege — it can only publish to this specific SNS topic and write to CloudWatch Logs.
- CloudTrail has log file validation enabled, so log tampering can be detected.
- The EventBridge rule only matches root logins; no other IAM activity triggers the alert.
- For production use, consider enabling S3 bucket versioning and MFA delete on the CloudTrail log bucket.
.
├── main.tf # All AWS resources (CloudTrail, EventBridge, Lambda, SNS, IAM)
├── variables.tf # Input variable declarations
├── outputs.tf # Stack outputs
├── terraform.tfvars # Variable values (do not commit secrets)
└── lambda/
└── handler.py # Lambda function — parses event, sends SNS alert
