Table of contents
Introduction
As part of my role, I am responsible for ensuring that our business adheres to the AWS Well-Architected Framework. During a recent review, I discovered that we were not meeting one of the framework's requirements.
You must have monitoring and alerting in place to identify when S3 buckets become public. Bucket permissions that grant Upload/Delete access to everyone create potential security vulnerabilities by allowing anyone to add, modify, or remove items in a bucket.
Why Slack?
If enabled, AWS Cloud Trail will log any API calls for S3 that invoke public access:
eventName": ["DeleteBucketPolicy", "PutBucketAcl", "PutBucketPolicy", "DeleteBucketPublicAccessBlock", "PutBucketPublicAccessBlock"]
One could argue that's the answer, events logged, a requirement met ๐.
However let's be honest, who sits and watches CloudTrail logs? Not me!
I decided early on to leverage SNS to achieve alerting, then given my hatred of emails, Slack was my obvious preference for receiving them.
Deploying:
To create the solution, I divided it into four main components:
Easy setup across multiple regions
EventBridge to capture alerts
SNS to send alerts
Chatbot to deliver alerts to Slack
Since the S3 bucket location, EventBridge Rules, and SNS Topics are specific to regions, we needed to pre-deploy each service in all six regions we operate in. While manually creating an EventBridge rule and SNS topic for each region is not a difficult administrative task, I decided to utilize CloudFormation to automate the deployment and integration of these services.
To ensure seamless integration of these services, I separated each service into its own CloudFormation template. This approach allowed us to deploy the SNS topic first before providing its Amazon Resource Name (ARN) to our EventBridge rule.
CloudFormation Parent Stack
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
TemplateURL:
Description: URL of nested stack template
Type: String
Resources:
SNSTopicStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: !Ref TemplateURL
TimeoutInMinutes: 5
EventsRule:
Type: "AWS::Events::Rule"
Properties:
Name: "S3PublicAccess"
EventPattern: |
{
"source": ["aws.s3"],
"detail-type": ["AWS API Call via CloudTrail"],
"detail": {
"eventSource": ["s3.amazonaws.com"],
"eventName": ["DeleteBucketPolicy", "PutBucketAcl", "PutBucketPolicy", "DeleteBucketPublicAccessBlock", "PutBucketPublicAccessBlock"]
}
}
State: "ENABLED"
Targets:
-
Arn: !GetAtt SNSTopicStack.Outputs.SNSTopicARN
Id: Slackbot
EventBusName: "default"
Chatbot:
Type: AWS::Chatbot::SlackChannelConfiguration
Properties:
SNSTopicArns: !GetAtt SNSTopicStack.Outputs.SNSTopicARN
SNS Topic Child Stack
AWSTemplateFormatVersion: "2010-09-09"
Resources:
SNSTopic:
Type: "AWS::SNS::Topic"
Properties:
DisplayName: "SlackBot"
TopicName: "SlackBot"
Outputs:
SNSTopicARN:
Value: !Ref SNSTopic
Description: ARN for SNS Topic
AWS Chatbot
AWS Chatbot is an interactive agent that makes it easy to monitor, operate, and troubleshoot your AWS workloads in your chat channels. With AWS Chatbot, you can receive alerts, run commands to retrieve diagnostic information, configure AWS resources, and initiate workflows.
Installing and configuring AWS Chatbot in Slack is pretty straightforward, simply install the Slack app and follow the prompts
You can install it from here > slack.com/apps/A6L22LZNH-aws-chatbot?tab=mo..
Chatbot will live in one region of your choice and receive SNS topic updates from all regions you provision.
Success!
If everything deployed correctly you should start receiving notifications in your chosen Slack channel when an S3 public access is changed ๐