Skip to main content
AWSSecurityintermediate

Amazon GuardDuty Guide

Detect threats with GuardDuty: findings, multi-account setup, automated remediation, and Security Hub integration.

CloudToolStack Team24 min readPublished Mar 14, 2026

Prerequisites

  • AWS account with administrative access
  • Basic understanding of AWS security services

Introduction to GuardDuty

Amazon GuardDuty is a managed threat detection service that continuously monitors your AWS accounts and workloads for malicious activity and unauthorized behavior. It analyzes data from multiple AWS sources including CloudTrail management events, CloudTrail S3 data events, VPC Flow Logs, DNS logs, EKS audit logs, and Lambda network activity without requiring you to deploy or manage any infrastructure.

GuardDuty uses machine learning, anomaly detection, and integrated threat intelligence feeds (from AWS and third-party sources like CrowdStrike and Proofpoint) to identify threats. When it detects suspicious activity, it generates a finding with detailed context about what happened, which resource was affected, and the severity level. Findings can be sent to EventBridge for automated remediation, to Security Hub for centralized visibility, or to an S3 bucket for long-term storage.

This guide covers enabling GuardDuty, understanding finding types, configuring multi-account deployments, building automated remediation workflows, and integrating GuardDuty with your broader security posture.

30-Day Free Trial

GuardDuty offers a 30-day free trial with full functionality. After the trial, pricing is based on the volume of data analyzed: CloudTrail events, VPC Flow Logs, and DNS logs. The trial period shows your estimated monthly cost so you can evaluate before committing. Most accounts pay between $5-50/month depending on activity volume.

Enabling GuardDuty

Enabling GuardDuty is straightforward: a single API call activates it for the current region. However, GuardDuty is a regional service, so you must enable it in every region where you operate (and ideally in all regions to detect unauthorized activity in regions you do not normally use).

bash
# Enable GuardDuty in the current region
aws guardduty create-detector \
  --enable \
  --finding-publishing-frequency FIFTEEN_MINUTES \
  --data-sources '{
    "S3Logs": {"Enable": true},
    "Kubernetes": {"AuditLogs": {"Enable": true}},
    "MalwareProtection": {"ScanEc2InstanceWithFindings": {"EbsVolumes": true}}
  }'

# 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" 2>/dev/null || true
done

# Verify GuardDuty is active
aws guardduty list-detectors --query 'DetectorIds[0]' --output text

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

Terraform Deployment

hcl
resource "aws_guardduty_detector" "main" {
  enable = true

  finding_publishing_frequency = "FIFTEEN_MINUTES"

  datasources {
    s3_logs {
      enable = true
    }
    kubernetes {
      audit_logs {
        enable = true
      }
    }
    malware_protection {
      scan_ec2_instance_with_findings {
        ebs_volumes {
          enable = true
        }
      }
    }
  }

  tags = {
    Environment = "production"
    Service     = "security"
  }
}

# Enable in multiple regions using provider aliases
provider "aws" {
  alias  = "us_west_2"
  region = "us-west-2"
}

resource "aws_guardduty_detector" "us_west_2" {
  provider = aws.us_west_2
  enable   = true

  datasources {
    s3_logs {
      enable = true
    }
  }
}

Understanding GuardDuty Findings

GuardDuty findings are organized by resource type and threat purpose. Each finding includes a type name following the pattern ThreatPurpose:ResourceType/ThreatName, a severity level (Low, Medium, or High), affected resource details, and actor information.

Finding Types by Category

CategoryExample FindingWhat It Means
ReconnaissanceRecon:EC2/PortProbeUnprotectedPortAn EC2 instance port is being probed by a known attacker
Unauthorized AccessUnauthorizedAccess:IAMUser/ConsoleLoginSuccess.BSuccessful console login from unusual location
Credential ExfiltrationUnauthorizedAccess:IAMUser/InstanceCredentialExfiltrationEC2 instance credentials used from external IP
CryptocurrencyCryptoCurrency:EC2/BitcoinTool.B!DNSEC2 instance communicating with Bitcoin-related domains
BackdoorBackdoor:EC2/C&CActivity.B!DNSEC2 instance querying command-and-control server
Data ExfiltrationExfiltration:S3/AnomalousBehaviorUnusual S3 API calls suggesting data theft
KubernetesPrivilegeEscalation:Kubernetes/PrivilegedContainerPrivileged container launched in EKS cluster
bash
# List recent findings
DETECTOR_ID=$(aws guardduty list-detectors --query 'DetectorIds[0]' --output text)

aws guardduty list-findings \
  --detector-id "$DETECTOR_ID" \
  --finding-criteria '{
    "Criterion": {
      "severity": {"Gte": 7},
      "updatedAt": {"GreaterThan": 1709251200000}
    }
  }' \
  --sort-criteria '{"AttributeName": "severity", "OrderBy": "DESC"}' \
  --max-results 20

