Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Hunt for threats in AWS environments using Detective behavior graphs, entity investigation timelines, GuardDuty finding correlation, and automated entity profiling across IAM users, EC2 instances, and IP addresses.
.claude/skills/performing-cloud-native-threat-hunting-with-aws-detective/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | — | — |
| case-11 | ✗→✓ | ▲ Improved | — | — |
| case-04 | ✗→✓ | ▲ Improved | — | — |
| case-10 | ✗→✓ | ▲ Improved | — | — |
| case-13 | ✓→✓ | = Same ✓ | — | — |
AWS Detective automatically collects and analyzes log data from AWS CloudTrail, VPC Flow Logs, GuardDuty findings, and EKS audit logs to build interactive behavior graphs. These graphs enable security analysts to investigate entities (IAM users, roles, IP addresses, EC2 instances) across time, identify anomalous API calls, detect lateral movement between accounts, and correlate GuardDuty findings into coherent attack narratives — all without manual log parsing.
detective:*, guardduty:List*)AmazonDetectiveFullAccess or custom policy with detective:SearchGraph, detective:GetInvestigation, detective:ListIndicators| Concept | Description | |---------|-------------| | Behavior Graph | Data structure linking CloudTrail, VPC Flow, GuardDuty, and EKS logs for an account/region | | Entity | Investigable object: IAM user, IAM role, EC2 instance, IP address, S3 bucket, EKS cluster | | Finding Group | Correlated set of GuardDuty findings linked to the same attack campaign | | Entity Profile | Timeline of API calls, network connections, and resource access for a specific entity | | Scope Time | Investigation window (default 24h, max 1 year) for behavioral analysis |
bashaws detective list-graphs --output table
bash# Get entity profile for an IAM user aws detective get-investigation \ --graph-arn arn:aws:detective:us-east-1:123456789012:graph:a1b2c3d4 \ --investigation-id 000000000000000000001
python#!/usr/bin/env python3 """Search AWS Detective for suspicious entities.""" import boto3 import json from datetime import datetime, timedelta detective = boto3.client('detective') def list_behavior_graphs(): """List all Detective behavior graphs.""" response = detective.list_graphs() return response.get('GraphList', []) def get_investigation_indicators(graph_arn, investigation_id, max_results=50): """Get indicators for a specific investigation.""" response = detective.list_indicators( GraphArn=graph_arn, InvestigationId=investigation_id, MaxResults=max_results ) return response.get('Indicators', []) def investigate_guardduty_findings(graph_arn): """List high-severity investigations correlated by Detective.""" response = detective.list_investigations( GraphArn=graph_arn, FilterCriteria={ 'Severity': {'Value': 'CRITICAL'}, 'Status': {'Value': 'RUNNING'} }, MaxResults=20 ) for investigation in response.get('InvestigationDetails', []): print(f"Investigation: {investigation['InvestigationId']}") print(f" Entity: {investigation['EntityArn']}") print(f" Status: {investigation['Status']}") print(f" Severity: {investigation['Severity']}") print(f" Created: {investigation['CreatedTime']}") print() if __name__ == "__main__": graphs = list_behavior_graphs() for graph in graphs: print(f"Graph: {graph['Arn']}") investigate_guardduty_findings(graph['Arn'])
bash# List investigations with high severity aws detective list-investigations \ --graph-arn arn:aws:detective:us-east-1:123456789012:graph:a1b2c3d4 \ --filter-criteria '{"Severity":{"Value":"HIGH"}}' \ --max-results 10
bash# Get indicators for a specific investigation aws detective list-indicators \ --graph-arn arn:aws:detective:us-east-1:123456789012:graph:a1b2c3d4 \ --investigation-id 000000000000000000001 \ --max-results 50
The list-investigations command returns investigation metadata:
json{ "InvestigationDetails": [ { "InvestigationId": "000000000000000000001", "Severity": "CRITICAL", "Status": "RUNNING", "State": "ACTIVE", "EntityArn": "arn:aws:iam::123456789012:user/suspicious-user", "EntityType": "IAM_USER", "CreatedTime": "2026-03-15T14:30:00Z" } ] }
Indicators are retrieved separately via list-indicators and include types such as TTP_OBSERVED, IMPOSSIBLE_TRAVEL, FLAGGED_IP_ADDRESS, NEW_GEOLOCATION, NEW_ASO, NEW_USER_AGENT, RELATED_FINDING, and RELATED_FINDING_GROUP.
aws detective list-graphs returns non-empty list| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-22 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-20 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-14 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-18 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-06 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-02 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-09 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-08 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-13 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-01 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-17 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-19 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-12 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-11 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-21 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-16 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-15 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-05 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-03 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-04 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-07 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-10 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +18 percentage points is the difference between those two pass rates over the 22 comparable cases.
The per-case answers from this run were removed by the retention sweep, so the case table below shows the verdicts without the text either arm produced. The counts above were recorded at the time and are unaffected. Answers are now kept for 180 days.
Other measured skills in the registry, with their headline benchmark lift.