How to Set Up AWS GuardDuty for Threat Detection

Complete guide to enabling AWS GuardDuty across all regions, configuring threat findings notifications, and integrating with Security Hub for centralized security monitoring.

9 min readUpdated 2026-01-13

AWS GuardDuty is a managed threat detection service that continuously monitors your AWS environment for malicious activity and unauthorized behavior. Using machine learning, anomaly detection, and integrated threat intelligence, GuardDuty identifies potential threats without requiring you to deploy or manage security infrastructure.

This article is part of our comprehensive Cloud Security Tips for 2026 guide covering essential practices for protecting your cloud environment.

What GuardDuty Monitors

GuardDuty analyzes multiple data sources:

Data SourceWhat It Detects
CloudTrail EventsUnusual API calls, credential abuse, policy changes
VPC Flow LogsPort scanning, DDoS attempts, data exfiltration
DNS LogsCommand-and-control communication, crypto mining
S3 Data EventsSuspicious bucket access, data theft attempts
EKS Audit LogsKubernetes-specific threats, container escapes
RDS Login ActivityAnomalous database access patterns
Lambda Network ActivityMalicious Lambda function behavior

Enable GuardDuty in a Single Account

Using AWS Console

  1. Open the GuardDuty Console
  2. Click Get Started
  3. Review the service-linked role permissions
  4. Click Enable GuardDuty

Using AWS CLI

# Enable GuardDuty
aws guardduty create-detector --enable

# Response includes detector ID
{
  "DetectorId": "12abc34d567e8f90g12h34i5j6k78901"
}

# Verify GuardDuty is enabled
aws guardduty list-detectors

Enable GuardDuty in All Regions

Enable GuardDuty across all regions to prevent attackers from exploiting unmonitored regions:

#!/bin/bash
# Enable GuardDuty in all regions

for region in $(aws ec2 describe-regions --query 'Regions[].RegionName' --output text); do
  echo "Enabling GuardDuty in $region..."
  aws guardduty create-detector \
    --enable \
    --region "$region" \
    --finding-publishing-frequency FIFTEEN_MINUTES \
    --data-sources S3Logs={Enable=true} 2>/dev/null || \
    echo "Already enabled or error in $region"
done

echo "GuardDuty enabled in all regions"

Enable Optional Protection Plans

GuardDuty offers additional protection modules:

# Get detector ID
DETECTOR_ID=$(aws guardduty list-detectors --query 'DetectorIds[0]' --output text)

# Enable S3 Protection
aws guardduty update-detector \
  --detector-id "$DETECTOR_ID" \
  --data-sources S3Logs={Enable=true}

# Enable EKS Protection
aws guardduty update-detector \
  --detector-id "$DETECTOR_ID" \
  --data-sources Kubernetes={AuditLogs={Enable=true}}

# Enable Malware Protection for EC2
aws guardduty update-member-detectors \
  --detector-id "$DETECTOR_ID" \
  --features '[{"Name":"EBS_MALWARE_PROTECTION","Status":"ENABLED"}]'

# Enable RDS Protection
aws guardduty update-detector \
  --detector-id "$DETECTOR_ID" \
  --features '[{"Name":"RDS_LOGIN_EVENTS","Status":"ENABLED"}]'

# Enable Lambda Protection
aws guardduty update-detector \
  --detector-id "$DETECTOR_ID" \
  --features '[{"Name":"LAMBDA_NETWORK_LOGS","Status":"ENABLED"}]'

Configure Findings Notifications

Step 1: Create SNS Topic

# Create SNS topic
aws sns create-topic --name guardduty-alerts

# Subscribe email
aws sns subscribe \
  --topic-arn arn:aws:sns:us-east-1:123456789012:guardduty-alerts \
  --protocol email \
  --notification-endpoint [email protected]

Step 2: Create EventBridge Rule

# Create EventBridge rule for high/critical findings
aws events put-rule \
  --name guardduty-high-severity \
  --event-pattern '{
    "source": ["aws.guardduty"],
    "detail-type": ["GuardDuty Finding"],
    "detail": {
      "severity": [{"numeric": [">=", 7]}]
    }
  }' \
  --description "GuardDuty high and critical severity findings"

# Add SNS as target
aws events put-targets \
  --rule guardduty-high-severity \
  --targets Id=1,Arn=arn:aws:sns:us-east-1:123456789012:guardduty-alerts

Step 3: Configure SNS Access Policy

aws sns set-topic-attributes \
  --topic-arn arn:aws:sns:us-east-1:123456789012:guardduty-alerts \
  --attribute-name Policy \
  --attribute-value '{
    "Version": "2012-10-17",
    "Statement": [{
      "Effect": "Allow",
      "Principal": {"Service": "events.amazonaws.com"},
      "Action": "sns:Publish",
      "Resource": "arn:aws:sns:us-east-1:123456789012:guardduty-alerts"
    }]
  }'

Integrate with Security Hub

Security Hub provides centralized security visibility across multiple AWS services:

# Enable Security Hub
aws securityhub enable-security-hub

# GuardDuty findings are automatically sent to Security Hub
# Verify integration
aws securityhub get-enabled-standards

