Detect and Respond to a Security Incident

Build an automated AWS pipeline that detects threats and disables compromised credentials.

Introduction

30 Second Summary

Every day, cloud accounts face unauthorized access attempts. When credentials are compromised, the damage an attacker can do grows with every minute it takes a human to notice and respond.

In this project, you will build an automated security incident detection and response system on AWS that detects threats and disables compromised credentials in seconds, without any human intervention.

What You'll Build

Picture triggering a simulated security incident and watching your system automatically detect the threat, disable the compromised access keys, and log the entire response in real time.

By the end of this project, you'll have:

  • A CloudTrail audit log showing every API call in your AWS account, searchable and filterable so you can trace exactly what happened and when.
  • A GuardDuty dashboard displaying real-time threat findings sorted by severity, just like a SOC analyst would triage in a production environment.
  • An automated pipeline using EventBridge and Lambda that disables compromised IAM access keys the moment a threat is detected, responding in seconds instead of hours.
  • Secret Mission: Add real-time email alerts via SNS so you get notified the instant a security incident is detected and contained.

Are there any prerequisites?

You need an AWS account (free tier eligible) and basic familiarity with IAM users and policies. Everything else is set up during the project.

Before We Start

Before We Start...

Before we dive in, let's lock in what you're about to build and why it matters.

Set Up Your Security Monitoring Foundation

Without logging and threat detection enabled, you have zero visibility into what is happening in your AWS account. This is the first thing a cloud security engineer sets up in any environment.

In this step, you will confirm that CloudTrail is already recording API activity and then enable GuardDuty to start detecting threats in real time.

In this step, get ready to:
  • Confirm CloudTrail is logging API activity in your account.
  • Enable GuardDuty threat detection with the 30-day free trial.
  • Record your Detector ID for use in later steps.
Verify CloudTrail is recording

CloudTrail is enabled by default on every AWS account. It automatically records the last 90 days of management events at no charge. You do not need to create anything here. You just need to confirm it is working.

  • In the AWS Management Console, type CloudTrail in the top search bar and select CloudTrail from the results.
  • In the left navigation pane, click Event history.
  • You should see a list of recent management events with the most recent events at the top.

Look for events like ConsoleLogin or actions from iam.amazonaws.com. These are your own recent activities being recorded.

What is CloudTrail?

CloudTrail is an audit log for your AWS account. Every API call made through the console, CLI, or SDK gets recorded here.

Think of it as a security camera for your cloud environment. If someone creates a user, deletes a resource, or changes a permission, CloudTrail has a record of it.

Not seeing any events?

Check that you are viewing events in the same Region where you have been working. Event history is per-Region, so if you recently signed in from a different Region, switch to that Region using the Region selector in the top-right corner.

help me find events in CloudTrail Event history

Enable GuardDuty

GuardDuty is a threat detection service that continuously analyzes CloudTrail logs, VPC Flow Logs, and DNS logs for malicious activity. Enabling it starts a 30-day free trial.

  • In the top search bar, type GuardDuty and select GuardDuty from the results.
  • On the welcome page, select Amazon GuardDuty - All features.
  • Click Get started.
  • Click Enable GuardDuty.

GuardDuty is now active. It immediately begins analyzing your account activity for suspicious behavior.

What is GuardDuty?

GuardDuty uses machine learning and threat intelligence to identify compromised credentials, unauthorized access, and cryptocurrency mining in your account.

It does not require you to deploy any agents or configure any infrastructure. Once enabled, it works automatically in the background.

Already see GuardDuty enabled?

If GuardDuty was previously enabled in this Region (by you or an organization administrator), you will see the Summary dashboard instead of the welcome page. That is fine. Skip ahead to the next substep to confirm your Detector ID.

help me figure out my GuardDuty status

Confirm GuardDuty is active and record your Detector ID

Your Detector ID is a unique identifier for your GuardDuty instance in this Region. You will need it in later steps when testing the automated response pipeline.

  • In the GuardDuty console, click Settings in the left navigation pane.

Before you look at the page, what do you expect to see that proves GuardDuty is working?

  • On the Settings page, confirm you can see your Detector ID (a long alphanumeric string).
  • Confirm the page shows GuardDuty is enabled with the 30-day free trial active.

