Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 43 additions & 2 deletions skills/secops/alert-triage/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ phase: [operate, respond]
frameworks: [MITRE-ATT&CK-v16, NIST-SP-800-61-Rev2]
difficulty: beginner
time_estimate: "10-20min per alert"
version: "1.0.0"
version: "1.0.1"
author: unitoneai
license: MIT
allowed-tools: Read, Grep, Glob
Expand Down Expand Up @@ -104,6 +104,32 @@ Connect the alert data with surrounding context to build a picture of what happe
| Lateral Movement (TA0008) | Collection (TA0009), Exfiltration (TA0010) -- what was the objective? |
| Command and Control (TA0011) | All tactics -- C2 implies an active intrusion; look for the full chain |

### Phase 2A: Enrichment Freshness and Provenance

Before enrichment lowers priority, supports BTP/FP closure, or drives escalation, validate that the source is current, attributable, and applicable to the alert timestamp. Missing enrichment is not automatically malicious; mark the field `Not Evaluable`, lower confidence, and continue investigation when other evidence is insufficient.

**Required enrichment gates:**

| Gate | Required evidence | False positive prevented |
|---|---|---|
| `TRIAGE-ENRICH-01` | Asset criticality, environment, owner, exposure, and sync/observation time from CMDB, EDR, or cloud inventory. | Stale CMDB labels lower priority for a production crown-jewel asset. |
| `TRIAGE-ENRICH-02` | User role, privilege, account status, employment status, group membership, and directory/HR/IAM sync time. | Current user state is used as proof of alert-time user state after changes. |
| `TRIAGE-ENRICH-03` | Threat-intel source, lookup time, first/last seen, confidence, expiration, feed health, and alert-time applicability. | Copied IOC reputation from an old case closes a live alert as FP. |
| `TRIAGE-ENRICH-04` | GeoIP, ASN, VPN, scanner, CDN, and cloud-provider tags include provider, lookup time, confidence, and corroborating ownership/activity context. | Provider tags become the sole BTP/FP reason. |
| `TRIAGE-ENRICH-05` | Historical disposition is checked against current rule version, tuning status, asset, user, environment, and related-alert context. | Prior BTP/FP is reused after rule or environment drift. |
| `TRIAGE-ENRICH-06` | Enrichment timestamps are compared to the alert timestamp and to containment/remediation timestamps. | Post-containment asset or user state is treated as alert-time state. |
| `TRIAGE-ENRICH-07` | Analyst overrides include override timestamp, analyst/source, source document, and reason. | Manual enrichment edits influence disposition without provenance. |
| `TRIAGE-ENRICH-08` | Correlated incidents use the oldest or maximum-age enrichment across contributing alerts, not only the current alert's enrichment. | Fresh context on one alert hides stale enrichment that triggered the correlation. |

**Finding guidance:**

| Condition | Result |
|---|---|
| Priority is lowered using stale or timestamp-less asset/user enrichment | Finding; High when production or privileged scope is affected |
| BTP/FP closure relies only on provider, scanner, VPN, CDN, GeoIP, ASN, or old case tags | Finding; require corroborating owner/change/activity evidence |
| Enrichment is missing or cannot be evaluated | Not Evaluable; lower confidence rather than auto-escalating or closing |
| Source, lookup/sync time, confidence, and alert-time applicability are documented | May support priority, escalation, or BTP/FP decision |

### Phase 3: Classify