Security Hub benefits:

  • Single pane of glass for all security findings
  • Automated compliance checks (CIS, PCI DSS, etc.)
  • Cross-account finding aggregation
  • Integration with third-party SIEM tools

Multi-Account Setup with AWS Organizations

For organizations, use a delegated administrator account:

# From management account: Designate GuardDuty admin
aws guardduty enable-organization-admin-account \
  --admin-account-id 111122223333

# From delegated admin: Create detector
aws guardduty create-detector --enable

# Auto-enable for new member accounts
aws guardduty update-organization-configuration \
  --detector-id "$DETECTOR_ID" \
  --auto-enable

# Enable for existing accounts
aws guardduty create-members \
  --detector-id "$DETECTOR_ID" \
  --account-details '[{"AccountId":"444455556666","Email":"[email protected]"}]'

Understanding GuardDuty Findings

Findings are categorized by severity:

Severity RangeLevelResponse
0.0 - 3.9LowReview during regular security audits
4.0 - 6.9MediumInvestigate within 24 hours
7.0 - 8.9HighInvestigate immediately
9.0 - 10.0CriticalUrgent response required

Common Finding Types

# List findings by severity
aws guardduty list-findings \
  --detector-id "$DETECTOR_ID" \
  --finding-criteria '{
    "Criterion": {
      "severity": {"Gte": 7}
    }
  }'

# Get finding details
aws guardduty get-findings \
  --detector-id "$DETECTOR_ID" \
  --finding-ids "12abc34d567e8f90g12h34i5j6k78901"

Create Suppression Rules

Reduce noise from known benign activity:

# Create suppression rule for penetration testing
aws guardduty create-filter \
  --detector-id "$DETECTOR_ID" \
  --name "pentest-suppression" \
  --description "Suppress findings from authorized pen test IPs" \
  --action ARCHIVE \
  --finding-criteria '{
    "Criterion": {
      "service.action.networkConnectionAction.remoteIpDetails.ipAddressV4": {
        "Eq": ["203.0.113.50", "203.0.113.51"]
      }
    }
  }'

# Create suppression for known scanning service
aws guardduty create-filter \
  --detector-id "$DETECTOR_ID" \
  --name "qualys-scanner" \
  --description "Suppress findings from Qualys vulnerability scanner" \
  --action ARCHIVE \
  --finding-criteria '{
    "Criterion": {
      "type": {"Eq": ["Recon:EC2/PortProbeUnprotectedPort"]},
      "service.action.portProbeAction.remoteIpDetails.ipAddressV4": {
        "Eq": ["64.39.96.0/20"]
      }
    }
  }'

Automated Response with Lambda

Create automated incident response:

# Lambda function for automated response
import boto3
import json

def lambda_handler(event, context):
    finding = event['detail']
    severity = finding['severity']
    finding_type = finding['type']

    # Auto-isolate compromised instances
    if severity >= 8 and 'EC2' in finding_type:
        instance_id = finding['resource']['instanceDetails']['instanceId']

        ec2 = boto3.client('ec2')

        # Apply isolation security group
        ec2.modify_instance_attribute(
            InstanceId=instance_id,
            Groups=['sg-isolation']
        )

        # Create snapshot for forensics
        ec2.create_snapshot(
            VolumeId=finding['resource']['instanceDetails']['volumeId'],
            Description=f'Forensic snapshot - {finding_type}'
        )

    return {'statusCode': 200}

Export Findings to S3

Archive findings for long-term analysis:

# Create S3 bucket for findings
aws s3api create-bucket \
  --bucket guardduty-findings-archive \
  --region us-east-1

# Configure export
aws guardduty create-publishing-destination \
  --detector-id "$DETECTOR_ID" \
  --destination-type S3 \
  --destination-properties DestinationArn=arn:aws:s3:::guardduty-findings-archive,KmsKeyArn=arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012

Verify GuardDuty Configuration

# Check detector status
aws guardduty get-detector \
  --detector-id "$DETECTOR_ID"

# List enabled data sources
aws guardduty get-detector \
  --detector-id "$DETECTOR_ID" \
  --query 'DataSources'

# Check finding statistics
aws guardduty get-findings-statistics \
  --detector-id "$DETECTOR_ID" \
  --finding-statistic-types COUNT_BY_SEVERITY

# List all filters (suppression rules)
aws guardduty list-filters \
  --detector-id "$DETECTOR_ID"

Best Practices Summary

PracticeRecommendation
CoverageEnable in all regions, even unused ones
Data SourcesEnable all available protection plans
NotificationsConfigure alerts for high/critical findings
IntegrationSend findings to Security Hub
Multi-AccountUse delegated administrator
ResponseAutomate containment actions
SuppressionDocument and review rules quarterly

Frequently Asked Questions

Find answers to common questions

GuardDuty pricing is based on the volume of data analyzed. CloudTrail management events cost $4.00 per million events for the first 500 million. VPC Flow Logs and DNS query logs cost $1.00-1.50 per GB. S3 data events cost $0.80 per million events. Most organizations pay $10-100 per month for basic protection. There's a 30-day free trial to evaluate costs in your environment. Use the AWS pricing calculator with your actual usage data for accurate estimates.

Need Professional Help?

Our team of experts can help you implement and configure these solutions for your organization.