Quick Start
This guide walks through the six essential steps for getting started with CSIRT-Pro: create a pipeline, generate an API key, send logs, search your data, create a case, and automate with a playbook.
Prerequisites
- A CSIRT-Pro account. Your administrator provides the login URL.
Step 1: Create a Pipeline
A Pipeline defines how incoming logs are parsed and stored. Each Pipeline corresponds to a distinct logical destination in the log analytics store.
Via the UI
- Open Pipeline in the left sidebar.
- Click Create New.
- Enter a pipeline name (for example,
firewall_logs). The name must be unique within your organization. - Configure parse settings (see below), or leave them empty for JSON auto-parsing.
- Set the TTL (retention period in days, or
0for unlimited). - Click Save.
Parse Settings (for structured text logs)
CSIRT-Pro uses two fields for parse configuration.
druid_parseis a regex pattern with numbered capture groups.druid_parse_fieldis a comma-separated list of field names that map to each capture group.- A field name can carry a type as
name(Type)(e.g.dst_port(Int32),bytes(Int64)) so the value is extracted with that type; an unannotated name defaults toString. This works in both regex and JSON mode. Supported types includeString,Int8/Int16/Int32/Int64,UInt8/UInt16/UInt32/UInt64,Float32/Float64,Bool,Date,DateTime. Typed numeric fields can be compared (dst_port == 22) and aggregated (sum bytes) without conversion functions.
If druid_parse is empty, the Pipeline treats each message as JSON and extracts fields from it.
If it is set, the Pipeline applies the regex.
Either way, extraction happens at query time (schema-on-read).
Example, Apache access log.
druid_parse (regex):
druid_parse_field (field names):
Each numbered capture group in the regex maps to the corresponding field name in order.
AI parse generation
Paste a sample log line and click AI Generate to have the generative AI propose parse rules. Review and apply the result before saving.
Step 2: Generate an API Key
An API key is required for sending logs and integrating with external tools.
How to Generate
- Click your user icon in the top-right corner.
- Select Settings.
- Open API Keys in the left menu.
- Click Create New.
- Enter a name for the key (for example,
log-forwarder). - Click Create.
Store your API key safely
The API key is shown only once, at creation. Save it in a secure location. If it is lost, revoke the existing key and create a new one.
Use the API key in the X-API-Key header.
API keys carry scopes that control what each key is permitted to do.
Step 3: Send Logs
With a Pipeline and an API key ready, you can send logs.
Send them as plain text (text/plain), and the Pipeline's parse rules extract fields on the server side.
The ingestion endpoint requires pipeline_id.
Send with curl
Single Line
curl -X POST "https://<your-domain>/api/v2/ingest?pipeline_id=<pipeline_id>" \
-H "X-API-Key: <your-api-key>" \
-H "Content-Type: text/plain" \
-d '2025-01-15T10:30:00Z DENY 192.168.1.100 10.0.0.50 443 1024'
Response:
{
"status": "ok",
"organization_uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"table_name": "firewall_logs",
"messages_count": 1
}
Multiple Lines
Send multiple log lines at once, separated by newlines.
curl -X POST "https://<your-domain>/api/v2/ingest?pipeline_id=<pipeline_id>" \
-H "X-API-Key: <your-api-key>" \
-H "Content-Type: text/plain" \
-d '2025-01-15T10:30:00Z DENY 192.168.1.100 10.0.0.50 443 1024
2025-01-15T10:30:01Z ALLOW 192.168.1.101 10.0.0.51 80 2048
2025-01-15T10:30:02Z DENY 192.168.1.100 10.0.0.52 22 512'
Response:
{
"status": "ok",
"organization_uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"table_name": "firewall_logs",
"messages_count": 1
}
How messages_count is counted
messages_count is the number of payloads accepted by the API.
For text/plain, the whole body counts as a single payload, so a multi-line request still returns messages_count of 1 (each line is split into one record per line on the server side).
To count items individually, use the batch endpoint (/api/v2/ingest/batch) with a messages array in the body; it returns the number of array elements.
JSON Format
For JSON log sources, send with application/json.
curl -X POST "https://<your-domain>/api/v2/ingest?pipeline_id=<pipeline_id>" \
-H "X-API-Key: <your-api-key>" \
-H "Content-Type: application/json" \
-d '{
"timestamp": "2025-01-15T10:30:00Z",
"action": "DENY",
"src_ip": "192.168.1.100",
"dst_ip": "10.0.0.50",
"dst_port": 443,
"bytes": 1024
}'
Verify the response
Confirm that "status": "ok" is returned. If an error occurs, check that the Pipeline ID and API key are correct.
Send with an HTTP Log Forwarder
Any agent that can POST over HTTP works as a log forwarder. Send log lines as-is in plain text, and the Pipeline handles parsing on the server side. A typical HTTP sink configuration looks like this.
# Endpoint
uri: "https://<your-domain>/api/v2/ingest?pipeline_id=<pipeline_id>"
method: POST
# Headers
X-API-Key: "<your-api-key>"
Content-Type: "text/plain"
# Batching (tune to your forwarder)
batch:
max_events: 100
timeout_secs: 5
Choosing a forwarder
Prefer a forwarder that tracks file read position so a restart does not drop or duplicate lines, and that batches requests to reduce overhead. Client-side parsing is not required, because the Pipeline parses on the server side.
Send with Logstash
Logstash is a log pipeline tool from Elastic. If you already run Logstash, add a CSIRT-Pro output.
logstash.conf:
input {
file {
path => "/var/log/firewall/*.log"
start_position => "beginning"
sincedb_path => "/var/lib/logstash/sincedb_firewall"
mode => "tail"
}
}
output {
http {
url => "https://<your-domain>/api/v2/ingest?pipeline_id=<pipeline_id>"
http_method => "post"
format => "message"
message => "%{message}"
content_type => "text/plain"
headers => {
"X-API-Key" => "<your-api-key>"
}
retry_non_idempotent => true
}
}
No filter section needed
The Pipeline parses logs on the server side, so no grok or other filters are needed in Logstash.
When using format => "message" you must also set message => "%{message}" (otherwise the pipeline fails to start with "message must be set if message format is used"); together they send the original log line as-is.
Run:
Migrating from Elastic?
Add a CSIRT-Pro output block alongside your existing Elasticsearch output to forward to both during the migration period.
Forward Syslog device logs
CSIRT-Pro does not receive Syslog directly, so Syslog from network devices and servers is converted to HTTP on the forwarder side and POSTed to the ingestion API. For example, rsyslog can forward over HTTP with the omhttp module.
# rsyslog example (/etc/rsyslog.d/csirt-pro.conf)
module(load="omhttp")
action(
type="omhttp"
server="<your-domain>"
restpath="api/v2/ingest?pipeline_id=<pipeline_id>"
httpheaders=["X-API-Key: <your-api-key>"]
template="RSYSLOG_FileFormat"
)
Syslog Pipeline configuration
After ingestion, configure your Pipeline parse rules so the regex accounts for the Syslog header format.
Syslog is not received directly
CSIRT-Pro does not provide a native UDP/TCP Syslog listener (no dedicated Syslog port).
The only ingestion paths are the HTTPS ingestion API and the HEC-compatible endpoints.
Receive Syslog with a forwarder (rsyslog omhttp, Vector syslog source, etc.) and forward it to the ingestion API over HTTP.
Step 4: Search Your Data
Once logs are ingested, query them with PRQL on the Search screen.
Open the Search Screen
- Open Search in the left sidebar.
- The PRQL query editor is at the top.
- Select a time range with the time picker.
Run Your First Query
This returns all records from the firewall_logs pipeline.
Add Filters
from `firewall_logs`
filter action == "DENY"
filter src_ip == "192.168.1.100"
sort {-__time}
take 100
Aggregate Data
from `firewall_logs`
filter action == "DENY"
group {src_ip} (
aggregate {count = count this}
)
sort {-count}
take 10
Visualize Results
Right-click the chart area to change the visualization type: Timeline, Bar, Line, Pie, Doughnut, Polar Area, Radar, or Markdown.
Keyboard shortcut
Press Ctrl + Enter to run a query.
Step 5: Create a Case
Cases track security incidents through investigation and resolution.
Create a Case Manually
- Open Case Management in the left sidebar.
- Click Create New.
- Enter a title and description for the incident.
- Set the initial status to Open.
- Save the case.
Use AI Features
- Similar case search. Click Similar Cases to find past incidents with similar characteristics. Matches are ranked by similarity of the case text.
- Response recommendations. Click AI Recommend to see suggested response procedures, ranked by a weighted score combining similarity and access history.
These features are advisory. They suggest, but do not take, response actions.
Step 6: Automate with a Playbook
Playbooks automate response workflows through a visual flow editor.
Create a Playbook
- Open Playbook in the left sidebar.
- Click Create New and give it a name (for example,
slack-alert-notification).
Add Nodes
Right-click the flow editor canvas and select Add Node. Choose from:
- Action runs code, such as HTTP requests, data transformations, and API calls.
- Condition branches the flow on a true/false evaluation.
- Loop iterates over a collection.
Write Code
Click a node to open the code editor, then write Python or JavaScript.
import requests
response = requests.post(
"https://slack.com/api/chat.postMessage",
headers={"Authorization": f"Bearer {env['SLACK_TOKEN']}"},
json={
"channel": "#security-alerts",
"text": f"New alert: {input_data['message']}"
}
)
output = response.json()
Connect Nodes
Drag connections between nodes to define the execution flow.
Set a Trigger
Configure when the playbook runs.
| Trigger | Description |
|---|---|
| Manual | Run from the UI or API |
| Webhook | Triggered by an external HTTP request |
| Schedule | Cron-based periodic execution |
| Case Creation | Runs automatically when a new case is created |
Response actions are approval-gated
Playbooks can draft response actions, but any write-back to an external system goes through an approval workflow (request, approve, apply) rather than executing automatically.
Test
- Open the Test tab.
- Enter sample input data as JSON.
- Click Run Test.
- Review the output of each node.
Next Steps
- Search Guide covers the full PRQL syntax and visualization options.
- Pipeline Guide covers advanced parse rules and data retention.
- Playbook Guide covers building automation flows with examples.
- Case Management covers incident tracking and AI features.
- Dashboards covers building dashboards and exporting PDF reports.
- UEBA covers setting up scheduled detection tasks.
- Integrations covers deploying integration packages.
- API Reference is the full REST API documentation.