Assign a disposition and priority based on collected and correlated data.
Expand Down Expand Up @@ -194,7 +220,7 @@ Produce the triage decision as a structured report:
```markdown
## Alert Triage Report
**Date:** [YYYY-MM-DD HH:MM UTC]
**Skill:** alert-triage v1.0.0
**Skill:** alert-triage v1.0.1
**Frameworks:** MITRE ATT&CK v16, NIST SP 800-61 Rev 2
**Analyst:** [Name or AI-assisted]

Expand Down Expand Up @@ -234,6 +260,17 @@ Produce the triage decision as a structured report:
- **Threat Intel:** [IOC match results]
- **Kill Chain Position:** [Where this falls in the attack lifecycle]

### Enrichment Provenance
| Enrichment | Source | Lookup / Sync Time | Applies to Alert Time? | Confidence | Impact on Decision |
|------------|--------|--------------------|------------------------|------------|--------------------|
| Asset criticality/exposure | [CMDB/EDR/cloud inventory] | [timestamp] | [Yes/No/Not Evaluable] | [High/Medium/Low] | [priority/disposition impact] |
| User context | [Directory/HR/IAM] | [timestamp] | [Yes/No/Not Evaluable] | [High/Medium/Low] | [priority/disposition impact] |
| Threat intel | [feed/platform] | [timestamp] | [Yes/No/Not Evaluable] | [High/Medium/Low] | [priority/disposition impact] |
| GeoIP/ASN/provider reputation | [provider/feed] | [timestamp] | [Yes/No/Not Evaluable] | [High/Medium/Low] | [priority/disposition impact] |
| Historical disposition | [case/ticket/rule version] | [timestamp] | [Yes/No/Not Evaluable] | [High/Medium/Low] | [priority/disposition impact] |
| Analyst override | [analyst/source document] | [timestamp] | [Yes/No/Not Evaluable] | [High/Medium/Low] | [priority/disposition impact] |
| Correlated alert enrichment age | [correlation rule/case] | [oldest contributing timestamp] | [Yes/No/Not Evaluable] | [High/Medium/Low] | [priority/disposition impact] |

### Recommended Actions
- [ ] [Action 1 -- e.g., isolate host, disable account, block IP]
- [ ] [Action 2 -- e.g., collect forensic artifacts, memory dump]
Expand Down Expand Up @@ -319,6 +356,10 @@ Investigating an alert in isolation without checking for activity before and aft

Waiting for complete certainty before escalating a high-priority alert costs response time. NIST SP 800-61 recommends erring on the side of over-notification. If 20 minutes of investigation has not resolved the disposition and the alert involves a critical asset or privileged account, escalate to Tier 2 or the IR team with your current findings and continue investigation in parallel.

### Pitfall 6: Trusting Enrichment Without Freshness or Provenance

Asset criticality, user privilege, threat-intel reputation, GeoIP/provider tags, analyst overrides, and historical dispositions can drift quickly. Record source, lookup or sync time, confidence, and alert-time applicability before using enrichment to lower priority, close as BTP/FP, or suppress escalation.

---

## 8. Prompt Injection Safety Notice
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
{
"case": "benign_current_or_not_evaluable_enrichment_handled",
"skill": "alert-triage",
"expected_result": "Pass",
"alerts": [
{
"id": "alert-2026-2032-current",
"timestamp": "2026-06-09T04:00:00Z",
"rule": "suspicious-admin-token-use",
"triage_decision": {
"disposition": "needs_investigation",
"priority": "P2",
"confidence": "high"
},
"enrichment_provenance": {
"asset_criticality": {
"source": "edr_inventory",
"synced_at": "2026-06-09T03:55:00Z",
"applies_to_alert_time": true,
"confidence": "high"
},
"user_context": {
"source": "iam_directory",
"synced_at": "2026-06-09T03:58:00Z",
"privilege_level": "privileged_service_account",
"applies_to_alert_time": true,
"confidence": "high"
},
"threat_intel": {
"source": "internal-ti",
"lookup_at": "2026-06-09T04:03:00Z",
"indicator_last_seen": "2026-06-09T03:50:00Z",
"feed_health": "healthy",
"confidence": "high"
},
"geoip_asn_provider": {
"source": "asn-provider",
"lookup_at": "2026-06-09T04:03:00Z",
"tag": "cloud_provider",
"business_owner": "identity-platform",
"used_as_sole_fp_reason": false
}
}
},
{
"id": "alert-2026-2032-not-evaluable",
"timestamp": "2026-06-09T05:00:00Z",
"rule": "unusual-login-location",
"triage_decision": {
"disposition": "needs_investigation",
"priority": "P3",
"confidence": "low"
},
"enrichment_provenance": {
"asset_context": {
"status": "Not Evaluable",
"reason": "cmdb_sync_timestamp_missing"
},
"user_context": {
"status": "Not Evaluable",
"reason": "hr_feed_unavailable"
},
"geoip_asn_provider": {
"status": "Not Evaluable",
"reason": "provider_lookup_unavailable"
}
},
"guardrail": "Missing enrichment lowers confidence and keeps investigation open; it is not used as the sole reason to escalate or close the alert."
}
],
"covered_gates": [
"TRIAGE-ENRICH-01",
"TRIAGE-ENRICH-02",
"TRIAGE-ENRICH-03",
"TRIAGE-ENRICH-04",
"TRIAGE-ENRICH-05",
"TRIAGE-ENRICH-06",
"TRIAGE-ENRICH-07",
"TRIAGE-ENRICH-08"
],
"review_decision": {
"status": "Pass",
"rationale": "Current enrichment may support priority when provenance is documented, while unavailable enrichment is explicitly marked Not Evaluable and does not drive BTP/FP closure."
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
{
"case": "vulnerable_enrichment_freshness_and_provider_fp_gap",
"skill": "alert-triage",
"expected_result": "Fail",
"alert": {
"id": "alert-2026-2032-a",
"timestamp": "2026-06-09T02:15:00Z",
"rule": "rare-outbound-domain-from-server",
"proposed_disposition": "false_positive",
"proposed_priority": "P4"
},
"enrichment": {
"asset_context": {
"source": "cmdb",
"criticality": "low",
"environment": "dev",
"synced_at": "2026-05-20T00:00:00Z"
},
"cloud_inventory": {
"criticality": "crown-jewel",
"environment": "production",
"internet_facing": true,
"observed_at": "2026-06-09T02:12:00Z"
},
"threat_intel": {
"copied_from_case": "case-2026-010",
"prior_lookup_at": "2026-05-01T10:00:00Z",
"confidence": null,
"first_seen": null,
"last_seen": null,
"feed_health": "unknown"
},
"geoip_asn_provider": {
"tag": "cloud_provider",
"lookup_at": null,
"provider": null,
"corroborating_owner_or_change_ticket": null
},
"historical_disposition": {
"prior_case": "case-2026-010",
"prior_disposition": "BTP",
"rule_version_checked": false,
"asset_user_environment_drift_checked": false
},
"analyst_override": {
"value": "known benign cloud service",
"override_timestamp": null,
"source_document": null,
"reason": null
},
"correlated_alerts": [
{
"id": "alert-2026-2032-b",
"enrichment_age_hours": 48
}
]
},
"expected_findings": [
"TRIAGE-ENRICH-01: stale CMDB context lowers priority despite current production crown-jewel cloud inventory",
"TRIAGE-ENRICH-03: threat-intel reputation copied from an old case lacks lookup time, confidence, first/last seen, and feed health",
"TRIAGE-ENRICH-04: cloud-provider tag is used as the sole FP reason without provider/time/source or ownership context",
"TRIAGE-ENRICH-05: historical BTP disposition is reused without rule, asset, user, or environment drift checks",
"TRIAGE-ENRICH-07: analyst override lacks timestamp, source document, and reason",
"TRIAGE-ENRICH-08: correlated alert enrichment is stale but not included in decision freshness"
],
"review_decision": {
"status": "Fail",
"severity_floor": "High",
"rationale": "The proposed FP/P4 decision relies on stale and unattributed enrichment rather than alert-time applicable evidence."
}
}