You now have your Detector ID visible and GuardDuty running. This confirms your threat detection is operational.

Why note the Detector ID?

The Detector ID uniquely identifies your GuardDuty instance in this Region. When you build the EventBridge rule and Lambda function in later steps, this ID confirms which detector generated a finding.

Don't see a Detector ID?

If the Settings page does not show a Detector ID, GuardDuty may not have fully activated. Go back to the GuardDuty main page, look for the Get started or Enable GuardDuty button, and complete the activation.

help me enable GuardDuty and find my Detector ID

Your security monitoring foundation is in place. CloudTrail is logging every API call, and GuardDuty is scanning those logs for threats. Next up, you will create a deliberately insecure IAM user to simulate a real-world security incident.

Create a Deliberately Insecure IAM User

In real security incidents, attackers target IAM credentials that have overly broad permissions. A user with AdministratorAccess and an active access key is the exact scenario that appears in breach reports.

In this step, you will deliberately create this misconfiguration so you have a realistic target for your security simulation. This gives GuardDuty something concrete to detect and your automated response something to act on.

In this step, get ready to:
  • Create a new IAM user with an overpermissioned policy attached.
  • Generate an access key pair and record the Access Key ID.
Create the IAM user

You need a user that simulates a real-world misconfiguration: broad permissions and active programmatic credentials.

  • In the AWS Management Console, type IAM in the top search bar and select IAM to open the IAM console.
  • In the left navigation pane, click Users.
  • Click Create user.
  • For User name, enter test-compromised-user.
  • Leave the Provide user access to the AWS Management Console checkbox unchecked. This user only needs programmatic access.
  • Click Next.

You are now on the Set permissions page.

  • Select Attach policies directly.
  • In the search box under Permissions policies, type AdministratorAccess.
  • Check the box next to the AdministratorAccess managed policy.
  • Click Next.
  • On the Review page, click Create user.

Why AdministratorAccess?

This is intentionally overpermissioned. In real environments, attackers look for credentials with broad access because a single compromised key can reach everything in the account.

By replicating this misconfiguration, you will see exactly how GuardDuty flags it and how your automated response handles it.

Generate an access key for the user

Access keys give programmatic access to your AWS account. You need one on this user so your Lambda function has something to disable when it responds to a threat.

  • Click on test-compromised-user in the Users list to open the user details page.
  • Select the Security credentials tab.
  • In the Access keys section, click Create access key.
  • On the Access key best practices & alternatives page, select Other as the use case.
  • Click Next.
  • Skip the description tag and click Create access key.

Record your Access Key ID now

On the Retrieve access key page, you will see an Access Key ID and a Secret access key. Copy the Access Key ID and paste it somewhere you can find it later (a text file or sticky note). You will reference this when verifying the automated response in Step 5.

Do NOT use this key for anything real. It exists only as a target for your security simulation.

  • Click Done to close the Retrieve access key page.
Verify the access key is active

Before you move on, confirm the user and its credentials are set up correctly.

  • In the IAM console, click Users in the left navigation.
  • Click test-compromised-user.
  • Select the Security credentials tab and scroll to the Access keys section.

What do you expect to see listed here? Take a moment to predict before looking.

You should see one access key listed with status Active. This confirms your user has live programmatic credentials that your automated pipeline can target.

Don't see an active access key?

Make sure you completed the Create access key flow all the way through to the Done button. If you navigated away before finishing, the key may not have been saved.

If no key appears, click Create access key again and follow the steps above.

Help me troubleshoot my missing access key

Your deliberately insecure user is ready. Next up, you will generate security findings in GuardDuty and investigate them like a SOC analyst triaging real incidents.

Generate and Investigate Security Findings

You now have a security monitoring foundation in place. GuardDuty is watching your account and CloudTrail is logging every API call.

But right now your Findings page is empty. Without seeing what a real threat looks like, you will not know what you are building automation for in the next step. GuardDuty's sample findings let you explore real-world attack types without needing actual attackers.

In this step, get ready to:
  • Generate sample security findings in GuardDuty.
  • Investigate a high-severity finding like a SOC analyst.
  • Filter findings by severity to prioritize your response.