# Get detailed finding information
aws guardduty get-findings \
  --detector-id "$DETECTOR_ID" \
  --finding-ids "finding-id-1" "finding-id-2" \
  --query 'Findings[].{Type:Type, Severity:Severity, Title:Title, Description:Description}'

Sample Findings for Testing

You can generate sample findings to test your alerting and remediation pipelines without waiting for real threats. Use aws guardduty create-sample-findings to generate findings across all detection types. These are clearly marked as sample findings and will not trigger real security incidents in properly configured workflows.

Multi-Account GuardDuty with AWS Organizations

In an AWS Organizations environment, you should designate a delegated administrator account for GuardDuty. This account automatically manages GuardDuty for all member accounts, enabling centralized finding visibility without requiring manual invitation in each account.

bash
# From the management account: delegate GuardDuty administration
aws guardduty enable-organization-admin-account \
  --admin-account-id 111222333444

# From the delegated admin: auto-enable for new accounts
DETECTOR_ID=$(aws guardduty list-detectors --query 'DetectorIds[0]' --output text)

aws guardduty update-organization-configuration \
  --detector-id "$DETECTOR_ID" \
  --auto-enable \
  --data-sources '{
    "S3Logs": {"AutoEnable": true},
    "Kubernetes": {"AuditLogs": {"AutoEnable": true}},
    "MalwareProtection": {"ScanEc2InstanceWithFindings": {"EbsVolumes": {"AutoEnable": true}}}
  }'

# List member accounts
aws guardduty list-members \
  --detector-id "$DETECTOR_ID" \
  --query 'Members[].{Account:AccountId, Status:RelationshipStatus}' \
  --output table

Terraform Multi-Account Setup

hcl
# Delegated admin configuration
resource "aws_guardduty_organization_admin_account" "main" {
  admin_account_id = var.security_account_id
}

resource "aws_guardduty_organization_configuration" "main" {
  auto_enable_organization_members = "ALL"
  detector_id                      = aws_guardduty_detector.main.id

  datasources {
    s3_logs {
      auto_enable = true
    }
    kubernetes {
      audit_logs {
        enable = true
      }
    }
    malware_protection {
      scan_ec2_instance_with_findings {
        ebs_volumes {
          auto_enable = true
        }
      }
    }
  }
}

Automated Remediation with EventBridge

The real power of GuardDuty comes from automated remediation. When GuardDuty generates a high-severity finding, you can trigger an EventBridge rule that invokes a Lambda function, Step Functions workflow, or SNS notification to respond automatically. Common remediation actions include isolating compromised EC2 instances, revoking IAM credentials, blocking suspicious IP addresses, and notifying the security team.

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

# Add a Lambda target for auto-remediation
aws events put-targets \
  --rule "guardduty-high-severity" \
  --targets '[
    {
      "Id": "remediation-lambda",
      "Arn": "arn:aws:lambda:us-east-1:123456789012:function:guardduty-remediation"
    },
    {
      "Id": "security-team-sns",
      "Arn": "arn:aws:sns:us-east-1:123456789012:security-alerts"
    }
  ]'

Remediation Lambda Example

python
import boto3
import json

ec2 = boto3.client("ec2")
iam = boto3.client("iam")

def handler(event, context):
    finding = event["detail"]
    finding_type = finding["type"]
    severity = finding["severity"]

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

    # Isolate compromised EC2 instances
    if "EC2" in finding_type and severity >= 8:
        instance_id = finding["resource"]["instanceDetails"]["instanceId"]
        isolate_instance(instance_id)

    # Disable compromised IAM credentials
    if "IAMUser" in finding_type and "CredentialExfiltration" in finding_type:
        access_key_id = finding["resource"]["accessKeyDetails"]["accessKeyId"]
        username = finding["resource"]["accessKeyDetails"]["userName"]
        disable_access_key(username, access_key_id)

    return {"statusCode": 200, "body": "Remediation completed"}

def isolate_instance(instance_id):
    """Replace security groups with an isolation SG that blocks all traffic."""
    # Create or find isolation security group
    vpc_id = ec2.describe_instances(
        InstanceIds=[instance_id]
    )["Reservations"][0]["Instances"][0]["VpcId"]

    # Apply isolation security group (no inbound/outbound rules)
    ec2.modify_instance_attribute(
        InstanceId=instance_id,
        Groups=["sg-isolation-group-id"]
    )
    print(f"Isolated instance {instance_id}")

def disable_access_key(username, access_key_id):
    """Disable a compromised IAM access key."""
    iam.update_access_key(
        UserName=username,
        AccessKeyId=access_key_id,
        Status="Inactive"
    )
    print(f"Disabled access key {access_key_id} for user {username}")

Threat Intelligence and IP/Domain Lists

