IT Incident Response
Automate SOC alert triage and containment. The agent ingests security alerts, enriches indicators with threat intelligence, correlates across SIEM data, takes containment actions, and escalates to analysts when confidence is low. The reasoning trace is the incident report.
Architecture
Graduated response: Known-benign alerts auto-close (~70%). Clear threats get auto-containment with agent reasoning (~20%). Ambiguous or high-severity incidents escalate to SOC analysts (~10%).
Required Actions
Register these before deploying the workflow:
| Action | Kind | Purpose |
|---|---|---|
enrich_indicator |
http |
Query threat intel feeds (VirusTotal, AbuseIPDB, MISP) |
query_siem |
http |
Search SIEM for correlated events (Splunk, Elastic, Sentinel) |
lookup_asset |
http |
Map IP/hostname to asset inventory and owner |
block_ip |
http |
Add IP to firewall blocklist |
isolate_host |
http |
Trigger host isolation via EDR (CrowdStrike, SentinelOne) |
create_ticket |
http |
Open incident ticket in ServiceNow / Jira |
classify_severity |
llm |
AI-assess severity from enrichment context |
curl -X POST https://apisvr.tryhyphen.com/actions \
-H "X-Org-Id: your-org" \
-H "Content-Type: application/json" \
-d '{
"action_name": "enrich_indicator",
"kind": "http",
"url": "https://www.virustotal.com/api/v3/ip_addresses/{{indicator}}",
"http_method": "GET",
"headers": { "x-apikey": "orgconfig:api:virustotal_key" },
"passthrough": true
}'
curl -X POST https://apisvr.tryhyphen.com/actions \
-H "X-Org-Id: your-org" \
-H "Content-Type: application/json" \
-d '{
"action_name": "classify_severity",
"kind": "llm",
"template": "Given this security alert and enrichment data, classify severity as critical/high/medium/low and recommend containment action.\n\nAlert: {{alert}}\nEnrichment: {{enrichment}}\nAsset info: {{asset}}\n\nRespond with JSON: {\"severity\": \"...\", \"recommendation\": \"...\", \"confidence\": 0.0-1.0}",
"model": "gpt-4",
"max_tokens": 500
}'
Workflow Definition
{
"name": "incident_response_pipeline",
"definition": {
"actions": [
{
"type": "matcher",
"properties": {
"left": "@input.alerts",
"right": "@input.known_benign_indicators",
"matchOn": ["indicator_value"],
"outputMatched": "known_benign",
"outputUnmatchedLeft": "alerts_to_investigate",
"outputUnmatchedRight": "unused_benign"
}
},
{
"type": "loop",
"filter": {
"condition": {
"greaterThan": [{ "length": "@alerts_to_investigate" }, 0]
}
},
"properties": {
"mode": "foreach",
"items_path": "@alerts_to_investigate",
"item_variable_name": "alert",
"actions_to_execute": [
{
"type": "loop",
"properties": {
"mode": "react",
"objective": "Investigate this security alert and recommend containment:\n\nAlert type: {{alert.type}}\nIndicator: {{alert.indicator_value}}\nSource: {{alert.source}}\nTimestamp: {{alert.timestamp}}\n\nSteps: 1) Enrich the indicator with threat intelligence, 2) Look up the affected asset and its owner, 3) Query SIEM for correlated events in the last 24 hours, 4) Classify severity, 5) If critical/high severity with high confidence — take containment action (block IP or isolate host). If medium/low or uncertain — escalate for human review. 6) Complete with your assessment.",
"tools": [
{ "type": "action", "name": "enrich_indicator" },
{ "type": "action", "name": "query_siem" },
{ "type": "action", "name": "lookup_asset" },
{ "type": "action", "name": "classify_severity" },
{ "type": "action", "name": "block_ip" },
{ "type": "action", "name": "isolate_host" },
{ "type": "action", "name": "create_ticket" }
],
"model": "gpt-4",
"max_iterations": 12,
"timeout_ms": 300000,
"on_stuck": {
"iterations": 3,
"action": "escalate"
},
"result_key": "investigation"
}
}
],
"max_concurrency": 5,
"failure_strategy": "continue_on_error",
"result_key": "investigation_results"
}
},
{
"type": "custom-table",
"properties": {
"table": "incident_log",
"operation": "write",
"keys": ["run_id", "timestamp"],
"values": ["@__run_id", "@now"],
"fields": {
"alerts_received": "@input.alerts.length",
"auto_closed": "@known_benign.length",
"investigated": "@alerts_to_investigate.length",
"status": "completed"
}
}
}
]
}
}
Structural Permissioning in Action
This is where governed autonomy matters most. The agent's tool list is an architectural constraint, not a policy:
| Tool declared | Agent can... |
|---|---|
block_ip |
Block an IP address at the firewall |
isolate_host |
Isolate a host via EDR |
create_ticket |
Open an incident ticket |
| Tool NOT declared | Agent cannot... |
|---|---|
delete_firewall_rule |
Modify existing firewall rules |
shutdown_server |
Shut down production systems |
access_credentials_vault |
Read or modify stored secrets |
The agent cannot discover or invent tools. It works with exactly the capabilities you've declared. If you want the agent to block IPs but not isolate hosts, remove isolate_host from the tools list. No prompt engineering required — it's structural.
Sample Reasoning Trace
Iteration 1:
Thought: "Suspicious source indicator flagged by firewall. Let me check threat intel."
Action: enrich_indicator
Input: { "indicator": "src-indicator-001" }
Result: { "malicious_score": 87, "tags": ["tor_exit_node", "scanning"], "last_seen": "2026-02-06" }
Iteration 2:
Thought: "Known Tor exit node with high malicious score. Let me check what asset it targeted."
Action: lookup_asset
Input: { "asset_ref": "asset-045" }
Result: { "hostname": "web-prod-03", "owner": "Platform Team", "criticality": "high" }
Iteration 3:
Thought: "High-criticality production server targeted by known malicious IP. Checking SIEM for more context."
Action: query_siem
Input: { "query": "source_indicator=src-indicator-001 last 24h", "limit": 50 }
Result: { "event_count": 247, "patterns": ["port_scan", "ssh_brute_force"] }
Iteration 4:
Thought: "247 events including SSH brute force against a production server. This is critical. Blocking immediately."
Action: block_ip
Input: { "indicator": "src-indicator-001", "reason": "Tor exit node — SSH brute force against web-prod-03" }
Result: { "blocked": true, "rule_id": "fw-rule-8823" }
Iteration 5:
Thought: "IP blocked. Creating incident ticket for follow-up investigation."
Action: create_ticket
Input: { "severity": "high", "title": "SSH brute force from Tor exit node against web-prod-03", ... }
Result: { "ticket_id": "INC-4521" }
Iteration 6:
Thought: "Contained and documented. Completing with assessment."
Action: __complete__
Input: {
"answer": "Critical: Tor exit node conducting SSH brute force against production server. IP blocked. Ticket INC-4521 created.",
"confidence": 0.95
}
This trace is the incident report. Every decision — why the IP was flagged, what intelligence confirmed it, what containment was taken — is queryable and auditable.
Customization
Alert sources: Replace @input.alerts with webhook ingestion from your SIEM (Splunk, Elastic, Microsoft Sentinel, CrowdStrike).
Threat intel feeds: Register additional enrich_indicator actions for multiple feeds — VirusTotal, AbuseIPDB, MISP, Recorded Future. The agent will use whichever it deems most relevant.
Containment actions: Control the blast radius by tuning the tool list. Start with block_ip only, add isolate_host after trust is established.
Escalation threshold: Adjust max_iterations and on_stuck settings. For SOC teams with fast SLAs, set on_stuck.iterations: 2 with action: "escalate" to route to analysts quickly.
Compliance alignment: The audit table + reasoning trace satisfies SOC 2 CC7.3 (incident response), ISO 27001 A.16 (incident management), and NIST CSF RS.AN (response analysis). No additional logging required.