Generate sample findings

GuardDuty can generate one sample finding for every threat type it supports. These are fictitious findings marked with a [SAMPLE] prefix, but they use the exact same JSON structure as real detections.

  • In the GuardDuty console, choose Settings from the left navigation pane.
  • Scroll down to the Sample findings section.
  • Choose Generate sample findings.
  • In the left navigation pane, choose Findings.

You should now see dozens of findings listed in the table, each prefixed with [SAMPLE]. You will see threat types like UnauthorizedAccess, CryptoCurrency mining, Backdoor activity, and Recon.

What are these findings?

Each finding represents a simulated threat that GuardDuty detected. In a production account, these would come from real suspicious activity in your CloudTrail logs, VPC Flow Logs, or DNS logs.

The [SAMPLE] prefix tells you these are test data generated for learning purposes. They are safe to explore and will not affect your account.

Not seeing any findings?

Make sure you clicked Generate sample findings on the Settings page, not the Findings page. After generating, navigate back to Findings in the left navigation. It may take a few seconds for all findings to appear.

help me find and generate sample findings in GuardDuty

Investigate a finding like a SOC analyst

Security Operations Center (SOC) analysts triage findings by clicking into them, reading the details, and deciding what action to take. You are going to do the same thing with a high-severity finding.

  • On the Findings page, look for a finding with a red severity icon (this indicates High severity).
  • Click on that finding to open its details panel.
  • In the details panel, examine the following fields: what resource is affected, what action was taken, what the severity level is, and what the recommended remediation says.
  • Click the finding ID link at the top of the details panel to view the full JSON.

The full JSON view shows you the raw event structure. Pay close attention to the source, detail-type, and detail fields. This is the exact same JSON structure that EventBridge will receive when a real finding is generated.

Why does the JSON structure matter?

When you build the automated response in the next step, your EventBridge rule will match events where source equals aws.guardduty and detail-type equals GuardDuty Finding. Your Lambda function will then extract information from the detail object.

Knowing this structure now means you will understand exactly how the automation works when you build it.

Filter findings by severity

In a production environment, GuardDuty can generate hundreds of findings. Security teams prioritize by focusing on High and Critical severity first. You are going to apply a severity filter to see how this works.

  • On the Findings page, select the Filter findings bar next to Saved rules. This displays a list of property filters.
  • From the filter list, select Severity.
  • Choose the Equals operator.
  • Select High and Critical as the severity values, then apply the filter.

Your findings list now shows only the most urgent threats. The table is narrowed down to findings with severity values of 7.0 and above.

How do severity levels work?

GuardDuty assigns severity on a 1.0 to 10.0 scale. Low is 1.0 to 3.9, Medium is 4.0 to 6.9, High is 7.0 to 8.9, and Critical is 9.0 to 10.0. In real incidents, you triage Critical and High first because they represent active compromises or imminent threats.

Filter not narrowing results?

Make sure you selected both High and Critical in the severity filter. If the filter bar shows nothing, try clearing any existing filters first by clicking the X next to them, then re-apply the severity filter.

help me filter GuardDuty findings by severity

Before we move on, do you think you could build an automated system that responds to every one of these findings manually? What would happen if a Critical finding appeared at 3 AM?

You have now seen what real-world threats look like through GuardDuty's lens. You know the JSON structure, the severity levels, and how to triage findings. Next up, you will build an automated pipeline that responds to these threats in seconds instead of waiting for a human to notice them.

Build the Automated Response Pipeline

In the previous step, you investigated GuardDuty findings manually. You clicked through each finding, examined the JSON, and filtered by severity. That process gives you understanding, but it does not scale.

In the time it takes a human to notice a compromised credential, an attacker can exfiltrate data from your account. In this step, you will build an automated response pipeline using Lambda and EventBridge that disables compromised access keys within seconds of detection.

In this step, get ready to:
  • Create a Lambda function that disables compromised IAM access keys.
  • Deploy the incident response code to the function.
  • Connect GuardDuty to Lambda with an EventBridge rule.
Create the Lambda function