GuardDuty uses built-in threat intelligence feeds, but you can also provide your own trusted IP lists (to suppress findings from known safe IPs like your VPN endpoints) and threat IP lists (to generate findings when your resources communicate with known bad actors).

bash
# Upload a trusted IP list (IPs that should not generate findings)
DETECTOR_ID=$(aws guardduty list-detectors --query 'DetectorIds[0]' --output text)

aws guardduty create-ip-set \
  --detector-id "$DETECTOR_ID" \
  --name "corporate-vpn-ips" \
  --format TXT \
  --location "s3://my-security-bucket/trusted-ips.txt" \
  --activate

# Upload a threat intelligence list
aws guardduty create-threat-intel-set \
  --detector-id "$DETECTOR_ID" \
  --name "custom-threat-feed" \
  --format TXT \
  --location "s3://my-security-bucket/threat-ips.txt" \
  --activate

# Create suppression rules for known false positives
aws guardduty create-filter \
  --detector-id "$DETECTOR_ID" \
  --name "suppress-internal-scanner" \
  --action ARCHIVE \
  --finding-criteria '{
    "Criterion": {
      "type": {"Eq": ["Recon:EC2/PortProbeUnprotectedPort"]},
      "resource.instanceDetails.tags.value": {"Eq": ["security-scanner"]}
    }
  }'

Security Hub Integration

GuardDuty findings are automatically sent to AWS Security Hub when both services are enabled. Security Hub provides a centralized dashboard that aggregates findings from GuardDuty, Inspector, Macie, Firewall Manager, and third-party tools. This gives your security team a single pane of glass for all security findings.

bash
# Enable Security Hub (if not already enabled)
aws securityhub enable-security-hub \
  --enable-default-standards

# View GuardDuty findings in Security Hub
aws securityhub get-findings \
  --filters '{
    "ProductName": [{"Value": "GuardDuty", "Comparison": "EQUALS"}],
    "SeverityLabel": [{"Value": "HIGH", "Comparison": "EQUALS"}]
  }' \
  --sort-criteria '[{"Field": "LastObservedAt", "SortOrder": "desc"}]' \
  --max-results 10

Exporting and Analyzing Findings

For long-term analysis and compliance, configure GuardDuty to export findings to an S3 bucket. Exported findings can be queried with Athena, visualized in QuickSight, or ingested into a SIEM platform like Splunk, Datadog, or Elastic.

bash
# Configure finding export to S3
DETECTOR_ID=$(aws guardduty list-detectors --query 'DetectorIds[0]' --output text)

aws guardduty create-publishing-destination \
  --detector-id "$DETECTOR_ID" \
  --destination-type S3 \
  --destination-properties '{
    "DestinationArn": "arn:aws:s3:::guardduty-findings-bucket",
    "KmsKeyArn": "arn:aws:kms:us-east-1:123456789012:key/key-id"
  }'

# GuardDuty statistics
aws guardduty get-findings-statistics \
  --detector-id "$DETECTOR_ID" \
  --finding-statistic-types COUNT_BY_SEVERITY \
  --finding-criteria '{
    "Criterion": {
      "updatedAt": {"GreaterThan": 1709251200000}
    }
  }'

Cost Optimization

GuardDuty costs are driven primarily by VPC Flow Log and CloudTrail event volume. To estimate costs before enabling, use the GuardDuty usage statistics API or check the estimated cost during the 30-day free trial. In most accounts, GuardDuty costs $5-50/month. The security value far exceeds this cost: detecting a cryptocurrency mining attack or credential exfiltration early can save thousands of dollars.

AWS Security Hub OverviewAWS Organizations & SCPs Guide

Key Takeaways

  1. 1GuardDuty analyzes CloudTrail, VPC Flow Logs, and DNS logs without deploying infrastructure.
  2. 2Findings follow the pattern ThreatPurpose:ResourceType/ThreatName with Low, Medium, or High severity.
  3. 3Multi-account deployment via Organizations provides centralized finding visibility.
  4. 4EventBridge rules enable automated remediation for high-severity findings.

Frequently Asked Questions

How much does GuardDuty cost?
GuardDuty pricing is based on data analyzed: CloudTrail events, VPC Flow Logs, and DNS logs. Most accounts pay $5-50/month. There is a 30-day free trial that shows estimated monthly costs. The security value typically far exceeds the cost.
Can GuardDuty detect insider threats?
Yes. GuardDuty uses anomaly detection on IAM behavior to identify unusual API calls, console logins from unexpected locations, credential exfiltration, and privilege escalation. It also detects cryptocurrency mining, data exfiltration, and command-and-control communication.

Written by CloudToolStack Team

Cloud engineers and architects with hands-on experience across AWS, Azure, and GCP. We write guides based on real-world production patterns, not just documentation rewrites.

Disclaimer: This guide is for educational purposes. Cloud services change frequently; always refer to official documentation for the latest information. AWS, Azure, and GCP are trademarks of their respective owners.