SOAR Integration Guide
RhythmX integrates with SOAR platforms (Cortex XSOAR, Splunk SOAR, IBM QRadar SOAR, etc.) through three methods — choose the approach that best fits your architecture.
Integration Methods
flowchart TD
RX["RhythmX Platform"]
RX -->|"Option 1: Syslog Push"| S["SIEM → SOAR Trigger"]
RX -->|"Option 2: REST API Poll"| P["SOAR Polls API"]
RX -->|"Option 3: Webhook Push"| W["Jira/ServiceNow → SOAR"]
S --> SOAR["SOAR Platform"]
P --> SOAR
W --> SOAR
style RX fill:#4a148c,stroke:#9c27b0,color:#fff
style S fill:#0d47a1,stroke:#42a5f5,color:#fff
style P fill:#1b5e20,stroke:#4c8c4a,color:#fff
style W fill:#b71c1c,stroke:#f05545,color:#fff
style SOAR fill:#e65100,stroke:#ff9800,color:#fff
| Method | Latency | Code Changes | Best For |
|---|---|---|---|
| Syslog | Near real-time (~60s) | None | SOAR ingests from SIEM (Splunk, QRadar) |
| REST API | Polling interval (1-5 min) | None | SOAR fetches directly from RhythmX |
| Webhook via Tickets | Real-time | None | SOAR watches Jira/ServiceNow tickets |
Option 1: Syslog-Based Integration
RhythmX pushes incident and case events to your SIEM via syslog. Your SOAR triggers playbooks based on SIEM correlation rules.
How It Works
flowchart LR
RX["RhythmX"] -->|"RFC 5424<br>TCP/514"| SIEM["SIEM<br>(Splunk/QRadar)"]
SIEM -->|"Correlation Rule<br>Trigger"| SOAR["SOAR Platform"]
SOAR -->|"Playbook Actions"| RX
style RX fill:#4a148c,stroke:#9c27b0,color:#fff
style SIEM fill:#0d47a1,stroke:#42a5f5,color:#fff
style SOAR fill:#e65100,stroke:#ff9800,color:#fff
Setup
-
Configure Syslog Export — System Settings > Integrations > Incident/Case Syslog Forwarding
- Host: Your SIEM's syslog receiver IP
- Port: 514 (or custom)
- Protocol: TCP (recommended) or UDP
-
Create SIEM Correlation Rule — Trigger on:
- Facility:
local1(17) - App Name:
SigmaIncident - Event:
created - Risk Score:
>= 70(or your threshold)
- Facility:
-
SOAR Playbook Trigger — SOAR watches for SIEM alerts matching the correlation rule
Syslog Data Available
Every incident syslog message includes (see Syslog Message Format for full details):
- Structured Data: incident ID, actor, entity, status, risk score, alarm/sigma/case counts, related case IDs
- JSON Body: Full enriched payload with risk breakdown, MITRE tactics, related cases, timeline
Example SOAR enrichment from syslog:
risk_score=82 → Set playbook severity to Critical
related_case_types="lateral_movement,credential_theft" → Run lateral movement containment
threat_case_count=3 → Escalate to Tier 3
assigned_analyst="" → Auto-assign via SOAR round-robin
Option 2: REST API Polling
The SOAR polls RhythmX directly to fetch new incidents and cases. Zero code changes required — the existing API supports all necessary queries.
How It Works
flowchart LR
SOAR["SOAR Platform"] -->|"GET /api/incidents<br>?since=timestamp"| RX["RhythmX API"]
RX -->|"JSON Response<br>New Incidents"| SOAR
SOAR -->|"PATCH /api/incidents<br>Status Update"| RX
style RX fill:#4a148c,stroke:#9c27b0,color:#fff
style SOAR fill:#e65100,stroke:#ff9800,color:#fff
Authentication
Two options depending on your security requirements:
JWT Authentication (full access):
POST /api/login
Content-Type: application/json
{"username": "soar-service-account", "password": "..."}
API Key Authentication (read-only, recommended for polling):
GET /api/v1/feed/incidents
X-API-Key: smk_your_api_key_here
Polling Workflow
Step 1: Initial Fetch
On first run, fetch all open incidents:
GET /api/incidents?status=OPEN&sort_by=created_at&limit=100
Authorization: Bearer <jwt_token>
Or using the External Feed API:
GET /api/v1/feed/incidents?status=OPEN&limit=100
X-API-Key: smk_your_key
Step 2: Incremental Polling
Every 1-5 minutes, fetch only new incidents:
GET /api/incidents?since=2026-03-13T04:30:00Z&limit=100
And check for updated incidents (status changes, assignments):
GET /api/incidents?updated_since=2026-03-13T04:30:00Z&limit=100
Step 3: Fetch Related Cases
For each incident, get the related threat cases:
GET /api/cases/search?entity_name=Primary%20Site&status=OPEN
Step 4: Update Status Back
When the SOAR resolves an incident, update RhythmX:
PATCH /api/incidents/INC-7601d999/status
Content-Type: application/json
Authorization: Bearer <jwt_token>
{"status": "CLOSED", "notes": "Resolved via SOAR playbook PB-1234"}
Polling Parameters
| Endpoint | Key Parameters |
|---|---|
GET /api/incidents |
since, updated_since, status, entity, limit, offset |
GET /api/v1/feed/incidents |
since, status, limit, offset |
GET /api/v1/feed/cases |
since, severity, case_type, limit, offset |
GET /api/incidents/{id} |
— (full detail) |
GET /api/cases/{id} |
— (full detail with alerts) |
Response Fields for SOAR Mapping
| RhythmX Field | SOAR Field (typical) | Notes |
|---|---|---|
incident_id |
External ID | Unique identifier |
group_key |
Source/Actor | User, host, or IP |
risk_score |
Severity (0-100) | Map to SOAR severity levels |
risk_level |
Priority | critical/high/medium/low |
alarm_count |
Event Count | Total LogRhythm alarms |
sigma_alert_count |
Alert Count | RhythmX rule detections |
threat_case_count |
Case Count | Correlated attack patterns |
entity_name |
Organization/Tenant | For MSSP routing |
status |
Status | OPEN/IN_PROGRESS/CLOSED/FALSE_POSITIVE |
assigned_analyst |
Owner | Current assignee |
first_alarm_time |
Start Time | First detection |
last_alarm_time |
Last Activity | Most recent detection |
Example: Cortex XSOAR Integration
Fetch Incidents command:
def fetch_incidents():
last_run = demisto.getLastRun().get('last_fetch', '')
url = f'https://rhythmx.example.com/api/incidents?since={last_run}&status=OPEN&limit=50'
headers = {'Authorization': f'Bearer {get_token()}'}
response = requests.get(url, headers=headers, verify=False)
incidents = response.json().get('incidents', [])
demisto_incidents = []
for inc in incidents:
demisto_incidents.append({
'name': f"RhythmX: {inc['group_key']} ({inc['actor_type']})",
'severity': map_severity(inc.get('risk_score', 0)),
'rawJSON': json.dumps(inc),
'occurred': inc['created_at'],
})
demisto.setLastRun({'last_fetch': datetime.utcnow().isoformat() + 'Z'})
demisto.incidents(demisto_incidents)
def map_severity(risk_score):
if risk_score >= 85: return 4 # Critical
if risk_score >= 70: return 3 # High
if risk_score >= 40: return 2 # Medium
return 1 # Low
Example: Splunk SOAR Integration
Polling action:
def on_poll(self, param):
last_time = self._state.get('last_poll_time', '')
url = f'{self._base_url}/api/v1/feed/incidents'
params = {'since': last_time, 'status': 'OPEN', 'limit': 100}
headers = {'X-API-Key': self._api_key}
response = requests.get(url, params=params, headers=headers)
data = response.json()
for incident in data.get('data', []):
container = {
'name': f"RhythmX Incident: {incident['group_key']}",
'severity': 'high' if incident.get('risk_score', 0) >= 70 else 'medium',
'source_data_identifier': incident['incident_id'],
}
self.save_container(container)
self._state['last_poll_time'] = datetime.utcnow().isoformat() + 'Z'
Option 3: Webhook via Ticketing System
RhythmX pushes incidents to Jira or ServiceNow. Your SOAR watches the ticketing system for new tickets and triggers playbooks.
How It Works
flowchart LR
RX["RhythmX"] -->|"Create Ticket<br>(auto-push)"| T["Jira /<br>ServiceNow"]
T -->|"Webhook"| SOAR["SOAR Platform"]
SOAR -->|"Update Ticket"| T
T -->|"Webhook"| RX
style RX fill:#4a148c,stroke:#9c27b0,color:#fff
style T fill:#0d47a1,stroke:#42a5f5,color:#fff
style SOAR fill:#e65100,stroke:#ff9800,color:#fff
Setup
- Configure Jira/ServiceNow in System Settings > Integrations
- Enable Auto-Push — automatically creates tickets for critical incidents
- SOAR watches tickets — most SOARs natively integrate with Jira/ServiceNow
- Bi-directional sync — RhythmX receives status updates via webhooks
Auto-Push Settings
| Setting | Default | Description |
|---|---|---|
AUTO_PUSH_ENABLED |
false |
Enable automatic ticket creation |
AUTO_PUSH_MIN_SEVERITY |
CRITICAL |
Minimum severity to auto-push |
AUTO_PUSH_SYSTEMS |
jira |
Target systems (jira, servicenow) |
Ticket Content
Auto-created tickets include:
- Actor identity and type
- Risk score with 7-factor breakdown
- MITRE ATT&CK tactics and techniques
- Alarm and alert counts
- Timeline (first/last detection)
- Investigation notes
- Direct link to RhythmX investigation
Retry Queue
Failed ticket deliveries are automatically retried with exponential backoff:
- Max retries: 5
- Base delay: 60 seconds
- Max delay: 1 hour
- Backoff: Exponential (60s → 120s → 240s → 480s → 960s)
Choosing the Right Method
| Consideration | Syslog | REST API | Webhook/Tickets |
|---|---|---|---|
| Setup effort | Low (configure syslog target) | Low (create API key) | Medium (configure ticketing) |
| Latency | ~60 seconds | 1-5 minutes (polling) | Real-time (auto-push) |
| Data richness | Full (structured data + JSON) | Full (API response) | Ticket fields only |
| Bi-directional | No (push only) | Yes (read + write) | Yes (via webhooks) |
| SOAR integration | Via SIEM correlation | Direct API integration | Native ticket connector |
| Authentication | Network-level (firewall) | API key or JWT | Ticketing system auth |
| Offline resilience | Syslog TCP retry | SOAR retries polling | Retry queue (5 attempts) |
Recommended combinations:
- SOAR + SIEM already deployed: Use Syslog (Option 1) — incidents flow through your existing SIEM pipeline
- SOAR only, no SIEM: Use REST API (Option 2) — direct integration, no intermediary
- SOAR + Jira/ServiceNow: Use Webhook (Option 3) — leverages existing ticket workflow
You can also combine methods — for example, use syslog for real-time alerting and REST API for enrichment lookups during playbook execution.