Written by: Nimesh Chakravarthi, Co-founder & CTO, Struct
Key Takeaways
-
Manual CrowdStrike Falcon triage burns engineering hours. End-to-end automation from detection through containment removes routine work and can save up to $1.9M per breach.
-
The five-step workflow uses the post-2025 Alerts API to ingest alerts, enrich with device and asset context, route by severity, contain safely, and then hand off for investigation.
-
Host isolation and RTR scripts must respect severity thresholds, asset criticality, and dry-run defaults so Tier-0 systems are never disrupted by mistake.
-
Integrations with Cortex XSOAR or similar SOAR platforms handle containment orchestration while Struct runs parallel root-cause analysis, cutting manual investigation from 30–45 minutes to about five.
-
Struct can automate your on-call runbook by sending AI-generated root-cause dashboards and suggested fixes directly into Slack after every Falcon detection.
Automated Incident Workflows with CrowdStrike Falcon
Automated workflows in incident response are rule-based or ML-driven pipelines that execute detection, enrichment, triage, containment, and recovery at machine speed. NIST SP 800-61 Revision 3 (April 2025) is a CSF 2.0-aligned community profile for incident response addressing the Respond and Recover functions. In the CrowdStrike Falcon context, the three native primitives are Fusion SOAR playbooks inside the Falcon console, the Alerts API as the authoritative post-2025 detection stream, and Real-Time Response (RTR) for live script execution on endpoints.
CrowdStrike deprecated its legacy Detections-based API on October 1, 2024, with decommissioning scheduled for September 30, 2025, so all integrations now authenticate against the Alerts API using a Client ID and Client Secret from the Falcon console API clients table.
The following skeleton handles OAuth token acquisition and a basic Alerts API poll. All production secrets must live in a secrets manager, not in source code.
import os import requests # --- Configuration (load from secrets manager in production) --- FALCON_BASE_URL = os.environ["FALCON_BASE_URL"] # e.g. https://api.crowdstrike.com CLIENT_ID = os.environ["FALCON_CLIENT_ID"] CLIENT_SECRET = os.environ["FALCON_CLIENT_SECRET"] def get_oauth_token() -> str: """Exchange client credentials for a short-lived bearer token.""" resp = requests.post( f"{FALCON_BASE_URL}/oauth2/token", data={"client_id": CLIENT_ID, "client_secret": CLIENT_SECRET}, headers={"Content-Type": "application/x-www-form-urlencoded"}, timeout=10, ) resp.raise_for_status() return resp.json()["access_token"] def list_open_alerts(token: str, severity_min: int = 3) -> list: """Fetch open alerts at or above the specified severity (1-5 scale). Uses /alerts/queries/alerts/v2, the post-2025 replacement for /detects. """ headers = {"Authorization": f"Bearer {token}"} params = { "filter": f"status:'open'+severity:>={severity_min}", "limit": 100, } resp = requests.get( f"{FALCON_BASE_URL}/alerts/queries/alerts/v2", headers=headers, params=params, timeout=15, ) resp.raise_for_status() return resp.json().get("resources", []) if __name__ == "__main__": token = get_oauth_token() alerts = list_open_alerts(token, severity_min=3) print(f"Open alerts (sev ≥ 3): {len(alerts)}")
Building a Four-Stage Falcon Incident Pipeline
The OAuth skeleton above handles alert ingestion, and a complete detection-to-containment-to-ticket pipeline builds on that foundation with four stages. SOAR playbooks commonly automate triage tasks such as indicator extraction, threat-intelligence checks, alert grouping, and ticket creation before moving to containment actions.
Stage 1 — Ingest and normalize. Poll /alerts/queries/alerts/v2 on a 60-second interval or subscribe to Falcon streaming for near-real-time delivery. Normalize each payload into a canonical incident object that carries device ID, severity, tactic, technique, and asset criticality.
Stage 2 — Enrich. Call /devices/entities/devices/v2 with the device ID to retrieve hostname, OS, site, and business unit. Cross-reference asset criticality from your CMDB. Append threat-intel context from your preferred feed.
Stage 3 — Route. Apply a severity whitelist described in the Production Guardrails section. Low-risk, high-confidence detections move to automated containment. High-blast-radius or ambiguous detections post a Slack approval request and wait for a human gate.
Stage 4 — Ticket. POST to Jira, Linear, or ServiceNow with the enriched payload, device timeline, and containment status. Attach the Falcon alert ID so analysts can deep-link back to the console.
import requests def create_jira_ticket(token: str, alert_id: str, device_id: str, severity: int, summary: str) -> str: """Create a Jira incident ticket with Falcon context attached. Requires JIRA_BASE_URL, JIRA_PROJECT_KEY, JIRA_API_TOKEN env vars. """ import os, base64 jira_url = os.environ["JIRA_BASE_URL"] project = os.environ["JIRA_PROJECT_KEY"] jira_token = os.environ["JIRA_API_TOKEN"] jira_user = os.environ["JIRA_USER_EMAIL"] credentials = base64.b64encode(f"{jira_user}:{jira_token}".encode()).decode() payload = { "fields": { "project": {"key": project}, "summary": f"[Falcon Sev-{severity}] {summary}", "description": f"Alert ID: {alert_id}\nDevice ID: {device_id}", "issuetype": {"name": "Incident"}, "priority": {"name": "High" if severity >= 4 else "Medium"}, } } resp = requests.post( f"{jira_url}/rest/api/3/issue", json=payload, headers={ "Authorization": f"Basic {credentials}", "Content-Type": "application/json", }, timeout=10, ) resp.raise_for_status() return resp.json()["key"]
Safe Host Isolation with the CrowdStrike API
Host isolation through the Falcon Device Control API is the highest-impact automated containment action available. Containment actions available in the Sumo Logic CrowdStrike Falcon integration (v1.21, updated March 31, 2026) include Close CrowdStrike Incident, Create Indicators, Device Actions, and Get Indicators.
Production warning: Isolating a host cuts all network connectivity except the Falcon sensor channel. Never automate isolation for production database servers, payment processors, or any asset tagged as Tier-0 without a manual approval gate. Start with workstations and developer laptops, then expand only after careful testing.
def isolate_host(token: str, device_id: str, dry_run: bool = True) -> dict: """Contain (network-isolate) a Falcon-managed host. Args: token: Valid OAuth bearer token. device_id: Falcon device ID from the alert payload. dry_run: If True, log the action but do NOT call the API. Set to False only after testing in staging. Returns: API response dict or a dry-run placeholder. """ import os base_url = os.environ["FALCON_BASE_URL"] if dry_run: print(f"[DRY RUN] Would isolate device: {device_id}") return {"status": "dry_run", "device_id": device_id} headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"} payload = { "action_parameters": [{"name": "action_name", "value": "contain"}], "ids": [device_id], } resp = requests.post( f"{base_url}/devices/entities/devices-actions/v2?action_name=contain", json=payload, headers=headers, timeout=15, ) resp.raise_for_status() return resp.json()
Palo Alto Networks Unit 42 research indicates that attackers often exfiltrate data quickly in many incidents, with AI-assisted attacks accelerating exfiltration times even further. Automated isolation is not optional for high-severity detections. It is the only response that consistently operates at attacker speed.
CrowdStrike RTR Python Script Example and Best Practices
Real-Time Response (RTR) lets engineers upload pre-approved scripts to the Falcon script library and execute them on live endpoints without opening an interactive shell. Scripts must be peer-reviewed for logic errors, unsafe assumptions, hardcoded values, and destructive commands before any production use, and rollback procedures must be tested in advance.
The 2025–2026 RTR best practices for production environments form a progression from basic safety to controlled rollout. Upload scripts to the RTR script library via the Falcon console and avoid ad-hoc commands that have not been reviewed and version-controlled. Scope scripts to the minimum required permissions and run them under a dedicated service account, not an admin’s personal credentials.
-
Validate repeatability so re-running the same script on the same device does not create duplicate changes, inconsistent endpoint states, or configuration drift.
-
Capture structured output including timestamp, target, test type, status, and error details, then export to JSON for audit trails and later analysis.
-
Pilot on a small, controlled group of representative devices, then roll out in phases with clear success criteria and failure thresholds.
def run_rtr_script(token: str, device_id: str, script_name: str, timeout_s: int = 60) -> dict: """Initiate an RTR session and execute a pre-approved library script. IMPORTANT: script_name must already exist in the Falcon RTR script library. Do NOT pass user-supplied strings directly, validate against an allowlist. """ import os, time base_url = os.environ["FALCON_BASE_URL"] headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"} ALLOWED_SCRIPTS = {"collect_artifacts", "check_persistence", "dump_processes"} if script_name not in ALLOWED_SCRIPTS: raise ValueError(f"Script '{script_name}' is not in the approved allowlist.") # Step 1: Open RTR session session_resp = requests.post( f"{base_url}/real-time-response/entities/sessions/v1", json={"device_id": device_id, "queue_offline": False}, headers=headers, timeout=15, ) session_resp.raise_for_status() session_id = session_resp.json()["resources"][0]["session_id"] # Step 2: Execute the approved script exec_resp = requests.post( f"{base_url}/real-time-response/entities/scripts/v1", json={ "base_command": "runscript", "command_string": f"runscript -CloudFile={script_name}", "session_id": session_id, }, headers=headers, timeout=timeout_s, ) exec_resp.raise_for_status() # Step 3: Always close the session to release the concurrent-session slot requests.delete( f"{base_url}/real-time-response/entities/sessions/v1", json={"session_id": session_id}, headers=headers, timeout=10, ) return exec_resp.json()
Coordinating Falcon with Cortex XSOAR and Struct
SOAR platforms integrate with EDR platforms such as CrowdStrike using APIs, agents, and prebuilt connectors, with webhooks as the common event-driven pattern that lets SOAR react immediately to EDR events instead of waiting on polling cycles. The Cortex XSOAR CrowdStrike Falcon integration maps Falcon alert severities to XSOAR incident types, triggers playbooks on ingest, and surfaces containment actions as playbook tasks.
The same Alerts API stream that feeds XSOAR can simultaneously feed Struct. When a Falcon detection fires, Struct ingests the enriched alert payload, correlates it against application logs, traces, and recent code changes in GitHub, and delivers a root-cause dashboard inside the Slack incident thread before the on-call engineer opens their laptop. XSOAR continues to orchestrate containment, and Struct runs the investigation layer in parallel, eliminating the manual log-hunting phase described later in this article.
Production Guardrails for Falcon Automation
The core design pattern for incident response automation is “automate the routine, escalate the consequential” with human-in-the-loop checkpoints between triage and containment and again before eradication of production assets. These guardrails apply whether you orchestrate containment through XSOAR, run custom Python, or use Struct alongside Falcon.
Severity whitelist. Only automate containment for detections with Falcon severity ≥ 4 (High or Critical) and a confidence score above your defined threshold. Severity 1–3 detections should enrich and ticket, not isolate.
Asset criticality gate. Even high-severity detections require an asset filter. Maintain a CMDB tag or environment variable list of Tier-0 assets such as databases, payment processors, and auth services. Any detection on a Tier-0 asset must route to a Slack approval workflow before any containment action executes.
Blast-radius check. Beyond asset type, you also need a blast-radius assessment. Before isolating, query how many active user sessions or dependent services are connected to the target host. If the count exceeds a defined threshold, escalate to human review.
Dry-run mode. All automation should ship with a dry_run=True default. Promote to dry_run=False only after a staged rollout on non-production hosts with documented sign-off.
Rollback procedure. Every isolation action must have a corresponding lift-containment script in the RTR library, tested and version-controlled, and executable by any on-call engineer without escalation. See how Struct automates post-containment investigation
Common Failure Modes in Falcon Automation
The following failure modes come from production RTR and Alerts API deployments. Each entry lists the error condition, its root cause, and a practical mitigation so you can harden your own workflows.
401 Unauthorized on Alerts API call. OAuth tokens expire after about 30 minutes. Mitigation: implement token caching with a TTL of 25 minutes and automatic refresh before expiry.
404 on device containment action. The device ID from the alert payload does not match a currently enrolled sensor. Mitigation: validate device enrollment status via /devices/entities/devices/v2 before issuing containment, then log and skip unenrolled devices.
RTR session fails to open. The device is offline or the concurrent session limit is reached. Validation testing must cover offline devices, expired credentials, and execution interruptions to understand failure behavior. Mitigation: use queue_offline=True for non-urgent scripts and implement exponential backoff with a maximum of three retries.
Script not found in RTR library. The script name passed to runscript does not exist in the Falcon console library. Mitigation: validate against a hardcoded allowlist in code, as shown in the RTR example above, before opening a session.
Isolation of wrong host. A device ID collision or copy-paste error occurs in a manual override. Mitigation: log full device metadata such as hostname, IP, and OS to a structured audit trail before every containment action, and require a second confirmation for any manual override of the automation.
Stale /detects endpoint calls. As noted earlier, CrowdStrike decommissioned the legacy Detects API in September 2025. Any integration still calling /detects returns no data. Mitigation: audit all automation code for legacy endpoint references and migrate to /alerts immediately.
Handoff to Struct for Automated Investigation
Containment stops the bleeding, and root-cause investigation explains why it started so you can prevent a repeat. Many workflows automate containment but still rely on manual investigation afterward.
Struct integrates directly into the Slack channel where Falcon alerts surface. The moment a detection fires and containment executes, Struct begins correlating the alert payload against application logs such as Datadog or AWS CloudWatch, distributed traces, Sentry exceptions, and recent GitHub commits. Within about five minutes, the on-call engineer receives a dynamically generated dashboard in Slack that shows the blast radius, a unified timeline of events across the stack, the identified root cause, and suggested fixes. For code-level root causes, Struct can generate a pull request directly.
This approach removes the manual investigation phase described earlier, the 30–45 minutes that typically follow containment. Real-world deployments show 50%–99.9% reductions in dwell time and MTTR from automated or AI-assisted incident response. The Struct handoff closes the loop from detection to resolution without requiring a senior engineer to manually reconstruct context in the middle of the night.
Measuring Success with MTTR, Precision, and On-Call Load
Three KPIs show whether the automation is working, and together they form a system of checks and balances.
Mean Time to Respond (MTTR). MTTR measures speed. Track the delta between alert timestamp and ticket-closed timestamp before and after automation. Organizations using AI-assisted incident response have reported significant reductions in MTTD and MTTR.
False-positive isolation rate. Speed without precision creates chaos, so you also track the percentage of automated containment actions that are reversed within 30 minutes as a proxy for automation accuracy. SOAR tooling can reduce false positives, with AI-driven detection providing further improvements. A false-positive isolation rate above 5% signals that severity thresholds or asset criticality gates need tightening.
On-call hours saved per engineer per week. When both MTTR and false-positive rate improve, the benefit appears in on-call hours saved. Log the time engineers spend in active incident response before and after Struct integration. Struct’s production deployments reduce triage time by over 80%, turning a 45-minute investigation into a 5-minute review.
Frequently Asked Questions
What is the minimum tooling maturity required to implement this workflow?
The workflow requires CrowdStrike Falcon EDR with API access enabled, a Python 3.10+ runtime for the automation scripts, a Slack workspace for alert delivery and approval gates, and at least one observability tool such as Datadog or AWS CloudWatch for Struct to query during investigation. Teams without basic logging, trace IDs, or alerting triggers will not get accurate root-cause output from Struct. The golden configuration uses Sentry for exceptions, a cloud log provider for infrastructure logs, and Slack for alert routing.
How long does Struct take to set up?
Struct connects in under 10 minutes. Authentication requires linking your issue source such as Slack or a ticketing system like Linear or Jira, your code repository such as GitHub, and your observability context such as Datadog or cloud logs. Once connected, auto-investigations activate immediately. There is no lengthy enterprise deployment, no indexing phase, and no professional services engagement required for standard configurations.
Is Struct compliant with SOC 2 and HIPAA requirements?
Struct is fully SOC 2 and HIPAA compliant. Log data is accessed and processed ephemerally, and it is not stored beyond the investigation window. For Seed-to-Series-C companies operating under standard compliance requirements, this posture covers the vast majority of use cases. Teams with strict on-premise or zero-egress requirements should evaluate Struct’s Enterprise tier, which includes sidecar and on-prem support options.
Is it safe to put junior engineers on call with this automation in place?
Struct acts as an automated senior engineer for the first pass of every alert. It digests company-specific runbooks and delivers a heavily contextualized, step-by-step starting point for any incident directly in Slack. Junior engineers receive the blast radius, root cause, and suggested fixes before they need to make decisions. The manual approval gates in the containment workflow also ensure that high-impact actions require explicit human confirmation, which prevents accidental isolation of critical infrastructure by engineers who are still learning the system.
What happens if the Falcon Alerts API changes again after the 2025 migration?
CrowdStrike publishes deprecation notices well in advance of endpoint decommissions, and the September 2025 Detects API cutover followed that pattern. The mitigation is to pin your integration to a specific API version, subscribe to CrowdStrike’s release notes and changelog, and run integration tests against a staging tenant on every deployment. The Python skeletons in this article target the current v2 Alerts API endpoints as of June 2026 and should be re-validated against CrowdStrike documentation on any major platform release.
Conclusion
Manual CrowdStrike Falcon EDR triage is an engineering scaling problem, not a headcount problem. The five-step workflow uses the post-2025 Alerts API to ingest alerts, enriches with device and asset context, routes through severity-based automation rules, contains with production-safe RTR scripts, and then hands off to Struct for root-cause investigation. This approach removes the manual triage loop that burns out on-call teams and extends MTTR.
Production guardrails, explicit approval gates for Tier-0 assets, and a dry-run-first deployment model ensure the automation does not create new incidents while resolving existing ones. Struct closes the final gap by replacing the 30–45 minutes of manual log-hunting that follow containment with a five-minute AI-generated root-cause dashboard delivered directly in Slack. Book a demo to automate your incident response