Your automated responder needs a place to live. You will create a Lambda function that receives GuardDuty findings and takes action on them.

  • Open the Lambda console by searching for Lambda in the AWS search bar and selecting it.
  • Click Create function.
  • Select Author from scratch.
  • For Function name, enter GuardDutyAutoResponse.
  • For Runtime, choose Python 3.12.
  • Under Permissions, expand Change default execution role and leave Create a new role with basic Lambda permissions selected.
  • Click Create function.

Lambda creates the function and takes you to the function's detail page. You should see a success banner at the top.

What is Lambda?

AWS Lambda lets you run code without provisioning or managing servers. You upload your code, and Lambda runs it in response to events. In this project, the event is a GuardDuty finding.

Now you need to give the function permission to disable IAM access keys. The default role only allows the function to write logs.

  • Select the Configuration tab.
  • Click Permissions in the left sidebar.
  • Under Execution role, click the Role name link to open it in the IAM console.
  • In the Permissions policies pane, click Add permissions and select Create inline policy.
  • In Policy editor, select JSON.
  • Replace the existing JSON with this policy:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "iam:UpdateAccessKey",
            "Resource": "*"
        }
    ]
}
  • Click Next.
  • Under Policy details, enter DisableAccessKeyPolicy as the Policy name.
  • Click Create policy.

You should see the new inline policy listed under the role's permissions. This grants your Lambda function the ability to disable any IAM access key in your account.

Why grant iam:UpdateAccessKey on resource *?

The function needs to disable access keys belonging to any user that GuardDuty identifies as compromised. Since you cannot predict which user will be targeted, the resource must be * (all users).

In a production environment, you would scope this down further using conditions or tag-based access control. For this project, a broad permission is safe because you control the only user in the account.

Don't see the inline policy listed?

Make sure you clicked Create policy at the end. If the page shows an error, check that your JSON is valid and that the Action value is exactly iam:UpdateAccessKey.

Help me add an inline policy to my Lambda execution role.

Add the function code

With permissions in place, you can now write the code that extracts compromised credentials from a GuardDuty finding and disables them. Navigate back to your Lambda function in the Lambda console.

  • Select the Code tab.
  • In the code editor, select all the existing code in lambda_function.py and delete it.
  • Paste the following code that sets up the imports and function entry point:
import boto3
import json
import datetime

iam_client = boto3.client('iam')


def lambda_handler(event, context):
    # Extract finding details from the GuardDuty event
    finding_type = event['detail']['type']
    severity = event['detail']['severity']

    print(f"Processing GuardDuty finding: {finding_type} (severity: {severity})")

What does this code do?

  • boto3.client('iam') creates an IAM client that can call the UpdateAccessKey API.
  • lambda_handler is the entry point Lambda calls when a GuardDuty finding arrives via EventBridge.
  • The function extracts type and severity from the finding's JSON structure for logging.
  • Directly below the code you just pasted, add the credential detection and disable logic:
    # Check if the finding involves IAM credentials
    if 'accessKeyDetails' in event['detail']['resource']:
        access_key_id = event['detail']['resource']['accessKeyDetails']['accessKeyId']
        username = event['detail']['resource']['accessKeyDetails']['userName']

        print(f"Compromised access key detected: {access_key_id} for user: {username}")

        # Disable the compromised access key
        iam_client.update_access_key(
            UserName=username,
            AccessKeyId=access_key_id,
            Status='Inactive'
        )

        print(f"Access key {access_key_id} has been disabled for user {username}")

        return {
            'statusCode': 200,
            'body': json.dumps({
                'message': f'Access key {access_key_id} disabled for user {username}',
                'finding_type': finding_type,
                'timestamp': datetime.datetime.now().isoformat()
            })
        }

What does this code do?

  • It checks whether the finding contains accessKeyDetails in the resource field. Not all findings involve IAM credentials.
  • If credentials are present, it extracts the accessKeyId and userName from the finding JSON.
  • iam_client.update_access_key() sets the key's status to Inactive. This immediately prevents anyone from using that key.
  • Finally, add the fallback return for findings that do not contain IAM credentials:
    print("Finding does not contain accessKeyDetails, no action taken.")
    return {
        'statusCode': 200,
        'body': json.dumps({
            'message': 'No IAM credentials found in finding, no action taken.',
            'finding_type': finding_type
        })
    }

