CrowdStrike Falcon to IBM QRadar Integration
Forward CrowdStrike Falcon detections into IBM QRadar so endpoint signal participates in offense correlation alongside firewall, identity, and DLP telemetry. The integration polls the Falcon Detections API on a cadence and pushes each detection as a normalised event into QRadar's Universal DSM listener.
Falcon API uses OAuth2 client-credentials, so credential management is token refresh rather than static keys. QRadar accepts events over syslog or its REST API depending on deployment; we default to the REST API for cloud QRadar and emit syslog when `QRADAR_TRANSPORT=syslog`.
What you get
A real excerpt from a generated CrowdStrike Falcon-to-IBM QRadar integration. The full script ships with logging, env-var loading, error handling, FIFO-capped dedup state, and a README.
# RINOX INTEGRATION: CrowdStrike -> QRadar (Python, scheduled poll)
# Token refresh on 401, child-detection-level state, conditional advancement.
TOKEN, EXP = None, 0
def get_token():
global TOKEN, EXP
if TOKEN and time.time() < EXP - 60:
return TOKEN
resp = requests.post(f"{FALCON_BASE}/oauth2/token",
data={"client_id": CID, "client_secret": SECRET},
timeout=15)
resp.raise_for_status()
body = resp.json()
TOKEN, EXP = body["access_token"], time.time() + body["expires_in"]
return TOKEN
def fetch_detections(since_iso):
fql = f'created_timestamp:>="{since_iso}"'
headers = {"Authorization": f"Bearer {get_token()}"}
ids = requests.get(f"{FALCON_BASE}/detects/queries/detects/v1",
headers=headers, params={"filter": fql, "limit": 1000}).json()["resources"]
if not ids:
return []
# Bulk hydrate — N+1 elimination (Phase 3)
return requests.post(f"{FALCON_BASE}/detects/entities/summaries/GET/v1",
headers=headers, json={"ids": ids}).json()["resources"]Common pitfalls
The mistakes that turn this integration from "works once" into "loses data silently for three weeks."
- 01Track Falcon `detection_id`, not `behavior_id` or `aggregate_id`. Aggregate IDs are stable across multiple alerts and would dedupe legitimate new detections.
- 02Falcon timestamps come in ISO-8601 with timezone. Cast through `datetime.fromisoformat` before passing to QRadar — never compare ISO strings lexically.
- 03OAuth tokens expire every 30 minutes. The script must refresh on `401` and retry the original request — once. Two retries in a tight loop usually means the credentials are wrong, not that the token is expired.
- 04QRadar REST `/siem/offenses` is not the ingestion endpoint. Detections enter as events through the DSM/streaming surface, then QRadar correlates them into offenses.
- 05Falcon's `assigned_to_uid` field is a UUID, not a username. Resolve it via `/users/queries/users/v1` if you need a human-readable owner in QRadar.
Generate this for your environment.
Pre-fills the form with CrowdStrike Falcon and IBM QRadar. You write a sentence about your use case, we write the rest.
Generate CrowdStrike Falcon → IBM QRadarFrequently asked
Does this integration use streaming or polling?
Polling by default for predictability across QRadar customers. For high-volume environments, switch the source to the Falcon Streaming API by setting `FALCON_TRANSPORT=streaming`; the generated script handles both paths.
Why not push offenses directly into QRadar?
QRadar offenses are the output of QRadar's correlation engine. Inserting them directly bypasses the rules that make QRadar valuable. Detections enter as events; QRadar correlates them into offenses.
What about Falcon Insight detections vs. EPP detections?
Both are pulled by the same query — `behaviors[].objective` and `behaviors[].tactic` tell QRadar which is which.
How does it handle CrowdStrike rate limits?
Falcon returns `429` with `X-RateLimit-RetryAfter`. The generated script honours the header with jitter, and falls back to exponential backoff if the header is missing.