Turning GuardDuty from noise into a rota someone answers
GuardDuty is enabled in most accounts and read in almost none. The fix is not more tuning, it is deciding in advance which five findings wake a human and what they do next.
GuardDuty has a specific failure mode. It is cheap and easy to enable, so it gets enabled. It then produces findings at a rate nobody budgeted attention for, most of them low severity, and within two months the console is a wall of Recon:EC2/PortProbeUnprotectedPort that everyone has learned to scroll past. The detection works perfectly. The response does not exist.
Fixing this is an operations design problem, not a tuning problem.
Decide the response before you route anything
Write down, for each finding type you care about, what a human does when it fires. If the answer is "look at it and probably close it", it does not get to page anyone. Our default split for a mid-size estate:
Page immediately, day or night:
UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration— instance role credentials used from outside AWS. This one is almost never a false positive and it means an instance is compromised.CryptoCurrency:EC2/BitcoinTool.B!DNS— usually the first visible symptom of a compromised workload.Policy:IAMUser/RootCredentialUsagein any account where root is not supposed to be used, which should be all of them.UnauthorizedAccess:IAMUser/AnomalousBehaviorat high severity, when the principal can write to IAM.- Any GuardDuty Malware Protection finding on a production instance.
Ticket, next business day: medium-severity S3 and EKS findings, anomalous API calls from principals with read-only scope, RDS login anomalies.
Archive with a suppression rule, permanently: port probes against instances you deliberately expose, the scanner traffic from your own pentest vendor, findings from a known VPN egress IP. Suppression rules are the tool here, not closing findings by hand — a suppressed finding stays archived when it recurs, a manually closed one comes straight back.
Route it once, centrally
Enable GuardDuty for the whole organisation with the security account as delegated administrator, so new accounts are covered on creation and nobody has to remember. Then a single EventBridge rule per severity band in that account, sending high severity to your on-call tool and everything else to a queue that creates tickets.
Do not route to email. Email is where findings go to be ignored.
Send the findings to Security Hub as well, because Security Hub is where GuardDuty, Inspector, Macie and your Config rules land in one normalised format, and it is what an auditor will ask to see. One caution: Security Hub with all standards enabled produces thousands of findings on day one. Enable the Foundational Security Best Practices standard first, work the failures down, and only then add CIS or PCI.
The part everyone skips: containment
A detection you cannot act on is a report, not a control. Write and test three runbooks before you need them.
- Compromised instance. Snapshot the volume, replace the security group with a deny-all quarantine group, revoke the instance profile's active sessions with an IAM policy that denies by
aws:TokenIssueTime, then terminate. Keep the snapshot. - Compromised IAM principal. Attach an explicit deny-all, rotate credentials, and read the last 24 hours of CloudTrail for that principal before anything else.
- Exposed S3 bucket. Block public access at account level first, then fix the bucket policy. Order matters under time pressure.
Each of these is a documented page with copy-pasteable commands, tested once a quarter in a game day. Ours are part of the security service; most of what they close would also have been caught earlier by posture scanning.
What this costs
GuardDuty pricing scales with CloudTrail events, VPC flow logs and DNS query volume. In accounts with chatty S3 workloads, enable S3 protection deliberately and watch the first month's bill. It is worth it, but it is not free, and the surprise is avoidable.
What to do this week
Open GuardDuty in your busiest production account and sort findings by type. Take the top five by count and write a suppression rule or a runbook for each. If you can do neither for a given type, you have learned that it should not be generating findings at all.