Why handle findings without credentials?

GuardDuty generates many finding types. Some involve networking anomalies or EC2 instance behavior that have no IAM credentials attached. This fallback ensures the function exits gracefully instead of crashing with a KeyError.

  • In the DEPLOY section above the editor, click Deploy.

You should see a green banner that says "Successfully updated the function GuardDutyAutoResponse".

✔️ Awesome, I've got everything!

Great. Make sure you see the success banner confirming the deployment.

ⓧ I'd like to double check the full code

Your lambda_function.py should contain all three blocks you pasted in order: imports and handler setup, the credential detection logic, and the fallback return. Scroll through your editor and confirm each section is present. The full function should start with import boto3 and end with the fallback return statement.

Seeing a deployment error?

Check that the indentation is consistent. The if block and the fallback return should both be indented one level inside lambda_handler. The code inside the if block should be indented two levels.

Help me fix a Lambda deployment error for my GuardDuty response function.

Create the EventBridge rule

Your Lambda function is ready, but nothing is sending findings to it yet. You need an EventBridge rule that listens for GuardDuty findings and routes them to your function.

  • Open the EventBridge console by searching for EventBridge in the AWS search bar.
  • In the left navigation pane, click Rules.
  • Click Create rule.
  • For Name, enter GuardDutyToLambda.
  • For Event bus, leave default selected.
  • For Rule type, choose Rule with an event pattern.
  • Click Next.

Now you will define the event pattern that tells EventBridge which events to capture.

  • Under Creation method, choose Custom pattern (JSON editor).
  • In the Event pattern field, paste this JSON:
{
    "source": ["aws.guardduty"]
}

What does this event pattern do?

This pattern matches every event that GuardDuty publishes to the default event bus. The source aws.guardduty is the identifier GuardDuty uses when it sends findings to EventBridge. Any time GuardDuty generates a finding, this rule will fire.

  • Click Next.
  • For Target types, choose AWS service.
  • For Select a target, choose Lambda function from the dropdown.
  • For Function, select GuardDutyAutoResponse.
  • Click Next.
  • Click Next again to skip tags.
  • Review the rule details, then click Create rule.

What is EventBridge?

EventBridge is a serverless event bus that routes events between AWS services. Think of it as a dispatcher. GuardDuty publishes a finding, EventBridge matches it against your rule, and routes it to your Lambda function. No polling, no servers, no delays.

Before you check the result, predict what you expect to see on the EventBridge Rules page. What status should your new rule have?

On the EventBridge Rules page, you should see GuardDutyToLambda listed with status Enabled. Click the rule name to confirm the event pattern shows "source": ["aws.guardduty"] and the target shows your GuardDutyAutoResponse Lambda function.

Rule not showing as Enabled?

If the rule shows as Disabled, click the rule name, choose Edit, and make sure the rule is set to Enabled on the first page of the wizard. Also confirm you selected the default event bus.

Help me troubleshoot my EventBridge rule for GuardDuty.

Your automated security pipeline is wired up. Next up, you will test the entire chain end-to-end by triggering a finding and watching it disable your test user's access key automatically.

Test the Automated Response

Your detection and response pipeline is fully wired. GuardDuty feeds findings to EventBridge, which routes them to your Lambda function.

But a security system you have never tested is a security system you cannot trust. In the time it takes to discover a misconfiguration in production, real damage can happen. This step validates the entire chain from detection to automated remediation so you can prove it works before you need it.

In this step, get ready to:
  • Test the Lambda function directly with a simulated GuardDuty finding.
  • Verify that the compromised access key was automatically disabled.
  • Run a full end-to-end pipeline test from GuardDuty through EventBridge to Lambda.
Create and run a Lambda test event

To test the Lambda function directly, you send it a fake GuardDuty finding that includes your test-compromised-user access key ID. This proves the function logic works before involving EventBridge.

  • In the Lambda console, open the GuardDutyAutoResponse function.
  • Select the Test tab.
  • Under Test event, choose Create new event.
  • For Event name, enter GuardDutyTest.
  • Replace the default JSON with the following test event, substituting your actual Access Key ID for test-compromised-user where indicated:
{
  "source": "aws.guardduty",
  "detail-type": "GuardDuty Finding",
  "detail": {
    "type": "UnauthorizedAccess:IAMUser/MaliciousIPCaller",
    "severity": 8,
    "resource": {
      "accessKeyDetails": {
        "accessKeyId": "your-access-key-id-here",
        "userName": "test-compromised-user"
      }
    }
  }
}

