Skip to content

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

  1. 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
  2. Create SIEM Correlation Rule — Trigger on:

    • Facility: local1 (17)
    • App Name: SigmaIncident
    • Event: created
    • Risk Score: >= 70 (or your threshold)
  3. 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": "..."}
Returns a JWT token. Token must be refreshed periodically.

API Key Authentication (read-only, recommended for polling):

GET /api/v1/feed/incidents
X-API-Key: smk_your_api_key_here
Create API keys in System Settings > Integration Admin. Keys don't expire unless configured.

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

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

  1. Configure Jira/ServiceNow in System Settings > Integrations
  2. Enable Auto-Push — automatically creates tickets for critical incidents
  3. SOAR watches tickets — most SOARs natively integrate with Jira/ServiceNow
  4. 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.