Security Assessment & Threat Detection
Automatically detect threats, scan workloads for vulnerabilities, and discover sensitive data across your AWS environment with GuardDuty, Inspector, and Macie.
Introduction
Encrypting data and rotating credentials (covered in Lesson 22) protects secrets at rest, but what about active attacks and sensitive data that should not exist in certain places? Amazon GuardDuty is an always-on threat detection service that uses machine learning to analyze CloudTrail API logs, VPC Flow Logs, and DNS queries for signs of compromise: cryptomining, credential theft, reconnaissance, and more. Amazon Inspector complements it by continuously scanning your EC2 instances, container images, and Lambda functions for known CVEs and unintended network exposure. Amazon Macie rounds out the picture by automatically discovering and classifying sensitive data (PII, credentials, financial records) stored in S3, alerting you when buckets are misconfigured or contain data they should not. Together the three services give you reactive threat detection, proactive vulnerability management, and continuous data security posture management.
Quick Navigation
1. Amazon GuardDuty
Threat detection, findings, EventBridge alerts
2. Amazon Inspector
CVE scanning for EC2, ECR, and Lambda
3. Amazon Macie
Sensitive data discovery and S3 security posture
4. Amazon Detective
Behavior graph, entity profiles, finding groups
5. Service Comparison
When to use each, how they complement each other
1. Amazon GuardDuty
GuardDuty is a regional, agentless threat detection service that continuously analyzes data sources already being produced by your AWS account. You enable it with a single API call and it starts producing security findings within minutes. There is nothing to install, no log pipelines to configure, and it does not sit in the data path so it cannot affect latency or availability.
Purpose
GuardDuty answers one question: is something malicious or anomalous happening in my AWS account right now? It detects active threats such as IAM credential exfiltration, EC2 instances communicating with known command-and-control servers, S3 buckets being enumerated by an outsider, and cryptomining workloads introduced via a compromised container.
Data Sources
GuardDuty ingests several foundational data sources automatically. You do not enable these yourself, GuardDuty subscribes to them on your behalf and analyzes them with ML models and threat intelligence feeds.
CloudTrail Events
Management events (API calls) and S3/Lambda data events. GuardDuty detects unusual API call patterns, console logins from unexpected locations, and disabled CloudTrail trails.
VPC Flow Logs
Network traffic metadata for all ENIs. GuardDuty correlates traffic patterns against known threat intelligence IPs, detects port scanning, and identifies unexpected outbound connections.
DNS Logs
DNS query logs from within your VPC (via the AWS resolver). GuardDuty detects DNS tunneling, queries to known C2 domains, and exfiltration via DNS.
EKS / ECS / Lambda Runtime Monitoring
Optional protection plans for container workloads and Lambda. Detects container escapes, privilege escalation inside pods, and suspicious process behavior in Lambda functions.
GuardDuty Data Sources and Alert Pipeline
GuardDuty pulls from existing data sources, no agents or log pipelines required. Findings publish to EventBridge for notification or automated remediation.
Finding Types and Severity
Every GuardDuty finding has a type in the format ThreatPurpose:ResourceType/ThreatFamilyNameand a severity score from 1.0 to 10.0. Low (1-3.9), Medium (4-6.9), High (7-8.9), and Critical (9-10) map directly to how urgently you should investigate.
| Finding Type Example | What It Means | Severity |
|---|---|---|
UnauthorizedAccess:EC2/SSHBruteForce | An EC2 instance is being targeted by SSH brute-force attempts | Low-High (depends on success) |
CryptoCurrency:EC2/BitcoinTool.B!DNS | EC2 instance is querying domains associated with cryptocurrency mining pools | High |
Recon:EC2/PortProbeUnprotectedPort | A known scanner is probing an unprotected port on your EC2 instance | Medium-High |
UnauthorizedAccess:IAMUser/ConsoleLoginSuccess.B | Successful console login from a Tor network exit node | Medium |
Backdoor:EC2/C&CActivity.B!DNS | EC2 instance is communicating with a known command-and-control server | High |
Stealth:IAMUser/CloudTrailLoggingDisabled | CloudTrail logging was disabled - a common attacker cover-your-tracks action | Low |
Impact:S3/AnomalousBehavior.Write | Anomalous volume of S3 write operations detected from an IAM entity | High |
Enable GuardDuty
# Enable GuardDuty in the current region aws guardduty create-detector \ --enable \ --finding-publishing-frequency FIFTEEN_MINUTES # Confirm the detector is active aws guardduty list-detectors
Expected Output:
{
"DetectorId": "abc123def456abc123def456abc123de"
}
["abc123def456abc123def456abc123de"]List and Retrieve Findings
DETECTOR="abc123def456abc123def456abc123de"
# List all active findings for this detector
aws guardduty list-findings \
--detector-id "$DETECTOR" \
--finding-criteria '{"Criterion": {"service.archived": {"Eq": ["false"]}}}'
# Fetch the details of specific findings
aws guardduty get-findings \
--detector-id "$DETECTOR" \
--finding-ids "finding-id-1" "finding-id-2"Expected Output:
{
"FindingIds": [
"1ab12abc1ab12ab12ab1234567890abc",
"2bc23bcd2bc23bc23bc2345678901bcd"
]
}Query High-Severity Findings with boto3
import boto3
gd = boto3.client("guardduty", region_name="us-east-1")
detector_id = gd.list_detectors()["DetectorIds"][0]
# Fetch HIGH and CRITICAL severity findings (7.0 = High, 9.0 = Critical)
paginator = gd.get_paginator("list_findings")
pages = paginator.paginate(
DetectorId=detector_id,
FindingCriteria={
"Criterion": {
"severity": {"Gte": 7}, # >= 7.0 catches both High and Critical
"service.archived": {"Eq": ["false"]},
}
},
SortCriteria={"AttributeName": "severity", "OrderBy": "DESC"},
)
ids = [fid for page in pages for fid in page["FindingIds"]]
if ids:
findings = gd.get_findings(DetectorId=detector_id, FindingIds=ids[:10])
for f in findings["Findings"]:
print(f["Type"], "|", f["Severity"], "|", f["Region"])
else:
print("No high-severity findings")Expected Output:
UnauthorizedAccess:EC2/SSHBruteForce | 7.0 | us-east-1 Recon:EC2/PortProbeUnprotectedPort | 8.0 | us-east-1
Route Findings to SNS via EventBridge
GuardDuty publishes every finding to EventBridge automatically. Create a rule that matches high-severity findings and routes them to SNS for immediate email or Slack notification, or to a Lambda for automated remediation such as isolating a compromised EC2 instance.
# Create a rule that fires whenever GuardDuty produces a HIGH finding
aws events put-rule \
--name "GuardDuty-High-Findings" \
--event-pattern '{
"source": ["aws.guardduty"],
"detail-type": ["GuardDuty Finding"],
"detail": {
"severity": [{"numeric": [">=", 7]}]
}
}' \
--state ENABLED
# Attach an SNS topic as the target to receive email notifications
aws events put-targets \
--rule "GuardDuty-High-Findings" \
--targets '[{
"Id": "SnsTopic",
"Arn": "arn:aws:sns:us-east-1:123456789012:security-alerts"
}]'Suppression Rules
Suppression rules automatically archive findings that match specific criteria, reducing noise from expected activity. A common use case is suppressing SSH brute-force findings from known bastion host IP addresses in your on-premises range.
DETECTOR="abc123def456abc123def456abc123de"
# Create a suppression rule to silence low-severity SSH probes
# from known bastion host IP ranges
aws guardduty create-filter \
--detector-id "$DETECTOR" \
--name "SuppressKnownBastionSSH" \
--action ARCHIVE \
--finding-criteria '{
"Criterion": {
"type": {"Eq": ["UnauthorizedAccess:EC2/SSHBruteForce"]},
"service.action.networkConnectionAction.remoteIpDetails.ipAddressV4": {
"Eq": ["10.0.0.50", "10.0.0.51"]
}
}
}'Multi-account management: In an AWS Organization, designate one account as the GuardDuty delegated administrator. It sees findings from all member accounts in a single pane of glass and can enforce detector settings organization-wide without per-account configuration.
2. Amazon Inspector
Inspector v2 is a continuous vulnerability management service. Where GuardDuty detects what an attacker is doing, Inspector tells you what vulnerabilities exist that an attacker could exploit. It correlates the packages installed on your workloads against the National Vulnerability Database (NVD) and AWS threat intelligence, then prioritizes findings by reachability from the internet, not just CVSS score alone.
Purpose
Inspector answers: which workloads have known CVEs, and which of those CVEs are actually reachable from the internet? A CRITICAL CVE on an EC2 instance with no public route is lower priority than a HIGH CVE on a publicly exposed instance. Inspector's Inspector Score bakes network context into the prioritization so you patch the most exposed vulnerabilities first.
What Inspector Scans
EC2 Instances
- OS and application package CVEs
- Network reachability: open ports accessible from the internet
- Uses SSM Agent (no Inspector-specific agent required)
- Continuous scanning - re-scans when new CVEs are published
ECR Container Images
- OS packages and application dependencies
- Scans on push and continuously as new CVEs emerge
- Findings surface directly in the ECR console
- Block deployments via ECR pull-through policies if severity threshold is exceeded
Lambda Functions
- Application package dependencies (pip, npm)
- Static code vulnerability analysis (Lambda Standard scanning)
- Re-scans when a new function version is deployed
- Detects hard-coded secrets in function code
The Inspector Score
The Inspector Score (0-10) is not the raw CVSS score. Inspector adjusts the base CVSS score using contextual factors specific to your environment. A CVE on an EC2 instance with port 443 open to 0.0.0.0/0 and no security group restriction gets a higher score than the same CVE on an instance reachable only from inside a private subnet.
Score Adjustment Factors
- Network exposure - publicly reachable via security group or NACLs raises the score
- Exploitability - CVEs with known public exploits or active exploitation in the wild score higher
- Package context - whether the vulnerable package is actually installed in the execution path
- VPC topology - multi-hop reachability analysis across subnets, route tables, and peering connections
Inspector Continuous Scanning Pipeline
Inspector continuously correlates installed packages against CVE databases. Findings flow to EventBridge and Security Hub for alerting and centralized visibility.
Enable Inspector v2
# Enable Inspector v2 for EC2, ECR, and Lambda scanning aws inspector2 enable \ --resource-types EC2 ECR LAMBDA
Expected Output:
{
"accounts": [
{
"accountId": "123456789012",
"resourceStatus": {
"ec2": "ENABLING",
"ecr": "ENABLING",
"lambda": "ENABLING"
},
"status": "ENABLING"
}
],
"failedAccounts": []
}List Critical and High Findings
# List CRITICAL and HIGH findings across all resource types
aws inspector2 list-findings \
--filter-criteria '{
"severity": [
{"comparison": "EQUALS", "value": "CRITICAL"},
{"comparison": "EQUALS", "value": "HIGH"}
],
"findingStatus": [{"comparison": "EQUALS", "value": "ACTIVE"}]
}' \
--sort-criteria '{"field": "INSPECTOR_SCORE", "sortOrder": "DESC"}' \
--max-results 10Expected Output:
{
"findings": [
{
"findingArn": "arn:aws:inspector2:us-east-1:...",
"title": "CVE-2023-44487 - HTTP/2 Rapid Reset Attack",
"severity": "CRITICAL",
"inspectorScore": 9.8,
"resources": [{"type": "AWS_EC2_INSTANCE", "id": "i-0abc123..."}],
"packageVulnerabilityDetails": {
"cvss": [{"baseScore": 7.5, "scoringVector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"}],
"vulnerabilityId": "CVE-2023-44487"
},
"status": "ACTIVE"
}
]
}Aggregate Findings by Type with boto3
import boto3
ins = boto3.client("inspector2", region_name="us-east-1")
# Aggregate finding counts by resource type and severity
response = ins.list_finding_aggregations(
aggregationType="FINDING_TYPE",
aggregationRequest={
"findingTypeAggregation": {
"sortBy": "CRITICAL",
"sortOrder": "DESC",
}
},
)
for item in response["responses"]:
agg = item["findingTypeAggregation"]
print(
agg["findingType"],
"- Critical:", agg.get("severityCounts", {}).get("critical", 0),
"| High:", agg.get("severityCounts", {}).get("high", 0),
)Expected Output:
PACKAGE_VULNERABILITY - Critical: 4 | High: 17 NETWORK_REACHABILITY - Critical: 0 | High: 3 CODE_VULNERABILITY - Critical: 1 | High: 2
Enable Continuous ECR Scanning
Setting the registry scanning configuration to ENHANCED with CONTINUOUS_SCANmeans Inspector re-evaluates every image already in your repository whenever a new CVE is published, not just on push. This is essential for catching vulnerabilities disclosed after an image was built.
# Enable continuous scanning when an image is pushed to ECR
aws ecr put-registry-scanning-configuration \
--scan-type ENHANCED \
--rules '[{
"repositoryFilters": [{"filter": "*", "filterType": "WILDCARD"}],
"scanFrequency": "CONTINUOUS_SCAN"
}]'
# Check the current scan findings for a specific image
aws inspector2 list-findings \
--filter-criteria '{
"ecrImageRepositoryName": [{"comparison": "EQUALS", "value": "my-app"}],
"findingStatus": [{"comparison": "EQUALS", "value": "ACTIVE"}]
}'Inspector requires SSM Agent for EC2 scanning. Instances without SSM Agent installed and managed will show as UNMANAGED and produce network-reachability findings only, not package CVE findings. Ensure your EC2 instances have the SSM Agent running and an IAM instance profile with AmazonSSMManagedInstanceCore attached.
3. Amazon Macie
Macie is a data security service focused entirely on S3. It uses machine learning and pattern matching to automatically discover and classify sensitive data stored in your buckets: personally identifiable information (PII), financial data, credentials, and PHI. Beyond data classification, Macie continuously evaluates your S3 bucket policies and settings and raises Policy findings for misconfigurations such as publicly accessible buckets, disabled encryption, or objects shared with external AWS accounts.
Purpose
Macie answers: do my S3 buckets contain sensitive data they should not, and are they misconfigured in a way that exposes that data? A bucket that is encrypted and private is still a problem if it holds 50,000 social security numbers belonging to customers who never consented to that storage. Macie surfaces both the security misconfiguration and the data classification problem in a single service.
Finding Types
SensitiveData Findings
Raised when Macie detects sensitive content inside S3 objects during a classification job or automated discovery.
SensitiveData:S3Object/Credentials- AWS keys, passwords, private keysSensitiveData:S3Object/Financial- credit card numbers, bank account dataSensitiveData:S3Object/Personal- SSNs, passport numbers, driver licensesSensitiveData:S3Object/Multiple- two or more sensitive data categories in a single object
Policy Findings
Raised when a bucket's configuration violates security best practices, regardless of what data it contains.
Policy:IAMUser/S3BucketPubliclyAccessible- bucket allows public read/writePolicy:IAMUser/S3BucketEncryptionDisabled- default encryption not enabledPolicy:IAMUser/S3BucketSharedExternally- bucket policy grants access to an external accountPolicy:IAMUser/S3BlockPublicAccessDisabled- Block Public Access settings have been turned off
Automated Discovery vs Classification Jobs
Automated Sensitive Data Discovery
- Continuously samples objects across all S3 buckets in the account
- Builds an inventory of buckets and their data sensitivity over time
- Lower cost: samples a representative subset, not every object
- Enable with a single API call - no job scheduling required
Classification Jobs
- Targeted scans of specific buckets, prefixes, or object tags
- One-time or scheduled (daily, weekly, monthly)
- Inspects every matching object - required for compliance audits
- Supports custom data identifiers for proprietary data patterns
Macie Sensitive Data Discovery Pipeline
Macie scans S3 objects and bucket policies. Sensitive data and policy findings flow to EventBridge for alerting and Security Hub for centralized posture management.
When to Use Macie
- You store user data in S3 and need to verify it does not contain PII, credentials, or PHI that violates your data handling policies
- Compliance frameworks (GDPR, HIPAA, PCI-DSS) require you to demonstrate that sensitive data is discovered, classified, and protected
- You want continuous alerting if any S3 bucket in your account becomes public, loses its encryption, or is shared with an unexpected external account
- You run a data lake and need an audit trail showing which buckets hold sensitive data categories
Enable Macie
# Enable Macie in the current region aws macie2 enable-macie # Confirm the session is active and check coverage status aws macie2 get-macie-session
Expected Output:
{
"createdAt": "2026-06-10T10:00:00Z",
"findingPublishingFrequency": "FIFTEEN_MINUTES",
"serviceRole": "arn:aws:iam::123456789012:role/aws-service-role/macie.amazonaws.com/...",
"status": "ENABLED",
"updatedAt": "2026-06-10T10:00:00Z"
}Enable Automated Discovery and Run a Classification Job
# Enable automated sensitive data discovery - Macie continuously samples
# objects across all S3 buckets and classifies sensitive data types
aws macie2 update-automated-discovery-configuration \
--status ENABLED
# Run a targeted one-time job on specific buckets for a full deep scan
aws macie2 create-classification-job \
--job-type ONE_TIME \
--name "prod-data-lake-full-scan" \
--s3-job-definition '{
"bucketDefinitions": [
{
"accountId": "123456789012",
"buckets": ["prod-data-lake", "app-user-uploads", "analytics-export"]
}
]
}'Query Sensitive Data Findings with boto3
import boto3
macie = boto3.client("macie2", region_name="us-east-1")
# Fetch SensitiveData findings sorted by severity score
paginator = macie.get_paginator("list_findings")
pages = paginator.paginate(
FindingCriteria={
"criterion": {
"category": {"eq": ["SENSITIVE_DATA"]},
}
},
SortCriteria={"attributeName": "severity.score", "orderBy": "DESC"},
)
ids = [fid for page in pages for fid in page["findingIds"]]
if ids:
result = macie.get_findings(findingIds=ids[:10])
for f in result["findings"]:
category = (
f["sensitiveData"][0]["category"] if f.get("sensitiveData") else "n/a"
)
bucket = f["resourcesAffected"]["s3Bucket"]["name"]
print(f["title"], "|", category, "|", bucket)
else:
print("No sensitive data findings")Expected Output:
Sensitive data in S3 object | CREDENTIALS | prod-data-lake Sensitive data in S3 object | PERSONAL_INFORMATION | app-user-uploads Sensitive data in S3 object | FINANCIAL_INFORMATION | analytics-export
List Policy Findings (Bucket Misconfigurations)
# List Policy findings - bucket misconfigurations (public access, no encryption, external sharing)
aws macie2 list-findings \
--finding-criteria '{
"criterion": {
"category": {"eq": ["POLICY"]},
"severity.description": {"eq": ["High", "Critical"]}
}
}'
# Get details on a specific Policy finding
aws macie2 get-findings \
--finding-ids "a1b2c3d4-e5f6-7890-abcd-ef1234567890"Custom data identifiers let you extend Macie's built-in classifiers with your own regex patterns and keywords. Use them to detect proprietary data formats such as internal employee IDs, customer account numbers, or any structured value unique to your organization.
4. Amazon Detective
Detective is not a threat detection service, it is a threat investigation service. Where GuardDuty tells you that something suspicious happened, Detective helps you understand why it happened, what else the affected entity did, and how far the compromise has spread. It automatically ingests CloudTrail logs, VPC Flow Logs, and GuardDuty findings and uses machine learning to build a behavior graph: an interactive model of how every IAM principal, EC2 instance, S3 bucket, and IP address in your account relates and behaves over time.
Purpose
Detective answers: is this GuardDuty finding a true positive, what did this entity do before and after the alert, and which other resources were touched during the same campaign? It replaces the manual workflow of pivoting between Athena queries, the CloudTrail console, and VPC Flow Log searches with a single graph-based investigation interface backed by 12 months of automatically retained data.
How Detective Works
Behavior Graph
Detective continuously ingests CloudTrail management events, VPC Flow Logs, and GuardDuty findings - the same sources GuardDuty reads - and builds a graph model of entity relationships and activity baselines. No agents or log pipelines to configure.
Entity Profiles
Each EC2 instance, IAM user/role, S3 bucket, IP address, and AS number gets a profile showing its API call volume, network connections, and anomaly score over the past 12 months. A spike on the timeline pinpoints exactly when behavior changed.
Finding Groups
Detective correlates related GuardDuty findings into a single finding group that represents one attack campaign: initial access, lateral movement, and impact findings all linked on a shared timeline so you see the full kill chain rather than isolated alerts.
GuardDuty Deep Link
Every GuardDuty finding has an Investigate with Detective button that opens the affected entity's profile directly in the Detective console, pre-scoped to the finding's time window. Triage without leaving the alert.
Detective Investigation Pipeline
Detective auto-ingests the same sources as GuardDuty and builds a behavior graph. Entity profiles and finding groups surface from the graph without any manual log queries.
Enable Amazon Detective
# Enable Amazon Detective - creates a behavior graph in the current region aws detective create-graph # Confirm the behavior graph is active aws detective list-graphs
Expected Output:
{
"GraphArn": "arn:aws:detective:us-east-1:123456789012:graph:abc123def456abc123def456abc123de"
}
{
"GraphList": [
{
"Arn": "arn:aws:detective:us-east-1:123456789012:graph:abc123def456abc123def456abc123de",
"CreatedTime": "2026-06-10T10:00:00Z"
}
]
}Start an Investigation on an IAM Entity
When a GuardDuty finding names a specific IAM user or role, you can open a scoped investigation that evaluates that entity's behavior across the time window you specify. Detective scores the entity's activity against its baseline and surfaces the indicators most likely to confirm or refute the finding.
GRAPH="arn:aws:detective:us-east-1:123456789012:graph:abc123def456abc123def456abc123de" # Start an investigation on a specific IAM entity over a time window. # Use this after GuardDuty raises a finding against an IAM user or role. aws detective start-investigation \ --graph-arn "$GRAPH" \ --entity-arn "arn:aws:iam::123456789012:user/alice" \ --scope-start-time "2026-06-01T00:00:00Z" \ --scope-end-time "2026-06-10T23:59:59Z" # Poll for results once the investigation is complete (RUNNING -> SUCCESSFUL) aws detective get-investigation \ --graph-arn "$GRAPH" \ --investigation-id "invest-abc123"
List Finding Groups with boto3
import boto3
det = boto3.client("detective", region_name="us-east-1")
graph_arn = det.list_graphs()["GraphList"][0]["Arn"]
# List finding groups - correlated GuardDuty findings forming an attack campaign
response = det.list_finding_groups(
GraphArn=graph_arn,
Filter={
"CreatedTime": {
"StartInclusive": "2026-06-01T00:00:00Z",
"EndInclusive": "2026-06-10T23:59:59Z",
}
},
)
for fg in response.get("FindingGroups", []):
print(fg["Id"], "|", fg["Severity"], "|", fg["CreatedTime"])Expected Output:
fg-001a2b3c4d5e6f | HIGH | 2026-06-09T14:22:01Z fg-007f8e9d0c1b2a | MEDIUM | 2026-06-08T09:47:33Z
GuardDuty is a prerequisite. Detective requires GuardDuty to be enabled in the same account and region. It cannot be used as a standalone service; if GuardDuty is disabled, Detective stops receiving findings and your behavior graph becomes stale. In a multi-account Organization, designate the same account as both the GuardDuty and Detective delegated administrator so all findings flow into one behavior graph.
5. Service Comparison
GuardDuty, Inspector, and Macie solve different but complementary security problems. In production you should run all three: one detects active threats, one closes attack surface before exploitation, and one ensures sensitive data is classified and protected at rest.
| Dimension | Amazon GuardDuty | Amazon Inspector | Amazon Macie | Amazon Detective |
|---|---|---|---|---|
| Core question | Is an attack happening right now? | What vulnerabilities could be exploited? | Do my S3 buckets contain or expose sensitive data? | Why did this finding occur, and what else was affected? |
| Detection type | Reactive: threat detection from observed behavior | Proactive: vulnerability and exposure scanning | Proactive: data classification and bucket posture | Reactive: forensic investigation of findings and entity behavior |
| Data sources | CloudTrail logs, VPC Flow Logs, DNS queries, runtime events | Installed OS/app packages, ECR image layers, Lambda code | S3 object content, bucket policies, ACLs, encryption settings | CloudTrail, VPC Flow Logs, GuardDuty findings, EKS audit logs |
| Agent required | No agent for CloudTrail/VPC/DNS; optional runtime agent for EKS/ECS | SSM Agent for EC2 package scanning (no Inspector-specific agent) | No agent - Macie accesses S3 directly via service role | No agent - ingests the same sources as GuardDuty automatically |
| Finding trigger | Malicious/anomalous API call, network connection, DNS query | New CVE published, new image pushed, new function deployed | Sensitive data found in object, bucket policy misconfiguration | Initiated by analyst from a GuardDuty finding or entity search |
| Pricing | Per million CloudTrail events + per GB of Flow Logs/DNS analyzed | Per EC2 instance/month + per container image scan + per Lambda scan | Per GB scanned for classification + per bucket/month for policy assessment | Per GB of data ingested into the behavior graph |
| Free trial | 30 days, full functionality | 30 days, full functionality | 30 days, full functionality | 30 days, full functionality |
| Integrates with | EventBridge, Security Hub, Detective, Organizations | EventBridge, Security Hub, ECR, Organizations | EventBridge, Security Hub, Organizations | GuardDuty (deep link), Security Hub, Organizations |
Enable GuardDuty when...
- You want always-on threat detection with zero configuration
- You need to detect compromised IAM credentials being used in the wild
- You want to catch cryptomining, C2 callbacks, or data exfiltration in progress
- You need a compliance control for anomaly-based detection (PCI-DSS, SOC 2)
Enable Inspector when...
- You want to know which EC2 instances or containers have unpatched CVEs
- You run a container delivery pipeline and need CVE scanning before images reach production
- Compliance requires a software composition analysis (SCA) tool
- You want to identify publicly exposed ports before an attacker does
Enable Macie when...
- You store user data in S3 and need to verify it does not contain PII or credentials
- Compliance (GDPR, HIPAA, PCI-DSS) requires sensitive data discovery and classification
- You want immediate alerting if any bucket becomes public or loses its encryption
- You run a data lake and need an ongoing audit of which buckets hold sensitive data
Enable Detective when...
- GuardDuty is firing and you need to distinguish true positives from false positives quickly
- You want a timeline of what an IAM user or EC2 instance did before and after a suspicious event
- Post-incident forensics require correlating events across CloudTrail and VPC Flow Logs without raw log queries
- Your security team is pivoting between multiple consoles to investigate a single GuardDuty finding
6. Security Hub
Bringing It Together with Security Hub
AWS Security Hub aggregates findings from GuardDuty, Inspector, Macie, IAM Access Analyzer, and third-party tools into a single normalized view using the AWS Security Finding Format (ASFF). Enabling Security Hub gives you a unified security posture dashboard without having to correlate findings across multiple service consoles. It also runs automated checks against the AWS Foundational Security Best Practices standard and CIS Benchmarks. If you only enable two security services today, make them GuardDuty and Security Hub; Inspector, Detective, and Macie integrate automatically once Security Hub is active.
Key Takeaways
- GuardDuty is agentless and always-on - enable it with one API call and it immediately starts analyzing CloudTrail, VPC Flow Logs, and DNS queries using ML models and AWS threat intelligence feeds.
- Findings go to EventBridge - build automated responses by routing high-severity findings to SNS for alerts or Lambda for remediation. You should have this pipeline in place before you need it.
- Use suppression rules to reduce noise - archive expected findings from known IPs or services so your security team focuses on genuine threats, not known-good activity.
- Inspector scores by reachability, not just CVSS - a CVE on a publicly exposed instance is prioritized higher than the same CVE on an internal-only instance. Patch by Inspector Score, not raw CVSS.
- Enable continuous ECR scanning - container images can become vulnerable after they are built. Continuous scanning re-evaluates images whenever a new CVE is published, not just on push.
- SSM Agent unlocks full EC2 scanning - without it, Inspector can only analyze network reachability. Attach
AmazonSSMManagedInstanceCoreto your EC2 instance profiles to enable package CVE scanning. - Macie closes the data visibility gap - GuardDuty and Inspector protect your infrastructure; Macie protects your data. Enable automated sensitive data discovery to maintain a continuous inventory of which S3 buckets hold PII, credentials, or financial records, and get immediate Policy findings when a bucket is misconfigured.
- GuardDuty detects, Detective investigates, Inspector prevents, Macie classifies - run all four. Security Hub ties their findings together into one normalized view so your security team works from a single pane of glass rather than four separate consoles.
- Detective requires no configuration beyond enabling it - it connects to GuardDuty automatically and starts building a behavior graph from CloudTrail and VPC Flow Logs immediately. The "Investigate with Detective" button on any GuardDuty finding opens the affected entity's profile pre-scoped to the finding's time window.
- Use Detective to triage before escalating - entity profiles show 12 months of baseline activity, so you can see whether an anomalous API call is a one-off or part of a pattern. Triage a GuardDuty finding in minutes instead of querying Athena and CloudTrail manually.