What does this JSON do?

This JSON mimics the structure of a real GuardDuty finding event. The detail.resource.accessKeyDetails.accessKeyId field is what your Lambda function reads to know which key to disable.

By using your real Access Key ID from test-compromised-user, the test proves the function can actually disable it in IAM.

  • Replace your-access-key-id-here with the Access Key ID you recorded when creating test-compromised-user in Step 2.
  • Click Save changes.

Before you run the test, what do you expect the function to return? Think about what your code does when it receives a finding with accessKeyDetails.

  • Click Test.

Under Execution result, expand Details. You should see a response with statusCode 200 and a message confirming the access key was disabled for test-compromised-user.

Seeing an error in the execution result?

  • If you see a NoSuchEntity error, double-check that the Access Key ID in your test event exactly matches the one shown in the IAM console for test-compromised-user.
  • If you see an AccessDenied error, confirm the Lambda execution role has the inline policy granting iam:UpdateAccessKey on resource *.
  • If the function times out, the Lambda role may lack internet access. Check that the function is not attached to a VPC.
Verify the access key was disabled

The Lambda function reported success. Now confirm the actual IAM change happened.

  • Open the IAM console.
  • In the left navigation pane, click Users.
  • Click test-compromised-user.
  • Select the Security credentials tab.
  • Look at the Access keys section.

The access key status now shows Inactive. Your Lambda function successfully disabled the compromised credential in seconds, without any human intervention.

Re-activate the key and test the full pipeline

The direct test proved the Lambda function works. Now test the full chain: GuardDuty generates a finding, EventBridge matches it, and Lambda disables the key automatically.

  • On the same Security credentials tab for test-compromised-user, find the access key in the Access keys section.
  • Click the Actions dropdown for the key, then choose Activate.
  • Confirm the activation when prompted.

The key is Active again. Now trigger the full pipeline.

  • Navigate to the GuardDuty console.
  • Click Settings in the left navigation.
  • Scroll down to Sample findings and click Generate sample findings.

What happens next?

Generating sample findings creates one finding for each supported finding type. Each finding is sent to EventBridge. Your rule matches all events from aws.guardduty and invokes your Lambda function.

Not all sample findings contain accessKeyDetails. Your Lambda function handles this gracefully by checking for the key before attempting any action. If a sample finding happens to include a matching access key for test-compromised-user, the key will be disabled automatically.

  • Wait about 30 seconds for EventBridge to route the findings to Lambda.
  • Return to the IAM console and check the Security credentials tab for test-compromised-user.

Before you check the status, do you think the key will show Inactive or Active? Consider whether the sample findings include your specific access key ID.

  • Refresh the page to see the current access key status.

If the key shows Inactive, a sample finding with matching access key details triggered the full pipeline. If it still shows Active, the sample findings used placeholder access key IDs that did not match your user.

How do I confirm EventBridge triggered my Lambda?

Regardless of whether the key was disabled, you can verify EventBridge triggered your function. Open the GuardDutyAutoResponse function in the Lambda console and select the Monitor tab. You should see a spike in invocations matching the number of sample findings generated. This confirms the EventBridge-to-Lambda connection works.

You already proved in the direct test that the function disables keys correctly. The Monitor tab confirms the full pipeline triggers it. Together, these two tests prove the end-to-end system works.

Not seeing any invocations on the Monitor tab?

  • Verify your EventBridge rule GuardDutyToLambda shows status Enabled in the EventBridge console.
  • Confirm the rule's event pattern includes "source": ["aws.guardduty"].
  • Check that the rule's target shows GuardDutyAutoResponse as the Lambda function.

The access key for test-compromised-user shows status Inactive in the IAM console after your Lambda executed. This proves the automated response pipeline works end-to-end, from threat detection to credential containment.

Secret mission

Add Real-Time Email Alerts via SNS

