# Security finding → triage → runbook decision tree

Maps an incoming detection signal to a triage decision and the containment
runbook to open. Built around **GuardDuty Extended Threat Detection** (which
emits a single `critical`-severity *attack sequence* finding by correlating
multiple signals) and **AWS Security Incident Response** (which auto-triages
findings from GuardDuty + Security Hub and filters the high-volume noise).

> Verify the current finding types and severity model on the AWS GuardDuty and
> AWS Security Incident Response docs before you wire automation against them —
> finding names change as coverage expands.

---

## Step 0 — Where does the signal come from?

| Source | Example | Default route |
|--------|---------|---------------|
| GuardDuty **attack sequence** (`critical`) | `AttackSequence:EC2/CompromisedInstanceGroup`, `AttackSequence:ECS/CompromisedCluster`, IAM/S3/EKS sequences | **Page on-call. Open SEV-2 case.** |
| GuardDuty single finding (`high`) | `UnauthorizedAccess:EC2/SSHBruteForce`, `CryptoCurrency:EC2/BitcoinTool.B` | Auto-triage → enrich → human review within SLA |
| GuardDuty (`medium`/`low`) | recon, port probes | Aggregate; review in business hours |
| Security Hub control failure | `S3.8 block public access` | Config drift backlog, not an incident |
| AWS Security IR case escalation | SIR engineer escalated | Treat as confirmed; jump to containment |

The point of the tree: **only the `critical` attack-sequence path pages a
human at 03:00.** Everything else is triaged or batched.

---

## Step 1 — Is it a correlated attack sequence?

```
critical attack-sequence finding?
├── yes → CONFIRMED-INTENT path
│         • Open SEV-2 (or SEV-1 if data-plane / customer data in scope)
│         • Read the GuardDuty incident summary + MITRE ATT&CK mapping
│         • Pick the matching containment runbook (below)
│         • Notify Communications IC
└── no  → SINGLE-SIGNAL path
          • Let SIR auto-triage / suppression rules score it
          • If SIR escalates a case → treat as CONFIRMED-INTENT
          • Else enrich (Detective / CloudTrail) and review within SLA
```

## Step 2 — What is the blast-radius boundary?

| Finding scope | Containment boundary | Runbook |
|---------------|----------------------|---------|
| EC2 instance group | instance(s) + their IAM role + SG | `containment-runbook-ec2-credential-compromise.md` |
| ECS / EKS cluster | task/pod + task role + cluster | adapt the EC2 runbook to the task role |
| IAM principal / keys | the principal + everything it can assume | rotate keys, attach deny-all, review CloudTrail |
| S3 data exfiltration | bucket(s) + the principal reading them | block public access, scope bucket policy, snapshot logs |

## Step 3 — Severity → response clock

| Severity | Trigger | Ack | Containment target |
|----------|---------|-----|--------------------|
| SEV-1 | Confirmed data exfiltration / customer data | 5 min | 30 min |
| SEV-2 | Critical attack sequence, no confirmed exfil | 15 min | 60 min |
| SEV-3 | High single finding, plausible FP | 1 business hour | same day |
| SEV-4 | Medium/low, recon | next business day | backlog |

> These are **example** targets. Set yours against a measured baseline, then
> track ack-time and containment-time as your two IR KPIs — they are what a
> retrospective should move.

---

## Anti-patterns this tree exists to kill

- **Paging on every `high` finding.** You train the team to ignore the pager.
  Reserve paging for the correlated `critical` sequence.
- **Treating a Security Hub control failure as an incident.** It is config
  drift. Route it to the hardening backlog, not the on-call.
- **Manual triage of medium/low findings.** Let SIR suppression rules and
  auto-triage absorb them; humans only see what survives the filter.
