AI Security Scanner for AWS S3
Scan S3 buckets for encryption vulnerabilities and get AI-powered security insights
Introduction
This project has been archived
We're no longer updating this project - we recommend checking out our active projects instead!
If you've already completed this project, don't worry! Your documentation is still available for you to check out and share.
If you have any questions, leave a question in our Discord and we'll get back to you ASAP!
⚡️ 30 Second Summary
Data leaks from poorly set up cloud storage make up 60% of all cloud security breaches. How does this happen? It only takes one wrongly configured S3 bucket for customer information or internal files to be exposed to people who should never see them.
So what are companies doing about it? Instead of relying on manual fixes, companies like Netflix, Capital One, and Lyft build automated security systems - they use AI to detecting encryption issues, explain WHY certain builds are risky, and even fix the issue.
What you'll build
In this project, you'll build a similar security monitoring system: a serverless Lambda function that scans S3 bucket encryption, sends its findings to Gemini AI for analysis, and shows you intelligent security insights. Then we'll schedule it to run automatically every 12 hours using EventBridge.
Prerequisite
You'll need an AWS account with IAM permissions for this project. If you don't have an AWS account already, complete the AWS Account Setup project before starting.
By the end of this project, you'll have:
- A Lambda function that scans S3 buckets for encryption using the S3 API.
- AI-powered security analysis with Gemini AI that explains encryption vulnerabilities in plain English.
- Verified AI output showing intelligent security insights directly in the AWS Console.
- 💎 Secret Mission: Automated scanning every 12 hours using EventBridge - continuous monitoring without manual testing.
Want a complete demo of how to do this project, from start to finish? Check out our 🎬 walkthrough with Kahu 🎬
No serverless experience needed!
This project guides you through everything step-by-step. You'll learn Lambda, EventBridge, and AI integration as you build.
Not sure if this project is right for you? Check if it matches your goals
If you're up for a bit of a challenge, quiz yourself on the key concepts up ahead in this project.
Set Up Gemini and Cursor
Alright! Let's assemble our ingredients for our AI Security Scanner.
Ingredient number one is a scanner. Our scanner will scan S3 buckets for encryption issues. We'll create this using Cursor and a Lambda function in AWS.
Ingredient number two is access to Gemini so we can translate the output from our scanner into recommendations of what to do. Let's get into it.
In this step, you're going to:
- Get access to Gemini using a Gemini API key from Google AI Studio.
- Create the project folder in Cursor.
- Write our scanner code, ready to deploy to Lambda.
Get Your Gemini API Key
No-one likes the account creation fluff. Let's get all the login, account creation shinangins out of the way.
Starting with our Gemini API key.
What is Gemini?
Gemini is Google's large language model. You're using it to transform the raw security findings from your scanner into actionable explanations.
For example, instead of seeing:
- bucket-xyz: not encrypted, you'll see:
- Enable encryption on bucket-xyz to protect data at rest.
💡 ...and why do we need an API key?
Gemini's API key will let your scanner use Gemini's API. It's literally the key to using Gemini in our app. Even better, Google provides free tier access for this project.
- Open your web browser and go to https://aistudio.google.com/.
✔️ I'm already logged in
- In the left sidebar, click Get API key.
ⓧ Nope, not logged in!
- Click Get started.
✔️ I have a Google account
- Click on your existing Google account to sign in.
- After signing in, you'll be on the Google AI Studio dashboard.
ⓧ I need a Google account
- Click Use another account.
- Click Create account.
✔️ Account created successfully
- After creating your account, you'll be on the Google AI Studio dashboard.
ⓧ What is going on...
If you're having trouble:
- Make sure you're using a valid email address.
- Check your email for a verification link if prompted.
- Try using a different browser if the form isn't working.
Still having issues?
Get help with Google account creation
- In the top right, click Create API key.
- A dialog will appear to create your API key.
- In the name field, enter Amazon S3 Security Scanner.
- Click on the Choose an imported project dropdown.
- Select Create project.
- In the project name field, enter NextWork Lambda S3 Project (this helps you identify what you created this API key for later).
- Click Create project.
- Click Create key.
Nice! Our API key is all set up and ready to go.
- Click the Copy icon next to your key to copy it.
- Now paste your API key into this variable - you'll use it later when configuring your Lambda function:
GOOGLE_API_KEY=[[GOOGLE_API_KEY="paste-your-gemini-api-key-here"]]
Keep your API key secure!
Don't share your API key publicly or commit it to version control. You'll store it securely as a Lambda environment variable later.
Create Project Folder in Cursor
Now that you have your API key for Gemini, let's set up your project folder and open it in Cursor. We'll use this to write the code for our scanner.
✅ I have Cursor
Open Cursor from your Applications (Mac) or Start menu (Windows).
🆕 I need to install it
- Download from cursor.com/downloads.
- macOS: Open the .dmg and drag Cursor to Applications.
- Windows: Run the .exe installer and click through the setup wizard.
- Open Cursor.
- From the home screen of Cursor, click Open Project.
- Navigate to your Desktop.
- Click New Folder and name it aws-monitor-gemini.
- Select the aws-monitor-gemini folder.
- Click Select Folder.
Create File for Lambda Function Code
In Cursor, create a new file called s3_scanner.py.
- Right-click in the file explorer.
- Click New File.
- Name it s3_scanner.py.
We're going to build this Lambda function in two parts - first scanning S3 buckets, then adding the encryption analysis. This way you can understand each piece before moving to the next.
Create Scanner
This is the big milestone! Can we write the code for a scanner that will scan S3 buckets, identify security faults, send it's findings to Gemini, AND send back suggestions on how to fix them?
I believe in you! Let's get it!
The first part we need to work out is how to scan S3 buckets. Diving into the deep end...
Part 1: Scan S3 Buckets
- Let's start by adding code that connects to Amazon S3 and lists all your buckets.
- Add the following code to your s3_scanner.py file:
import boto3
import json
import os
import google.generativeai as genai
def lambda_handler(event, context):
"""Scan S3 buckets for encryption and use AI to explain risks"""
# Initialize S3 client
s3_client = boto3.client('s3')
print("Scanning S3 buckets for encryption...")
# Get all S3 buckets
response = s3_client.list_buckets()
buckets = response['Buckets']
print(f"Found {len(buckets)} buckets to scan\n")
# Store results
scan_results = []
for bucket in buckets:
bucket_name = bucket['Name']
# We'll add the encryption check logic next
- This first part connects to Amazon S3, lists all your buckets, and prepares to check each one.
What does Part 1 do?
- import boto3, json, os, google.generativeai - Loads the libraries we need (AWS SDK, JSON formatting, environment variables, Gemini AI)
- lambda_handler(event, context) - The function AWS Lambda calls when your code runs
- boto3.client('s3') - Creates an S3 client that connects to AWS using your credentials
- s3_client.list_buckets() - Makes an API call to get all S3 buckets in your account
- buckets = response['Buckets'] - Extracts the list of buckets from AWS's response
- for bucket in buckets: - Loops through each bucket so we can check it individually
- scan_results = [] - Creates an empty list to store encryption check results
Part 2: Add Encryption Check and AI Analysis
- Now let's add the logic that checks each bucket for encryption AND uses AI to analyze the security risks.
- In your s3_scanner.py file, find this line:
# We'll add the encryption check logic next
- Delete that comment line and replace it with this encryption check AND AI analysis code:
Important: Watch your indentation!
The new code should be aligned at the same level as the comment you're replacing (8 spaces from the left edge - inside the for loop). Python is very sensitive to indentation - if it's wrong, the code won't run.
# Check if bucket has encryption enabled
try:
encryption = s3_client.get_bucket_encryption(Bucket=bucket_name)
encrypted = True
encryption_type = encryption['ServerSideEncryptionConfiguration']['Rules'][0]['ApplyServerSideEncryptionByDefault']['SSEAlgorithm']
except s3_client.exceptions.ServerSideEncryptionConfigurationNotFoundError:
encrypted = False
encryption_type = 'None'
# Store result
scan_results.append({
'bucket_name': bucket_name,
'encrypted': encrypted,
'encryption_type': encryption_type
})
status = "Encrypted" if encrypted else "Not Encrypted"
print(f"{status}: {bucket_name} ({encryption_type})")
# Count unencrypted buckets
unencrypted_count = len([r for r in scan_results if not r['encrypted']])
unencrypted_buckets = [r['bucket_name'] for r in scan_results if not r['encrypted']]
# Use AI to analyze security findings
print("\nAnalyzing security findings with Gemini AI...")
# Configure Gemini
api_key = os.environ.get('GOOGLE_API_KEY')
if not api_key:
ai_analysis = "AI analysis skipped: GOOGLE_API_KEY not configured"
else:
genai.configure(api_key=api_key)
model = genai.GenerativeModel("gemini-2.0-flash-exp")
prompt = f"""You are an AWS security expert. Analyze this S3 encryption scan and provide a brief security assessment.
Scan Results:
- Total Buckets: {len(buckets)}
- Encrypted: {len(buckets) - unencrypted_count}
- Unencrypted: {unencrypted_count}
- Unencrypted Bucket Names: {', '.join(unencrypted_buckets) if unencrypted_buckets else 'None'}
Provide a 2-3 sentence analysis:
1. What's the security risk of unencrypted buckets?
2. What encryption should be enabled? (AES256 or aws:kms)
3. What action should the user take immediately?
Be concise and actionable."""
try:
response = model.generate_content(prompt)
ai_analysis = response.text
except Exception as e:
ai_analysis = f"AI analysis failed: {str(e)}"
# Build final result
result = {
'total_buckets': len(buckets),
'unencrypted_buckets': unencrypted_count,
'encrypted_buckets': len(buckets) - unencrypted_count,
'scan_results': scan_results,
'ai_analysis': ai_analysis,
'alert': unencrypted_count > 0
}
print(f"\nScan complete: {unencrypted_count}/{len(buckets)} buckets need encryption")
return {
'statusCode': 200,
'body': json.dumps(result)
}
- Once you've replaced the comment with the code above, your complete s3_scanner.py file should now include the second part:
What does Part 2 add?
Encryption Checking:
This section loops through all your S3 buckets and checks if each one has encryption enabled. It builds a list of findings that we'll analyze with AI.
- try...except - Attempts to get encryption configuration; if bucket has no encryption, catches the error gracefully.
- s3_client.get_bucket_encryption() - Retrieves the encryption configuration for this bucket.
- SSEAlgorithm - Extracts the encryption type (AES256, aws:kms, etc.) from AWS's nested response.
- scan_results.append({...}) - Adds this bucket's results to the list.
- unencrypted_count - Counts how many buckets lack encryption.
AI Analysis:
This section takes the raw scan results and sends them to Gemini AI. The AI transforms technical findings into plain-English security recommendations that explain the impact and urgency.
- os.environ.get('GOOGLE_API_KEY') - Retrieves your Gemini API key from Lambda environment variables (you'll configure this later).
- genai.configure() - Sets up the Gemini AI client with your API key.
- model.generate_content(prompt) - Sends scan results to Gemini and asks for security analysis.
- ai_analysis - Stores Gemini's plain-English security recommendations.
- Error handling ensures scanner works even if AI fails.
- Perfect! Your Lambda function now has the complete encryption scanning AND AI analysis logic.
Deploy to AWS Lambda
Now that you've written your AI-powered S3 scanner code, it's time to deploy it to AWS Lambda. You'll package your code with dependencies, create IAM permissions, deploy the Lambda function, and test it.
What's the architecture we're deploying?
Your security scanner has three main AWS components:
- Lambda - Runs your Python code
- S3 API - Provides bucket encryption data
- IAM - Permissions management
You'll package your code into a zip file, upload it to Lambda, and attach an IAM role that grants Lambda permission to read S3 bucket configurations. Lambda runs in a serverless environment - you don't manage servers, you just upload code and AWS executes it when needed.
In this step, you're going to:
- Package the Lambda function with dependencies.
- Deploy the Lambda function to AWS.
- Test the AI-powered S3 security scanner.
Package Lambda for Deployment
Lambda needs dependencies bundled in a zip file.
In Cursor, create a new file called requirements.txt:
What does requirements.txt mean? Why do we create this?
requirements.txt is a Python convention that lists all the external libraries your project needs. When you deploy to Lambda, this file tells AWS which packages to install. These are the two libraries your Lambda function needs: boto3 (AWS's Python SDK for accessing S3) and google-generativeai (for calling Gemini AI). You don't install them locally because Lambda will install them from this file when you deploy.
- Right-click in the file explorer.
- Click New File.
- Name it requirements.txt.
Add this content:
boto3
google-generativeai
- Save the file (Cmd+S on Mac or Ctrl+S on Windows).
Why do we need to package dependencies?
Lambda runs in a sandboxed environment without pre-installed Python packages. When you deploy a Lambda function, you need to include all the libraries your code imports. The requirements.txt file lists the dependencies: boto3 (AWS SDK for S3 scanning) and google-generativeai (Gemini AI for security analysis). Pip installs them to a local folder, then you zip everything together so Lambda has access to both your code and its dependencies. This packaging pattern is standard for all serverless deployments.
Install dependencies to a package folder.
Open a terminal in Cursor by clicking Terminal → New Terminal from the top menu (or press Ctrl+` on Windows / Cmd+` on macOS).
The terminal automatically opens in your aws-monitor-gemini project folder.
Set Up Your Python Virtual Environment
Before installing packages, let's create a virtual environment to keep your project dependencies isolated.
What is a virtual environment?
A virtual environment is like a separate workspace for your Python project. It keeps all your project's packages isolated from other projects, so they don't interfere with each other. Think of it as a sandbox where you can install whatever you need without affecting your computer's main Python setup.
Create a virtual environment:
python -m venv venv
You should see a new venv folder appear in your project directory.
Activate the virtual environment:
🍎 macOS/Linux
source venv/bin/activate
You should see (venv) appear at the beginning of your terminal prompt.
🖼️ Windows
venv\Scripts\activate
You should see (venv) appear at the beginning of your terminal prompt.
Make sure your virtual environment is activated!
You should see (venv) at the beginning of your terminal prompt. This tells you that your virtual environment is active and ready to use.
Check if pip is installed:
pip --version
✅ I see a version number
Great! Pip is installed. Now install the dependencies:
🍎 macOS/Linux
mkdir package
pip install --target ./package boto3 google-generativeai
You should see pip downloading and installing both packages and their dependencies.
🖼️ Windows
mkdir package
pip install --platform manylinux2014_x86_64 --target ./package --implementation cp --python-version 3.12 --only-binary=:all: -r requirements.txt
Why the extra flags on Windows?
Lambda runs on Linux. The --platform flag tells pip to download Linux-compatible package versions instead of Windows binaries. Without this, your Lambda will fail with import errors.
You should see pip downloading and installing both packages with Linux-compatible binaries.
❌ Command not found
You need to install Python and pip first.
🍎 macOS
Install Python using Homebrew:
brew install python3
Verify installation:
python3 --version
pip3 --version
Now install dependencies (use pip3 instead of pip):
mkdir package
pip3 install --target ./package boto3 google-generativeai
🖼️ Windows
Download Python from python.org:
- Go to https://www.python.org/downloads/.
- Download Python 3.12 for Windows.
- Run the installer.
- Check "Add Python to PATH" during installation.
- Click Install Now.
- After installation completes, close and reopen PowerShell.
Verify installation:
python --version
pip --version
Now install dependencies:
mkdir package
pip install --platform manylinux2014_x86_64 --target ./package --implementation cp --python-version 3.12 --only-binary=:all: -r requirements.txt
Why the extra flags on Windows?
Lambda runs on Linux. The --platform flag tells pip to download Linux-compatible package versions instead of Windows binaries. Without this, your Lambda will fail with import errors.
Add your code to the package and create a zip file.
🍎 macOS/Linux
Run these commands in Terminal:
cp s3_scanner.py package/
cd package
zip -r ../s3_scanner.zip .
cd ..
What do these commands do?
- cp s3_scanner.py package/ - Copies your scanner code into the package folder
- cd package - Navigates into the package folder
- zip -r ../s3_scanner.zip . - Creates a zip file containing everything in this folder
- cd .. - Returns to the parent directory
You should see the files being added to the zip archive.
🖼️ Windows
Run this command in PowerShell:
Copy-Item s3_scanner.py package/
Compress-Archive -Path package\* -DestinationPath s3_scanner.zip -Force
You should see s3_scanner.zip created in your project folder.
Create S3 Encryption Read Policy
Your Lambda function needs permission to read S3 bucket encryption configurations. Let's create a policy that grants exactly those permissions.
- Log into the AWS Console (if you haven't already).
- In the top search bar, search for IAM.
What is IAM? What are policies?
IAM (Identity and Access Management) controls who can do what in AWS. Policies are JSON documents that define specific permissions - like "can read S3 buckets" or "can write to CloudWatch Logs". You'll create a policy that grants Lambda exactly the S3 permissions it needs.
- Hover over IAM in the search results.
- Click Policies under Features.
You'll see the IAM Policies page with all existing policies.
- Click Create policy in the top right.
- Click the JSON tab.
- Delete all existing text in the editor.
- Paste this JSON policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets",
"s3:GetEncryptionConfiguration"
],
"Resource": "*"
}
]
}
What does this policy do?
- s3:ListAllMyBuckets - Retrieves the list of all S3 buckets in your account
- s3:GetEncryptionConfiguration - Reads the encryption configuration for each bucket
- Resource: "*" - Lambda can read encryption settings for all buckets in your account
- IAM policies use JSON format - Effect: "Allow" grants access, and Action lists the specific API calls Lambda can make.
🙋♀️ Wait! I see a "prohibited whitespace" error
This happens if you accidentally copied extra spaces before or after the JSON. Delete everything in the editor again, then carefully paste ONLY the JSON code (starting with { and ending with }). Make sure there are no spaces before the opening { or after the closing }.
- Click Next at the bottom of the page.
Now you'll name your policy.
- In the Policy name field, type S3EncryptionReadPolicy.
- Scroll down and click Create policy.
Perfect! Your policy was created successfully.
Create IAM Role for Lambda
Now you'll create the IAM role that Lambda will assume when it runs. This role will have the S3 Encryption Read policy you just created, plus CloudWatch logging permissions.
- In the AWS Console, search for IAM again.
- Click Roles in the search results.
You'll see the IAM Roles page showing all existing roles.
- Click Create role in the top right.
What is a role? Why do we need one?
A role is a set of permissions that AWS services can assume. Lambda needs a role to access other AWS services on your behalf. Instead of giving Lambda permanent credentials, you create a role with specific permissions that Lambda temporarily assumes when it runs.
Now you'll configure who can use this role.
- Select Custom trust policy.
What is a custom trust policy?
A trust policy defines which AWS services can assume this role. You're creating a custom one to specifically allow Lambda.
- Delete the existing JSON.
- Paste this trust policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
What does this trust policy code do?
This policy allows Lambda (lambda.amazonaws.com) to assume this role. The sts:AssumeRole action grants Lambda permission to use the role's permissions when executing your function.
- Click Next at the bottom.
Now you'll attach permissions to this role. You need two policies: your custom S3 encryption policy and AWS's logging policy.
What is AWS's logging policy?
AWS's logging policy (AWSLambdaBasicExecutionRole) allows Lambda to write logs to CloudWatch so you can debug your function. Without this, you won't be able to see execution logs or errors.
- In the search box, type S3EncryptionReadPolicy.
- Check the box next to S3EncryptionReadPolicy.
- Clear the search box.
- Type AWSLambdaBasicExecutionRole.
- Check the box next to AWSLambdaBasicExecutionRole.
Why AWSLambdaBasicExecutionRole?
This AWS-managed policy gives Lambda permission to write logs to CloudWatch. When your function runs, you'll be able to see print statements and errors in CloudWatch Logs - essential for debugging!
You should see both policies selected.
- Click Next.
Now you'll name your role.
- In the Role name field, type LambdaS3ScannerRole.
- Scroll down and verify both policies are listed under Permissions policies.
- Click Create role at the bottom.
You should see a green success banner confirming your role was created!
Excellent! Your IAM role is now ready. Lambda can now scan S3 bucket encryption and write logs to CloudWatch.
- Click View role on the right side of the green success banner to see your role's details.
Deploy and Test Lambda
Now that your code is packaged and permissions are configured, you'll deploy the Lambda function to AWS, configure it with your Gemini API key, and test the AI-powered security scanner.
In this step, you're going to:
- Deploy the Lambda function to AWS.
- Configure the handler to use your s3_scanner.py file.
- Add your Gemini API key as an environment variable.
- Test the Lambda function and see AI security analysis.
Deploy Lambda Function
Now you'll create the Lambda function and configure it to use your IAM role.
- In the AWS Console search bar, search for Lambda.
- Click Lambda in the search results.
- Click Create function in the top right.
Now you'll configure your Lambda function.
- Keep Author from scratch selected.
- In the Function name field, type s3-security-scanner.
- For Runtime, select Python 3.12 from the dropdown.
What's a runtime?
A runtime is the execution environment for your code - it determines which programming language version Lambda uses to run your function.
Now you need to attach the IAM role you created.
- Expand Change default execution role by clicking the arrow.
What's a default execution role?
The default execution role is a basic IAM role that AWS creates automatically. You're changing it to use your custom role with S3 permissions instead.
- Select Use an existing role.
- In the dropdown, search for LambdaS3ScannerRole.
- Select LambdaS3ScannerRole from the dropdown.
- Scroll down and click Create function at the bottom.
You should see your Lambda function created successfully!
Configure Lambda Timeout
Before uploading code, let's increase the timeout so your scanner has enough time to check all buckets.
Why increase the timeout?
Lambda functions have a default timeout of 3 seconds - if your code doesn't finish in that time, AWS kills the execution. Scanning S3 buckets can take 5-15 seconds if you have many buckets, especially when checking encryption for each one. By increasing the timeout to 30 seconds, you ensure Lambda has enough time to complete the scan without timing out.
- Click the Configuration tab.
- Click Edit on the right.
- Change Timeout from 3 seconds to 30 seconds.
- Click Save in the bottom right.
Upload Lambda Code
Now you'll upload your s3_scanner.zip file.
On the s3-security-scanner Lambda function page:
- Click the Code tab.
- Click the Upload from dropdown button.
- Click .zip file.
- Click Upload button.
- Navigate to your Desktop → aws-monitor-gemini folder.
- Select s3_scanner.zip.
- Click Open.
- Click Save in the bottom right.
You should see your Lambda function code uploaded successfully!
Got "The selected file is too large. The maximum size is 50 MB" error?
This happens if your zip file exceeds Lambda's 50MB upload limit. If you're on Mac and followed the standard pip install, you likely hit the Mac cygrpc error. Jump to the "❌ cannot import name 'cygrpc'" error tab below in the Test Lambda Function section - it has instructions to rebuild with Linux-compatible binaries that produce a smaller ~26MB zip file.
Configure Lambda Handler
Lambda needs to know which file and function to run. By default, it looks for lambda_function.py, but your file is called s3_scanner.py. Let's update the handler configuration.
On the s3-security-scanner Lambda function page:
- Make sure you're on the Code tab.
- Scroll down to Runtime settings section.
- Click Edit on the right.
You'll see the Runtime settings editor with the current handler.
- In the Handler field, change lambda_function.lambda_handler to s3_scanner.lambda_handler.
What is a handler?
The handler tells Lambda which file and function to execute. The format is filename.function_name - so s3_scanner.lambda_handler means "run the lambda_handler function in the s3_scanner.py file."
- Click Save in the bottom right.
Configure Gemini API Key
Your Lambda function needs the Gemini API key to run AI analysis. Let's add it as an environment variable.
On the s3-security-scanner Lambda function page:
- Click the Configuration tab.
- Click Environment variables in the left menu.
You'll see the Environment variables section (currently empty). - Click Edit on the right.
- Click Add environment variable.
- In Key, type GOOGLE_API_KEY.
- In Value, paste your Gemini API key (the one you saved earlier from Step 1).
- Click Save in the bottom right.
You should see your environment variable configured successfully!
What are environment variables and why use them?
Environment variables store configuration values like API keys, database passwords, and service endpoints. They're stored separately from your code, which keeps secrets secure. When Lambda runs your code, it loads these variables into memory so your code can access them via os.environ.get(). This way, you never hardcode sensitive values in your code, and you can easily change configurations without redeploying your function. Environment variables are a security best practice across all cloud platforms.
Test Lambda Function
Now let's test your Lambda function to verify it can scan S3 buckets.
On the s3-security-scanner Lambda function page:
- Switch to the Test tab at the top of the page.
You'll see the test event configuration area.
- Delete the existing JSON in the test event editor.
- Paste this new test event:
{
"test": "manual-invoke"
}
- Scroll up and click the Test button.
✅ I see S3 scan results with AI analysis
You should see a green success banner at the top showing "Executing function: succeeded".
In the Log output section, you'll see your scanner in action:
START RequestId: e3946789-0d8d-4a94-bc59-304ab92f8155 Version: $LATEST
Scanning S3 buckets for encryption...
Found 4 buckets to scan
Encrypted: cf-templates-3fqouf71r0d9-ap-southeast-2 (AES256)
Encrypted: nextwork-portfolio-assets (AES256)
Encrypted: test-security-demo-12345 (AES256)
Encrypted: test-security-demo-33333 (AES256)
Analyzing security findings with Gemini AI...
Scan complete: 0/4 buckets need encryption
END RequestId: e3946789-0d8d-4a94-bc59-304ab92f8155
REPORT RequestId: e3946789-0d8d-4a94-bc59-304ab92f8155 Duration: 9754.74 ms ...
In the Response section at the top, you'll see the JSON output with AI analysis:
{
"statusCode": 200,
"body": {
"total_buckets": 4,
"unencrypted_buckets": 0,
"encrypted_buckets": 4,
"scan_results": [
{
"bucket_name": "cf-templates-3fqouf71r0d9-ap-southeast-2",
"encrypted": true,
"encryption_type": "AES256"
},
{
"bucket_name": "nextwork-portfolio-assets",
"encrypted": true,
"encryption_type": "AES256"
},
...
],
"ai_analysis": "The scan results are excellent, showing all 4 buckets are currently encrypted, which significantly reduces risk. Unencrypted S3 buckets pose a critical data breach risk...",
"alert": false
}
}
Perfect! Your AI-powered Lambda function is successfully scanning S3 buckets and providing intelligent security recommendations. Step 3 is complete!
❌ GOOGLE_API_KEY not set
This error means you haven't configured the Gemini API key environment variable yet.
What's happening:
- Lambda tried to read GOOGLE_API_KEY from environment variables but couldn't find it.
- Your scanner code has os.environ.get('GOOGLE_API_KEY') which retrieves the key at runtime.
- Without this key, Lambda can't call Gemini AI for security analysis.
How to fix:
- Go to Lambda → Configuration → Environment variables → Edit.
- Click Add environment variable.
- Enter Key: GOOGLE_API_KEY.
- Enter Value: Paste your Gemini API key (the one you saved from Step 1).
- Click Save.
- Return to Code tab and click Test again.
You should now see AI analysis in the output!
❌ cannot import name 'cygrpc'
Mac-only error: macOS binaries don't work on Lambda's Linux environment
This happens because the google-generativeai package has compiled C extensions (binary files) built for macOS, but Lambda runs on Amazon Linux. When you installed packages on your Mac, pip downloaded macOS-compatible binaries that won't work in Lambda's Linux environment.
Solution: Rebuild with Linux-Compatible Dependencies
Delete your existing package and rebuild with Linux binaries:
cd ~/Desktop/aws-monitor-gemini
rm -rf package s3_scanner.zip
pip install --platform manylinux2014_x86_64 --target=./package --implementation cp --python-version 3.12 --only-binary=:all: --upgrade -r requirements.txt
cp s3_scanner.py ./package/
cd package
zip -r ../s3_scanner.zip . -x "*.pyc" -x "*__pycache__*"
cd ..
ls -lh s3_scanner.zip
The new zip file will be ~26 MB (under the 50 MB limit). Now:
- Go back to Lambda → Code tab.
- Click Upload from → .zip file.
- Upload the new s3_scanner.zip.
- Click Save.
- Click Test again.
You should now see successful results!
❌ I got a different error
Common errors and fixes:
Unable to import module:
- Your zip file structure is incorrect or missing dependencies.
- Rebuild package: rm -rf package s3_scanner.zip && mkdir package && pip install --target ./package boto3 google-generativeai && cp s3_scanner.py package/ && cd package && zip -r ../s3_scanner.zip . && cd ...
- Re-upload the zip to Lambda.
Access Denied on S3:
- Your IAM role lacks S3 permissions.
- Go to IAM → Roles → LambdaS3ScannerRole → Add permissions → Attach S3EncryptionReadPolicy.
Task timed out:
- AI analysis took too long.
- Go to Configuration → General configuration → Edit → Change Timeout to 60 seconds.
No buckets found:
- Normal for new AWS accounts with no S3 buckets.
- Create a test bucket in S3 Console and test again.
Still stuck?
Ask Claude for help with your specific error. You can also ask the NextWork community!
Secret mission
So far, you've built a Lambda function that scans S3 buckets for security issues - but it only runs when you manually test it. Professional security teams need continuous monitoring that runs automatically, without human intervention.
In this secret mission, you'll automate your scanner: use EventBridge to schedule your Lambda function to run every 12 hours, creating the same automated security monitoring pattern that enterprises like Netflix and Capital One use in production.
Schedule Daily Security Scans
Clean Up Your Resources
Clean Up Your Resources
Now that you've completed the project, decide what to do with your security scanner.
Keep it running
If you completed the Secret Mission, your security scanner runs automatically.
What stays active:
- EventBridge rule triggers Lambda at 9am UTC daily (if you did Secret Mission)
- Lambda function remains deployed
- You can manually test anytime
Cost: Free (Lambda within AWS Free Tier for occasional scans)
No cleanup needed!
Pause scheduled scans
If you completed the Secret Mission and want to stop daily automated scans:
- Go to EventBridge in AWS Console.
- Navigate to Rules.
- Find daily-s3-security-scan.
- Click the rule, then click Disable.
Your Lambda function remains - you can still manually test it anytime. Re-enable the EventBridge rule later to resume automated scans.
Delete everything
To completely remove all resources:
Delete EventBridge Rule (if you did Secret Mission)
- Go to EventBridge in AWS Console.
- Navigate to Rules.
- Find daily-s3-security-scan.
- Click Delete.
- Type delete in the confirmation field.
- Click Delete button to confirm.
Delete Lambda Function
- Go to Lambda in AWS Console.
- Select s3-security-scanner.
- Click Actions, then Delete.
- Confirm deletion.
Delete IAM Role
- Go to IAM in AWS Console.
- Click Roles.
- Find LambdaS3ScannerRole.
- Select it, click Delete.
- Confirm deletion.
Delete IAM Policy
- Go to IAM in AWS Console.
- Click Policies.
- Search for S3EncryptionReadPolicy.
- Select the policy.
- Click Delete.
- Type S3EncryptionReadPolicy to confirm.
- Click Delete button.
Delete CloudWatch Log Group
- Go to CloudWatch in AWS Console.
- Click Log groups in the left menu.
- Find /aws/lambda/s3-security-scanner.
- Select the log group.
- Click Actions → Delete log group(s).
- Click Delete to confirm.
All resources are now deleted. You can rebuild the security scanner anytime using this project guide!
That's a wrap!
That's a wrap!
You did it! 🎊 You've built an AI-powered AWS security scanner with automated scheduling.
What you learned:
- 🔍 AWS Lambda serverless deployment and configuration
- 🤖 Gemini AI integration for security analysis
- 🛡️ Amazon S3 encryption scanning with boto3
- 🔐 IAM roles and permissions for Lambda
- ⏰ EventBridge scheduled automation (Secret Mission)
- 📊 CloudWatch Logs for monitoring automated executions
Ready to quiz yourself? 💪
p.s. Does it say "Still tasks to complete!" at the bottom of the screen?
This means you still have screenshots left to upload, or questions left to answer!
- Press Ctrl+F (Windows) or Cmd+F (Mac) on your keyboard
- Search for the text Return to later
- Jump straight to your incomplete tasks!
📣 If you're EVER stuck - ask the NextWork community. Students like you are already asking questions about this project.
🚀 p.s. Does it say "Still tasks to complete!" at the bottom of the screen?
This means you still have screenshots left to upload, or questions left to answer!
- Press Ctrl+F (Windows) or Command+F (Mac) on your keyboard.
- Search for the text Return to later.
- Jump straight to your incomplete tasks!
- 🙋♀️ Still stuck? Ask the community!