Amazon GuardDuty gets searched more than 2,400 times a month in the US alone, and for good reason: it’s the fastest way to get real threat detection running across an AWS account without deploying a single agent. This tutorial walks through enabling GuardDuty from a cold start, turning on the protection plans that actually matter (Malware Protection, EKS Runtime Monitoring, Lambda Protection, S3 Protection), wiring findings into Security Hub and Slack, tuning out false positives with suppression rules, and setting up multi-account coverage through AWS Organizations. By the end you’ll have a working detector, an automated notification pipeline, and a documented process for triaging what GuardDuty throws at you.
GuardDuty isn’t new, but the service AWS ships in September 2026 looks different from the one that launched back in 2017. Extended Threat Detection now correlates multi-stage attack sequences automatically, EC2 and ECS runtime coverage expanded in December 2025, and the pricing model has settled into a predictable tiered structure that makes budgeting far less of a guessing game than it used to be. This guide covers the current version end to end, and fits alongside the broader cybersecurity threat landscape teams are managing across their AWS estate this year.
Don't miss new tech stories on Google
Add Tech Insider once in the Google app and our stories appear in your news suggestions.
What AWS GuardDuty Actually Monitors
GuardDuty is Amazon’s threat detection service for AWS accounts and workloads, and it’s the piece most cloud security teams reach for first when they need continuous monitoring without standing up their own detection pipeline. GuardDuty is a managed threat detection service, meaning AWS runs the analysis engine and you never install or patch anything. Once enabled, it continuously analyzes three foundational data sources: AWS CloudTrail management and data events, VPC Flow Logs, and Route 53 Resolver DNS query logs. That foundational layer is enabled automatically the moment you turn the service on, at no separate configuration step.
On top of the foundational layer sit optional protection plans that extend coverage into specific AWS services. S3 Protection watches object-level API activity for data exfiltration patterns. EKS Protection and EKS Runtime Monitoring cover Kubernetes audit logs and in-cluster process behavior. Malware Protection scans EBS volumes attached to EC2 instances and container workloads when GuardDuty flags suspicious activity. Lambda Protection analyzes network activity logs from Lambda function invocations. RDS Protection profiles login activity against your databases for credential-stuffing and anomalous access patterns.
The newest addition to the lineup is Extended Threat Detection, which AWS describes as using AI and machine learning to identify complex, multi-stage attack sequences rather than flagging isolated events. In December 2025, AWS expanded Extended Threat Detection coverage to EC2 instances and ECS tasks across every region where GuardDuty operates, following an earlier rollout to EKS clusters in mid-2025. Coverage depth scales with how many protection plans you’ve turned on, so a bare-bones foundational setup gets thinner attack-sequence correlation than an account running the full stack.
Prerequisites and Versions
Before starting, confirm you have the following in place. GuardDuty itself doesn’t have a version number the way self-hosted software does, since it’s a fully managed AWS service, but the surrounding tooling does.
- An AWS account with administrator or GuardDutyFullAccess IAM permissions
- AWS CLI v2 (2.15 or newer) installed and configured with
aws configure - Python 3.10+ if you plan to run the sample automated-response Lambda later in this guide
- An AWS Organizations setup already in place if you’re rolling GuardDuty out across multiple accounts (optional for single-account setups)
- A Slack workspace with permission to add an incoming webhook, if you want findings routed to chat
- Roughly 90 minutes for the full walkthrough, including the 30-day free trial activation and a validation pass
Every AWS account gets a 30-day GuardDuty free trial the first time the service is enabled in a given region, which is enough runway to validate the setup before committing to ongoing spend.
IAM Permissions You Need Before You Start
GuardDuty setup fails more often on missing IAM permissions than on anything else in this guide, so it’s worth getting the policy right before touching the console or CLI. The managed policy AmazonGuardDutyFullAccess covers everything in this tutorial, but production environments usually want something narrower. A working least-privilege policy for the person or role running setup needs create/update rights on detectors, filters, IP sets, publishing destinations, and organization configuration:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "GuardDutySetup",
"Effect": "Allow",
"Action": [
"guardduty:CreateDetector",
"guardduty:UpdateDetector",
"guardduty:GetDetector",
"guardduty:ListDetectors",
"guardduty:CreateFilter",
"guardduty:CreateIPSet",
"guardduty:CreatePublishingDestination",
"guardduty:CreateSampleFindings",
"guardduty:GetFindings",
"guardduty:ListFindings",
"guardduty:EnableOrganizationAdminAccount",
"guardduty:UpdateOrganizationConfiguration",
"guardduty:UpdateMalwareProtectionPlan"
],
"Resource": "*"
},
{
"Sid": "GuardDutyS3Export",
"Effect": "Allow",
"Action": ["s3:PutObject", "s3:GetBucketLocation"],
"Resource": "arn:aws:s3:::your-security-bucket/*"
}
]
}
Two details trip people up here. First, EnableOrganizationAdminAccount only works when called by the AWS Organizations management account itself — attaching this permission to a role in a member account does nothing, since AWS checks the caller’s account identity against the organization’s management account ID, not just the IAM policy. Second, if you’re using a customer-managed KMS key for the S3 export bucket from Step 9, the key policy needs a separate statement granting GuardDuty’s service principal guardduty.amazonaws.com permission to use the key for encryption, or publishing destination creation fails with an opaque access-denied error that doesn’t clearly point back to KMS.
Step 1: Enable GuardDuty in a Single Account
Start with the console for the first pass, since it gives you immediate visual confirmation. Sign in to the AWS Management Console, search for GuardDuty, and click “Enable GuardDuty.” The console creates a detector resource in the background, which is the object that represents your GuardDuty configuration in that region.
For repeatable deployments, use the CLI instead. This is the command you’ll want in any infrastructure-as-code pipeline:
aws guardduty create-detector \
--enable \
--finding-publishing-frequency FIFTEEN_MINUTES \
--data-sources '{"S3Logs":{"Enable":true},"Kubernetes":{"AuditLogs":{"Enable":true}},"MalwareProtection":{"ScanEc2InstanceWithFindings":{"EbsVolumes":true}}}'
The --finding-publishing-frequency flag controls how often GuardDuty pushes findings to CloudWatch Events (and by extension, to EventBridge). Setting it to FIFTEEN_MINUTES gives you the fastest turnaround; the default is six hours, which is too slow if you’re routing findings to Slack for near-real-time triage. Note the detector ID returned in the response — you’ll need it for nearly every subsequent command.
aws guardduty list-detectors
# {
# "DetectorIds": ["a1b2c3d4e5f6g7h8i9j0"]
# }
GuardDuty operates on a per-region basis, meaning enabling it in us-east-1 gives you zero coverage in eu-west-1. If your workloads span multiple regions, repeat this step in each one, or move straight to the multi-region automation covered in Step 7. A quick way to check which regions you’re already missing is to loop the list-detectors call across every enabled region and diff it against your actual resource footprint:
for region in $(aws ec2 describe-regions --query 'Regions[].RegionName' --output text); do
echo "== $region =="
aws guardduty list-detectors --region "$region" --output text
done
Any region that returns an empty result but shows up elsewhere in your resource inventory (check Cost Explorer or Resource Explorer for a fast cross-check) is a blind spot worth closing before moving on.
Step 2: Turn On the Protection Plans That Matter
Foundational detection alone catches network- and API-level anomalies, but it misses malware sitting on a disk or anomalous behavior inside a running container. The optional protection plans close that gap, and each one can be toggled independently depending on what you’re actually running.
Malware Protection deserves priority if you run EC2 or ECS workloads, since it triggers an on-demand scan of EBS volumes whenever GuardDuty sees a suspicious finding tied to that instance, without needing an always-on agent. Enable it with:
aws guardduty update-malware-protection-plan \
--detector-id a1b2c3d4e5f6g7h8i9j0 \
--scan-ec2-instance-with-findings '{"EbsVolumes":true}'
If you’re running EKS, turn on both EKS Protection (audit log analysis) and EKS Runtime Monitoring (in-cluster process and file activity) separately, since they cover different layers of the stack:
aws guardduty update-detector \
--detector-id a1b2c3d4e5f6g7h8i9j0 \
--features Name=EKS_AUDIT_LOGS,Status=ENABLED \
Name=EKS_RUNTIME_MONITORING,Status=ENABLED,AdditionalConfiguration='[{Name=EKS_ADDON_MANAGEMENT,Status=ENABLED}]'
Lambda Protection and RDS Protection follow the same pattern — enable via the --features flag on update-detector with the relevant feature name. Extended Threat Detection itself doesn’t need a toggle; AWS enables it automatically for every account running GuardDuty, at no additional charge beyond the underlying protection plan costs.
Step 3: Understand What Findings Look Like
A GuardDuty finding is a structured JSON object describing a specific detected behavior, tagged with a type, a severity score, and the resource it affects. Finding type names follow a consistent pattern: ThreatPurpose:ResourceTypeAffected/ThreatFamilyName.DetectionMechanism. A few examples that show up frequently in production accounts:
Backdoor:Runtime/C&CActivity.B— a workload is communicating with a known command-and-control serverCryptoCurrency:Runtime/BitcoinTool.B— cryptocurrency mining software detected on a runtime resourceExecution:Runtime/NewLibraryLoaded— an unexpected library was loaded into a running container processUnauthorizedAccess:EC2/SSHBruteForce— repeated failed SSH attempts against an EC2 instanceRecon:IAMUser/MaliciousIPCaller— API calls originating from an IP address on a known threat list
Extended Threat Detection’s real value shows up when it links several of these together. AWS’s documented example shows a container workload triggering a Backdoor finding, a CryptoCurrency finding, and an Execution finding within a short window — individually each is a moderate-severity alert, but correlated together they represent a full compromise chain: reverse shell, privilege escalation, command-and-control contact, and mining payload execution. That correlated view is what shows up as a single high-confidence “attack sequence” finding rather than three separate low-priority tickets.
Severity is scored on a 1.0–10.0 scale and bucketed into Low, Medium, High, and Critical. Retrieve a specific finding’s full detail with:
aws guardduty get-findings \
--detector-id a1b2c3d4e5f6g7h8i9j0 \
--finding-ids "abc123def456"
Reading a Real Attack Sequence Finding
It helps to walk through one concrete example rather than treat attack sequences as an abstraction. AWS documents a scenario involving an ECS task running a compromised container image. The sequence starts with an Execution:Runtime/NewLibraryLoaded finding as the attacker’s payload loads an unexpected shared library into the running process — on its own, a Low-to-Medium severity event that could plausibly be a legitimate dependency update. Within minutes, a Backdoor:Runtime/C&CActivity.B finding fires as the same task establishes an outbound connection to a known command-and-control IP. Shortly after, a CryptoCurrency:Runtime/BitcoinTool.B finding shows mining binaries executing inside the container.
Handled individually, none of those three findings alone would necessarily justify paging an on-call engineer at 2 a.m. Correlated by Extended Threat Detection into a single attack-sequence finding, the picture changes completely: this is a full compromise chain covering initial execution, command-and-control contact, and monetization through mining. That’s the entire point of the feature — it takes the analyst work of connecting three separate low-confidence signals into one high-confidence narrative and does it automatically, which is exactly the kind of triage burden that used to require a dedicated SOC analyst staring at a dashboard. When you see an attack-sequence finding in your GuardDuty console, treat it as several orders of magnitude more urgent than any of its component findings would suggest on their own.
Step 4: Generate Sample Findings to Test Your Pipeline
You don’t want to wait for a real attack to find out your Slack integration is broken. GuardDuty ships a built-in sample-finding generator that populates one example of every finding type into your detector, letting you validate the entire downstream pipeline without touching production traffic.
aws guardduty create-sample-findings \
--detector-id a1b2c3d4e5f6g7h8i9j0 \
--finding-types "Backdoor:EC2/C&CActivity.B!DNS" "UnauthorizedAccess:IAMUser/ConsoleLoginSuccess.B"
Sample findings are clearly marked with a sample flag in the JSON payload, so they won’t corrupt your real detection metrics, but they do flow through EventBridge exactly like genuine findings, which makes them ideal for testing notification routing end to end.
Step 5: Route Findings to EventBridge and Slack
GuardDuty pushes every finding to EventBridge automatically once the detector is created — there’s no separate opt-in. What you need to build is a rule that catches those events and forwards them somewhere a human will actually see them.
Create an EventBridge rule that matches GuardDuty findings above a severity threshold:
aws events put-rule \
--name guardduty-high-severity \
--event-pattern '{
"source": ["aws.guardduty"],
"detail-type": ["GuardDuty Finding"],
"detail": {
"severity": [{"numeric": [">=", 7]}]
}
}'
Then point the rule at a Lambda function that formats the finding and posts it to a Slack incoming webhook. A minimal handler looks like this:
import json
import urllib.request
import os
SLACK_WEBHOOK = os.environ["SLACK_WEBHOOK_URL"]
def handler(event, context):
detail = event["detail"]
message = {
"text": (
f":rotating_light: *{detail['title']}*\n"
f"Severity: {detail['severity']}\n"
f"Type: {detail['type']}\n"
f"Account: {detail['accountId']}\n"
f"Region: {detail['region']}"
)
}
req = urllib.request.Request(
SLACK_WEBHOOK,
data=json.dumps(message).encode("utf-8"),
headers={"Content-Type": "application/json"},
)
urllib.request.urlopen(req)
return {"statusCode": 200}
Set the severity threshold at 7 or above to start — that filters out low-confidence reconnaissance noise and surfaces only findings worth an immediate look. You can always lower the bar once you’ve tuned suppression rules in Step 8.
Step 6: Integrate GuardDuty With Security Hub
If you’re already running AWS Security Hub for centralized posture management, GuardDuty findings feed into it as a native data source once you flip the integration on. This gives you one pane of glass for GuardDuty threat findings alongside configuration-drift and compliance findings from other services.
aws securityhub enable-import-findings-for-product \
--product-arn arn:aws:securityhub:us-east-1::product/aws/guardduty
Security Hub normalizes GuardDuty’s finding format into the AWS Security Finding Format (ASFF), which means the same finding can now be correlated with anything else feeding Security Hub — Inspector vulnerability scans, IAM Access Analyzer results, or third-party tools that also publish into ASFF. For deeper forensic work on a specific finding, pivot from Security Hub into Amazon Detective, which builds a graph view of the account, IAM principal, and IP addresses involved.
Step 7: Roll Out Multi-Account Coverage With AWS Organizations
Enabling GuardDuty account by account doesn’t scale past a handful of AWS accounts. If you’re running AWS Organizations, designate a security account as the GuardDuty delegated administrator, and every member account’s findings roll up to it automatically.
From the management account, designate the delegated admin:
aws guardduty enable-organization-admin-account \
--admin-account-id 111122223333
Then, from the delegated admin account, configure auto-enrollment so any new account joining the organization gets GuardDuty turned on without manual intervention:
aws guardduty update-organization-configuration \
--detector-id a1b2c3d4e5f6g7h8i9j0 \
--auto-enable-organization-members ALL \
--features Name=S3_DATA_EVENTS,AutoEnable=ALL \
Name=EKS_AUDIT_LOGS,AutoEnable=ALL \
Name=RUNTIME_MONITORING,AutoEnable=ALL
This is the setup pattern used by security teams managing dozens or hundreds of AWS accounts: one detector configuration, applied consistently everywhere, with new accounts inheriting coverage the moment they land in the organization. It also means a single dashboard for findings instead of logging into dozens of separate accounts to check for threats.
Step 8: Tune Out Noise With Suppression Rules and Trusted IP Lists
Every threat detection service produces some volume of findings that are technically accurate but operationally irrelevant — a vulnerability scanner your security team runs weekly, an internal IP range that legitimately probes ports as part of a health check. Left unaddressed, this noise trains analysts to ignore GuardDuty entirely, which defeats the purpose.
Suppression rules let you archive findings matching specific criteria automatically, so they never hit your Slack channel or Security Hub dashboard:
aws guardduty create-filter \
--detector-id a1b2c3d4e5f6g7h8i9j0 \
--name suppress-internal-scanner \
--action ARCHIVE \
--finding-criteria '{
"Criterion": {
"resource.instanceDetails.networkInterfaces.privateIpAddress": {
"Eq": ["10.0.5.12"]
}
}
}'
For IP ranges you always trust — a corporate VPN egress, a known scanning tool’s static IP — upload a trusted IP list instead of writing a filter per finding type:
aws guardduty create-ip-set \
--detector-id a1b2c3d4e5f6g7h8i9j0 \
--name corporate-vpn-range \
--format TXT \
--location s3://your-security-bucket/trusted-ips.txt \
--activate
Review suppression rules quarterly. It’s easy to suppress a finding to silence a one-time false positive and forget to remove the rule, which quietly creates a blind spot months later.
Step 9: Export Findings to S3 for Long-Term Retention
GuardDuty retains findings natively for 90 days. That’s fine for active triage but not enough for compliance audits, incident post-mortems six months later, or SIEM ingestion pipelines that expect a durable data lake. Export findings continuously to S3:
aws guardduty create-publishing-destination \
--detector-id a1b2c3d4e5f6g7h8i9j0 \
--destination-type S3 \
--destination-properties '{
"DestinationArn": "arn:aws:s3:::your-security-bucket/guardduty-findings",
"KmsKeyArn": "arn:aws:kms:us-east-1:111122223333:key/your-kms-key-id"
}'
Encrypt the destination bucket with a customer-managed KMS key rather than the default S3-managed key — findings data includes IP addresses, IAM principal ARNs, and resource identifiers that qualify as sensitive operational data under most compliance frameworks. If you’re also running Amazon Macie, point it at this bucket too, since findings exports occasionally contain embedded metadata worth scanning.
Step 10: Build an Automated Response for Critical Findings
For your highest-severity finding types, waiting on a human to read a Slack message and manually isolate an instance costs precious minutes. A common automated-response pattern uses Lambda to quarantine an EC2 instance the moment a high-confidence compromise finding fires, by swapping its security group to one that allows no inbound or outbound traffic.
import boto3
ec2 = boto3.client("ec2")
QUARANTINE_SG = "sg-0123456789abcdef0"
def handler(event, context):
detail = event["detail"]
if detail["severity"] < 8.0:
return {"statusCode": 200, "body": "Below auto-response threshold"}
instance_id = detail.get("resource", {}).get("instanceDetails", {}).get("instanceId")
if not instance_id:
return {"statusCode": 200, "body": "No EC2 instance in finding"}
ec2.modify_instance_attribute(
InstanceId=instance_id,
Groups=[QUARANTINE_SG],
)
return {"statusCode": 200, "body": f"Quarantined {instance_id}"}
Test this against sample findings first, and gate the severity threshold conservatively. An overly aggressive auto-quarantine policy that fires on medium-confidence findings will eventually take down a production instance over a false positive, which is a worse outcome than the threat it was meant to stop.
Step 11: Verify the Full Configuration
Before calling the setup done, run through a verification checklist. Confirm the detector is active and check which data sources and features are enabled:
aws guardduty get-detector --detector-id a1b2c3d4e5f6g7h8i9j0
A healthy response shows "Status": "ENABLED" and lists every feature you turned on in Step 2 with a corresponding ENABLED status. Re-run the sample finding generator from Step 4 and confirm it appears in Slack within a minute or two — that's your end-to-end proof that detection, EventBridge routing, and notification are all wired together correctly.
GuardDuty Pricing Breakdown for 2026
GuardDuty pricing runs on a consumption model tied to the volume of data analyzed, not a flat per-account or per-instance fee. Foundational detection (VPC Flow Logs and DNS query log analysis) uses tiered per-GB pricing in us-east-1, while CloudTrail management event analysis is billed per million events. Optional protection plans each carry their own per-GB or per-scan rate on top of the foundational cost.
| Data source / plan | Pricing basis (us-east-1) | Rate |
|---|---|---|
| VPC Flow Logs + DNS logs | Per GB/month, first 500 GB | $1.00/GB |
| VPC Flow Logs + DNS logs | Per GB/month, next 2,000 GB | $0.50/GB |
| VPC Flow Logs + DNS logs | Per GB/month, over 2,500 GB | $0.25/GB |
| CloudTrail management events | Per million events/month | $4.00 |
| Extended Threat Detection | Included with GuardDuty | No additional charge |
Extended Threat Detection is worth calling out separately: AWS documentation states there is no additional cost associated with using it, and it's automatically enabled for every account with GuardDuty turned on, in every region where the service operates, including AWS GovCloud (US) and China regions as of March 2025. You're not paying extra for attack-sequence correlation — you're paying for the underlying protection plans it draws signal from. AWS lists the full current feature set on the GuardDuty features page.
For cost control, start with foundational detection and CloudTrail analysis only, monitor the bill for a full month, then layer in protection plans one at a time against workloads where they add real coverage. Enabling every protection plan across a large multi-account estate on day one is how teams end up with a GuardDuty bill that outsizes what they actually get value from.
A worked example makes the tiered pricing easier to plan around. Say a mid-sized account generates 800 GB of combined VPC Flow Log and DNS query data in a month, plus 3 million CloudTrail management events. The first 500 GB is billed at $1.00/GB ($500), the remaining 300 GB falls into the second tier at $0.50/GB ($150), and CloudTrail events run 3 × $4.00 ($12). That's roughly $662 for foundational detection before any protection plans, which is why teams with high-traffic VPCs often see their GuardDuty line item jump sharply the month after a new service goes into production — the tiered discount only kicks in once you clear the first 500 GB threshold, and a busy new microservice can push you past that fast.
GuardDuty vs. Other AWS Threat Detection Options
GuardDuty doesn't operate alone in the AWS security stack, and understanding where it stops and other services start avoids duplicate spend and duplicate alerts.
| Service | Primary focus | Relationship to GuardDuty |
|---|---|---|
| Amazon Inspector | Vulnerability scanning of EC2, ECR images, Lambda code | Complementary — Inspector finds weaknesses, GuardDuty finds active exploitation |
| AWS Security Hub | Centralized posture management and finding aggregation | Downstream consumer of GuardDuty findings via ASFF |
| Amazon Detective | Graph-based forensic investigation | Downstream — pivot here from a GuardDuty finding for root-cause analysis |
| AWS Shield | DDoS protection at network and application layer | Separate detection domain, no direct overlap |
| Amazon Macie | Sensitive data discovery and classification in S3 | Separate focus — data classification vs. threat behavior |
Teams running a full AWS VPC Lattice service-to-service networking layer should also enable GuardDuty's VPC Flow Log analysis at the Lattice-adjacent VPCs, since east-west traffic between services is exactly where lateral movement after an initial compromise tends to show up.
The overlap that causes the most confusion in practice is GuardDuty versus Amazon Inspector, since both sound like they're solving "find the vulnerability" problems. They aren't. Inspector scans EC2 instances, ECR container images, and Lambda functions for known CVEs and misconfigurations before anything bad happens — it's a preventive, point-in-time scanner. GuardDuty watches live behavior for signs that something already went wrong: unusual API calls, traffic to a known-bad IP, a process that shouldn't be running. Running both together closes more of the kill chain than either does alone — Inspector shrinks the attack surface, GuardDuty catches what gets through anyway.
5 Common Pitfalls When Setting Up GuardDuty
Most GuardDuty misconfigurations aren't dramatic failures — they're quiet gaps that only surface during an incident, when it's too late to fix them cheaply. The five below account for the large majority of avoidable coverage gaps seen in real account audits, and every one of them is a five-minute fix once you know to look for it.
- Enabling GuardDuty in one region only. Detection is strictly regional. An account with resources in three regions and GuardDuty enabled in one has zero visibility into the other two.
- Leaving the finding publishing frequency at the six-hour default. That's fine for a weekly review cadence, but useless if you're trying to route findings to Slack for near-real-time response.
- Turning on every protection plan without checking what's actually running. Enabling EKS Runtime Monitoring on an account with no EKS clusters costs nothing in false positives but does nothing useful either — audit what you actually run before enabling.
- Forgetting the 90-day native retention limit. Teams often discover this during an audit request for findings from eight months ago, by which point the data is gone unless it was exported to S3.
- Writing suppression rules too broadly. A filter meant to silence one internal scanner's IP, written instead as a wildcard on an entire CIDR block, can suppress a genuine attacker who happens to route through that same address space.
Troubleshooting Common GuardDuty Issues
Working through the same set of issues repeatedly across account setups, these are the ones worth having a fix ready for before they show up mid-incident. Bookmark this list — half of these only surface weeks after the initial setup, once real traffic and real findings start flowing.
- No findings appear after enabling GuardDuty. This is expected initially — GuardDuty needs a baseline period to establish normal behavior before it can flag anomalies. Use
create-sample-findingsto confirm the pipeline works while waiting for organic findings. - Findings aren't reaching Slack. Check the EventBridge rule's event pattern first; a mismatched
detail-typestring is the most common cause. Confirm withaws events test-event-patternagainst a sample finding payload. - Malware Protection scans never trigger. Malware Protection only scans in response to a qualifying finding on that resource — it's not a continuously running scanner. If you need proactive scanning, that's a different tool entirely, such as an EDR agent.
- Delegated admin setup fails with a permissions error. The account attempting
enable-organization-admin-accountmust be the AWS Organizations management account itself, not just an account with admin IAM permissions. - Member accounts aren't auto-enrolling. Confirm
auto-enable-organization-membersis set toALLand notNEW, which only applies to accounts that join after the setting was configured. - GuardDuty bill spikes unexpectedly. Check CloudWatch metrics for a sudden VPC Flow Log volume increase — a new high-traffic service or a misconfigured logging setup duplicating flow logs are the usual culprits.
- Suppression rule isn't archiving matching findings. Filter criteria are case-sensitive and must match the exact JSON path in the finding schema; a typo in the criterion key silently matches nothing rather than erroring.
- Extended Threat Detection findings seem sparse. Coverage depth depends directly on which protection plans are active. An account running only foundational detection will rarely see attack-sequence correlations, since there isn't enough telemetry to correlate against.
Advanced Tips for Production GuardDuty Deployments
Once the base setup is stable, a few refinements separate a functional GuardDuty deployment from one a SOC team actually trusts.
Tag findings by business unit or application using resource tags on the underlying EC2 instances and Lambda functions — GuardDuty findings inherit those tags, which makes routing to the right team's Slack channel trivial once you're past a single-team setup. Set up a weekly finding digest separate from the real-time high-severity alerts, since medium- and low-severity findings still carry signal worth a human glance even if they don't warrant a page. Pair GuardDuty's IAM-focused findings with IAM Access Analyzer for a fuller picture of identity risk, since GuardDuty flags anomalous IAM activity but doesn't audit permission scope the way Access Analyzer does. Finally, if your organization runs a dedicated SIEM such as Wazuh, Elastic, or Graylog, forward GuardDuty findings there via the S3 export pipeline from Step 9 rather than relying on Security Hub alone — a dedicated SIEM gives you longer retention windows and cross-correlation with non-AWS log sources.
Run a tabletop exercise once the pipeline is live rather than waiting for a real incident to test it. Pick one attack-sequence scenario — say, a compromised Lambda function exfiltrating data to an external endpoint — and walk through it using sample findings: confirm the Slack alert fires with the right severity framing, confirm the auto-quarantine Lambda from Step 10 correctly identifies the affected resource, and time how long it takes a human to acknowledge and act on the alert. Teams that skip this step often discover during a real incident that their EventBridge rule was matching on the wrong field, or that the Slack webhook token had quietly expired weeks earlier. A 30-minute tabletop run catches both before they matter.
Complete Working Example: End-to-End Detector Setup Script
Putting the full pipeline together, here's a single script that enables GuardDuty with the core protection plans, sets up S3 export, and creates the high-severity EventBridge rule from earlier steps. Run it after substituting your own bucket name, KMS key ARN, and account ID.
#!/bin/bash
set -euo pipefail
REGION="us-east-1"
BUCKET="your-security-bucket"
KMS_KEY_ARN="arn:aws:kms:us-east-1:111122223333:key/your-kms-key-id"
echo "Creating detector..."
DETECTOR_ID=$(aws guardduty create-detector \
--enable \
--finding-publishing-frequency FIFTEEN_MINUTES \
--region "$REGION" \
--query 'DetectorId' --output text)
echo "Detector ID: $DETECTOR_ID"
echo "Enabling protection plans..."
aws guardduty update-detector \
--detector-id "$DETECTOR_ID" \
--features Name=S3_DATA_EVENTS,Status=ENABLED \
Name=EKS_AUDIT_LOGS,Status=ENABLED \
Name=LAMBDA_NETWORK_LOGS,Status=ENABLED \
--region "$REGION"
echo "Configuring S3 export..."
aws guardduty create-publishing-destination \
--detector-id "$DETECTOR_ID" \
--destination-type S3 \
--destination-properties "{\"DestinationArn\":\"arn:aws:s3:::$BUCKET/guardduty-findings\",\"KmsKeyArn\":\"$KMS_KEY_ARN\"}" \
--region "$REGION"
echo "Creating EventBridge rule..."
aws events put-rule \
--name guardduty-high-severity \
--event-pattern '{"source":["aws.guardduty"],"detail-type":["GuardDuty Finding"],"detail":{"severity":[{"numeric":[">=",7]}]}}' \
--region "$REGION"
echo "Generating sample findings for validation..."
aws guardduty create-sample-findings --detector-id "$DETECTOR_ID" --region "$REGION"
echo "Setup complete. Detector $DETECTOR_ID is active in $REGION."
Expected output after running this script looks like:
Creating detector...
Detector ID: a1b2c3d4e5f6g7h8i9j0
Enabling protection plans...
Configuring S3 export...
Creating EventBridge rule...
Generating sample findings for validation...
Setup complete. Detector a1b2c3d4e5f6g7h8i9j0 is active in us-east-1.
Check the AWS console GuardDuty findings page a few minutes later, and the sample findings should already be populated, confirming the detector, protection plans, S3 export, and EventBridge routing are all functioning together.
GuardDuty Setup Checklist for Multi-Account Environments
| Task | Owner | Frequency |
|---|---|---|
| Enable GuardDuty in every active region | Platform/security team | Once per region, per account |
| Designate delegated administrator account | Organizations admin | Once |
| Set auto-enable for new member accounts | Security team | Once, then review quarterly |
| Review and prune suppression rules | Security team | Quarterly |
| Validate S3 export pipeline is receiving data | Security/platform team | Monthly |
| Audit protection plan coverage vs. active workloads | Security team | Quarterly |
| Test EventBridge-to-Slack notification path | On-call/security team | Monthly, via sample findings |
Frequently Asked Questions
Does GuardDuty require installing an agent on my EC2 instances?
No. GuardDuty is fully managed and analyzes existing data sources — VPC Flow Logs, CloudTrail events, DNS query logs — without any agent installation. Malware Protection's EBS volume scanning is also agentless, triggered on-demand when a qualifying finding occurs.
How much does GuardDuty cost for a small AWS account?
For a modest account generating under 50 GB of VPC Flow and DNS log data monthly, foundational detection typically runs in the tens of dollars per month at the $1.00/GB first-tier rate, plus CloudTrail event analysis at $4.00 per million events. The 30-day free trial on first activation lets you see your actual usage pattern before committing.
What's the difference between GuardDuty and Extended Threat Detection?
Extended Threat Detection isn't a separate product — it's a capability built into GuardDuty that correlates multiple individual findings into a single higher-confidence "attack sequence" finding when it detects a multi-stage pattern. It's automatically enabled for every GuardDuty account at no additional cost.
Can I use GuardDuty across multiple AWS regions from one dashboard?
GuardDuty detectors are regional, so there's no single native cross-region dashboard. The standard workaround is exporting findings from every region to a centralized S3 bucket or forwarding them into Security Hub, which does support cross-region aggregation.
How long does GuardDuty retain findings by default?
90 days. Anything you need to retain longer for compliance or post-incident review needs to be exported to S3 or another data store using the publishing destination configuration covered in this guide.
Does enabling every GuardDuty protection plan slow down my applications?
No. GuardDuty analyzes logs and metadata out-of-band rather than intercepting live traffic, so there's no in-line latency impact on application requests. Malware Protection's EBS scanning does briefly attach a snapshot for analysis, but it operates on a copy, not the live volume.
Is GuardDuty a replacement for a SIEM?
No. GuardDuty is a detection source, not a full security information and event management platform. It's common to feed GuardDuty findings into a dedicated SIEM for longer retention, correlation with non-AWS sources, and custom detection rules beyond what GuardDuty's built-in finding types cover.
What happens if I disable GuardDuty after the free trial?
Disabling the detector stops billing and stops new finding generation immediately. Existing findings remain accessible for the remainder of their 90-day retention window unless the detector is fully deleted, which also removes historical finding data from the console.