Your pipeline detects threats and disables compromised credentials automatically. But no one on the security team knows it happened. Can you add real-time email notifications so the team gets alerted the instant an incident is detected?

Clean Up Your Resources

Clean Up Your Resources

Decide whether to keep your resources running, pause them to come back later, or delete them entirely. Most resources in this project fall under the AWS always-free tier, but GuardDuty has a 30-day free trial that will begin charging if left enabled after the trial period ends.

Cost warning

GuardDuty is on a 30-day free trial. After the trial ends, you will be charged based on the volume of data analyzed. If you do not plan to continue using GuardDuty, disable it before the 30 days expire.

The IAM user test-compromised-user has AdministratorAccess attached. This is a deliberate security vulnerability and should be deleted immediately regardless of which cleanup option you choose.

Resources you used:

  • GuardDuty detector (30-day free trial, usage-based pricing after trial ends).
  • Lambda function GuardDutyAutoResponse (always-free tier: 1M requests/month).
  • EventBridge rule GuardDutyToLambda (always-free tier).
  • IAM user test-compromised-user (no cost, but a security risk if left active).
  • SNS topic SecurityAlerts (always-free tier: first 1,000 email notifications/month).

Keep everything running

No action needed on most resources. Choose this if you want to keep GuardDuty monitoring your real account activity for the remainder of your 30-day trial.

  • Leave GuardDuty enabled to monitor your account through the end of your free trial.
  • Leave the Lambda function, EventBridge rule, and SNS topic in place. They incur no cost while inactive.
  • Delete the test-compromised-user IAM user immediately. It has AdministratorAccess and is a deliberate vulnerability. In the IAM console, choose Users, select the checkbox next to test-compromised-user, choose Delete, type the username to confirm, then choose Delete.

Pause - I'll come back to this later

Suspend GuardDuty to pause the trial and avoid future charges. Your Lambda function and EventBridge rule remain in place at no cost.

  • Suspend GuardDuty. In the GuardDuty console, choose Settings in the navigation pane. In the Suspend GuardDuty section, choose Suspend GuardDuty, then confirm your action. You can re-enable it later from the same page.
  • Keep the Lambda function GuardDutyAutoResponse and EventBridge rule GuardDutyToLambda in place. They incur no cost while no events are flowing.
  • Keep the SNS topic SecurityAlerts in place. No cost while unused.
  • Delete the test-compromised-user IAM user. In the IAM console, choose Users, select the checkbox next to test-compromised-user, choose Delete, type the username to confirm, then choose Delete.

Delete - I don't want to use this again

Remove all project resources and start fresh. Follow each step below in order.

  • Disable GuardDuty. In the GuardDuty console, choose Settings in the navigation pane. In the Suspend GuardDuty section, choose Disable GuardDuty, then confirm your action. This permanently removes your existing findings and configuration.
  • Delete the Lambda function. Open the Functions page of the Lambda console. Select GuardDutyAutoResponse, choose Actions, then Delete. Type confirm in the text input field and choose Delete.
  • Delete the EventBridge rule. In the EventBridge console, choose Rules, select GuardDutyToLambda, choose Delete, then confirm.
  • Delete the IAM user. In the IAM console, choose Users, select the checkbox next to test-compromised-user, choose Delete, type the username to confirm, then choose Delete.
  • Delete the SNS topic. In the SNS console, choose Topics, select SecurityAlerts, choose Delete, then confirm.

Nice Work!

Nice Work!

You just built a fully automated AWS security incident detection and response system. From enabling threat detection to watching compromised credentials get disabled in seconds, you have experienced the same workflow that cloud security teams use to protect production environments.

You've learned how to:

  • Set up a security monitoring foundation with CloudTrail audit logging and GuardDuty threat detection, giving you full visibility into your AWS account activity.
  • Investigate GuardDuty findings like a SOC analyst, triaging by severity and examining finding JSON details to understand the scope of a threat.
  • Build an automated incident response pipeline using EventBridge and Lambda that detects compromised credentials and disables them in seconds without human intervention.
  • Secret Mission: Added real-time email notifications via SNS to alert the security team the instant an incident is detected and contained.

Ready to quiz yourself?