Ticketing¶
Closed Beta
Ticketing is currently in closed beta. Please contact LimaCharlie to request access.
The Ticketing extension is a purpose-built SOC triage system that automatically converts LimaCharlie detections into trackable tickets with SLA enforcement, investigation tooling, and performance reporting. It is designed for high-volume environments where every detection needs to be acknowledged, investigated, classified, and resolved within measurable timeframes.
Once subscribed, all detections from the organization are automatically ingested and converted into tickets. Analysts work the ticket queue through a defined lifecycle, attach investigation evidence, and classify outcomes. SOC managers get real-time dashboards and MTTA/MTTR reports.
Enabling the Extension¶
Navigate to the Ticketing extension page in the marketplace. Select the organization you wish to enable it for, and select Subscribe.
On subscription, the extension automatically:
- Creates a detection output that forwards all detections to the ticketing system
- Initializes the organization with default configuration (severity mapping, SLA targets, retention)
No additional setup is required to begin receiving tickets. Detections start flowing immediately.
The full API specification is available as an OpenAPI document at ticketing.limacharlie.io/openapi.
Permissions
The ticketing extension uses LimaCharlie's existing RBAC permissions. Analysts need investigation.get to view tickets and reports, and investigation.set to update tickets, add notes, and manage investigation data. Configuration management requires org.conf.get to read and org.conf.set to update organization settings.
How Tickets Are Created¶
Every detection generated by D&R rules in a subscribed organization automatically becomes a ticket. The mapping is one detection to one ticket by default.
Each ticket captures from the detection:
- Detection category (the D&R rule name)
- Detection source (the rule namespace)
- Detection priority (mapped to severity)
- Sensor ID and hostname of the affected endpoint
- Detection ID (used for deduplication)
Duplicate detections (same detection_id) are silently dropped to prevent ticket duplication.
Auto-Grouping¶
When auto-grouping is enabled in the organization configuration, detections that share the same category and sensor within a one-hour window are automatically grouped into a single ticket instead of creating separate tickets. This significantly reduces ticket volume for noisy rules.
When a detection is grouped into an existing ticket:
- The ticket's
detection_countincrements - The severity may be upgraded if the new detection has a higher priority
- An event is recorded in the ticket's audit trail
Ticket Lifecycle¶
Tickets follow a defined state machine that tracks progress from creation through resolution.
stateDiagram-v2
[*] --> new
new --> acknowledged
new --> in_progress
new --> escalated
new --> closed
new --> merged
acknowledged --> in_progress
acknowledged --> escalated
acknowledged --> closed
acknowledged --> merged
in_progress --> escalated
in_progress --> resolved
in_progress --> closed
in_progress --> merged
escalated --> in_progress
escalated --> resolved
escalated --> closed
escalated --> merged
resolved --> closed
resolved --> in_progress: reopen
resolved --> merged
closed --> [*]
merged --> [*]
Status Definitions¶
| Status | Description |
|---|---|
new |
Ticket created, not yet reviewed by an analyst |
acknowledged |
Analyst has seen and accepted the ticket. Records MTTA timestamp |
in_progress |
Active investigation underway |
escalated |
Escalated to a senior analyst or specialized team |
resolved |
Investigation complete, findings documented. Records MTTR timestamp |
closed |
Ticket fully closed. Terminal state |
merged |
Ticket was merged into another ticket. Terminal state |
Key Timestamps¶
created_at-- Set when the ticket is created from a detectionacknowledged_at-- Set on first transition toacknowledged(used for MTTA calculation)resolved_at-- Set on first transition toresolved(used for MTTR calculation)closed_at-- Set on transition toclosed
Severity and SLA¶
Severity Mapping¶
LimaCharlie detection priorities (integer 0--10) are mapped to four severity levels. The thresholds are configurable per organization.
| Severity | Default Priority Range | Description |
|---|---|---|
critical |
8--10 | Requires immediate response |
high |
5--7 | Urgent, handle promptly |
medium |
3--4 | Standard priority |
low |
0--2 | Informational, handle when available |
SLA Targets¶
Each severity level has two SLA targets:
- MTTA (Mean Time To Acknowledge) -- Maximum time from ticket creation to first acknowledgement
- MTTR (Mean Time To Resolve) -- Maximum time from ticket creation to resolution
Default SLA targets:
| Severity | MTTA Target | MTTR Target |
|---|---|---|
critical |
15 minutes | 4 hours |
high |
15 minutes | 12 hours |
medium |
1 hour | 24 hours |
low |
100 minutes | ~47 hours |
SLA breaches are tracked in the dashboard and reporting views.
Configuration¶
Each organization has its own configuration that controls severity mapping, SLA targets, retention, and optional features.
Configuration Options¶
| Setting | Type | Default | Description |
|---|---|---|---|
severity_mapping.critical_min |
int | 8 |
Minimum detection priority for critical severity |
severity_mapping.high_min |
int | 5 |
Minimum detection priority for high severity |
severity_mapping.medium_min |
int | 3 |
Minimum detection priority for medium severity |
sla_config.critical.mtta_minutes |
int | 15 |
MTTA target for critical tickets (minutes) |
sla_config.critical.mttr_minutes |
int | 240 |
MTTR target for critical tickets (minutes) |
sla_config.high.mtta_minutes |
int | 15 |
MTTA target for high tickets (minutes) |
sla_config.high.mttr_minutes |
int | 720 |
MTTR target for high tickets (minutes) |
sla_config.medium.mtta_minutes |
int | 60 |
MTTA target for medium tickets (minutes) |
sla_config.medium.mttr_minutes |
int | 1440 |
MTTR target for medium tickets (minutes) |
sla_config.low.mtta_minutes |
int | 100 |
MTTA target for low tickets (minutes) |
sla_config.low.mttr_minutes |
int | 2800 |
MTTR target for low tickets (minutes) |
retention_days |
int | 90 |
Days to retain resolved/closed tickets before archival |
auto_close_resolved_after_days |
int | 7 |
Automatically close resolved tickets after this many days |
auto_grouping_enabled |
bool | false |
Enable auto-grouping of related detections into single tickets |
Get Configuration¶
Update Configuration¶
curl -s -X PUT \
"https://ticketing.limacharlie.io/api/v1/config/YOUR_OID" \
-H "Authorization: Bearer $LC_JWT" \
-H "Content-Type: application/json" \
-d '{
"severity_mapping": {
"critical_min": 8,
"high_min": 5,
"medium_min": 3
},
"sla_config": {
"critical": {"mtta_minutes": 15, "mttr_minutes": 240},
"high": {"mtta_minutes": 30, "mttr_minutes": 480},
"medium": {"mtta_minutes": 60, "mttr_minutes": 1440},
"low": {"mtta_minutes": 120, "mttr_minutes": 2880}
},
"retention_days": 90,
"auto_close_resolved_after_days": 7,
"auto_grouping_enabled": true
}'
Working with Tickets¶
Creating a Ticket¶
While detections are automatically converted to tickets, you can also create tickets manually via the CLI or SDK. This is useful for ad-hoc investigations or when integrating with external detection sources.
from limacharlie.sdk.ticketing import Ticketing
from limacharlie.sdk.organization import Organization
from limacharlie.client import Client
client = Client(oid="YOUR_OID")
org = Organization(client)
t = Ticketing(org)
result = t.create_ticket(
"DETECTION_ID",
detection_cat="lateral_movement",
severity="high",
sensor_id="SENSOR_ID",
hostname="DESKTOP-001",
)
print(result["ticket_number"])
Listing Tickets¶
Query the ticket queue with filtering, sorting, and pagination. Supports cross-organization queries for multi-tenant SOCs.
Available query parameters:
| Parameter | Description |
|---|---|
oids |
Organization IDs (comma-separated, required) |
status |
Filter by status (comma-separated: new, acknowledged, in_progress, escalated, resolved, closed) |
severity |
Filter by severity (comma-separated: critical, high, medium, low) |
classification |
Filter by classification (comma-separated: pending, true_positive, false_positive) |
assignee |
Filter by assigned analyst email |
search |
Search text (matches against detection category and hostname) |
tag |
Filter by tags (comma-separated, AND logic: all specified tags must be present) |
sort |
Sort field (created_at, severity, ticket_number) |
order |
Sort order (asc, desc) |
page_size |
Page size, 1--200 (default 50) |
page_token |
Pagination token from previous response |
Getting a Ticket¶
Returns the full ticket including the event timeline (audit trail of all changes).
Exporting a Ticket¶
Export a ticket with all its components (ticket record, event timeline, detections, entities, telemetry, and artifacts) in a single JSON object.
Without --with-data, the combined metadata JSON is printed to stdout. With --with-data <DIR>, the command creates a directory containing:
ticket.json-- ticket record, event timeline, entitiesdetections/-- one JSON file per linked detection (fetched from Insight)telemetry/-- one JSON file per linked telemetry event (fetched by atom+sid)artifacts/-- downloaded artifact binaries
Fetches that fail (e.g. expired or retained data) emit a warning and are skipped.
Updating a Ticket¶
Updatable fields:
| Field | Type | Description |
|---|---|---|
status |
string | New status (must be a valid transition) |
assignee |
string | Analyst to assign the ticket to |
classification |
string | true_positive, false_positive, or pending |
escalation_group |
string | Team or group to escalate to |
investigation_id |
string | Link to a LimaCharlie Investigation |
summary |
string | Investigation summary narrative (max 8192 characters) |
conclusion |
string | Final conclusion (max 8192 characters) |
tags |
string[] | Arbitrary tags for categorization (see Tags) |
Bulk Updates¶
Update multiple tickets at once, useful for bulk-closing false positives or reassigning workload.
Up to 200 tickets can be updated in a single bulk operation.
Tags¶
Tickets support arbitrary string tags for custom categorization and workflow organization (e.g., "phishing", "ransomware", "shift-b").
Constraints:
| Constraint | Value |
|---|---|
| Max tag length | 128 characters |
| Max tags per ticket | 50 |
| Case sensitivity | Case-preserved, case-insensitive deduplication |
| Allowed characters | Any printable character (no control characters) |
Setting Tags¶
Tags are set by replacing the full tag array on the ticket.
Tag Management CLI¶
The CLI provides convenience commands for adding or removing individual tags without replacing the full array.
# Replace all tags
limacharlie ticket tag set --id 42 --tag phishing --tag urgent --oid YOUR_OID
# Add a tag (preserves existing tags)
limacharlie ticket tag add --id 42 --tag new-label --oid YOUR_OID
# Remove a tag
limacharlie ticket tag remove --id 42 --tag old-label --oid YOUR_OID
Filtering by Tag¶
Filter the ticket list to only tickets that have all specified tags (AND logic).
Tag changes create a tags_updated event in the ticket's audit trail with old and new tag values in the event metadata.
Classification¶
Tickets are classified to track detection accuracy. Classification can be set at any status.
| Classification | Description |
|---|---|
pending |
Not yet classified (default) |
true_positive |
Confirmed malicious or policy-violating activity |
false_positive |
Benign activity incorrectly flagged |
Classification rates are tracked in reports and feed into detection rule tuning.
Detections¶
Each ticket is created from a detection and can have additional detections linked to it (for example, when auto-grouping is enabled or when manually associating related detections).
Link a Detection¶
curl -s -X POST \
"https://ticketing.limacharlie.io/api/v1/tickets/42/detections?oid=YOUR_OID" \
-H "Authorization: Bearer $LC_JWT" \
-H "Content-Type: application/json" \
-d '{
"detection_id": "DETECTION_ID",
"detection_cat": "lateral-movement",
"detection_source": "dr-general",
"detection_priority": 7,
"sensor_id": "550e8400-e29b-41d4-a716-446655440000",
"hostname": "DESKTOP-001"
}'
List Linked Detections¶
Unlink a Detection¶
Investigation¶
Each ticket supports structured investigation evidence that creates a documented chain of analysis.
Entities (IOCs)¶
Attach indicators of compromise and other artifacts of interest to a ticket.
# Add an entity
curl -s -X POST \
"https://ticketing.limacharlie.io/api/v1/tickets/42/entities?oid=YOUR_OID" \
-H "Authorization: Bearer $LC_JWT" \
-H "Content-Type: application/json" \
-d '{
"entity_type": "ip",
"entity_value": "203.0.113.50",
"name": "Suspected C2 Server",
"verdict": "malicious",
"context": "Outbound connections observed from compromised host"
}'
limacharlie ticket entity add --ticket 42 \
--type ip --value "203.0.113.50" --verdict malicious \
--context "Outbound connections observed from compromised host"
limacharlie ticket entity list --ticket 42
limacharlie ticket entity update --ticket 42 --entity-id ENTITY_ID --verdict benign
limacharlie ticket entity remove --ticket 42 --entity-id ENTITY_ID
Supported entity types: ip, domain, hash, url, user, email, file, process, registry, other
Verdict values: malicious, suspicious, benign, unknown, informational
Cross-Ticket Entity Search¶
Find all tickets containing a specific indicator. This is critical for understanding the blast radius of an IOC across the organization.
Telemetry References¶
Link specific LimaCharlie events to the ticket by their atom and sensor ID. This creates a direct reference back to the raw telemetry for forensic review.
curl -s -X POST \
"https://ticketing.limacharlie.io/api/v1/tickets/42/telemetry?oid=YOUR_OID" \
-H "Authorization: Bearer $LC_JWT" \
-H "Content-Type: application/json" \
-d '{
"atom": "abc123def456",
"sid": "550e8400-e29b-41d4-a716-446655440000",
"event_type": "NEW_PROCESS",
"event_summary": "powershell.exe launched with encoded command",
"verdict": "malicious",
"relevance": "Initial payload execution"
}'
Artifacts¶
Attach references to forensic artifacts such as memory dumps, packet captures, or disk images.
Notes¶
Add structured notes to document analysis, remediation steps, and handoff information.
Note types: general, analysis, remediation, escalation, handoff
Ticket Merging¶
Related tickets can be merged when multiple detections are part of the same incident. Merging consolidates the investigation into a single primary ticket.
Up to 20 source tickets can be merged at once.
When tickets are merged:
- The target ticket inherits all detections from source tickets
- Merged tickets transition to the
mergedstatus (terminal) - The
merged_into_ticket_idfield on merged tickets references the primary ticket - Merge events are recorded in the audit trail of all affected tickets
Escalation¶
Tickets can be escalated to specialized teams or senior analysts by setting the escalation_group field and transitioning to escalated status.
Tickets can be filtered by escalation_group in the listing endpoint. Escalation rates are tracked in reports.
Assignees¶
List all unique assignee emails across your accessible organizations. Useful for populating assignment dropdowns.
D&R Rule Integration¶
The ticketing extension exposes request handlers that can be used in D&R rule response actions. This enables automated ticket management based on detection logic.
Create a Ticket Manually¶
Create a ticket from a D&R rule response action, useful for rules that need tickets for specific scenarios beyond the default auto-ticketing.
respond:
- action: extension request
extension name: ext-ticketing
extension action: create_ticket
extension request:
detection_cat: '{{ .cat }}'
detection_source: manual
detection_priority: 5
sensor_id: '{{ .routing.sid }}'
hostname: '{{ .routing.hostname }}'
Query Open Ticket Count¶
Use as a condition in D&R rules to trigger actions based on ticket volume. For example, escalate when a sensor has too many open tickets.
detect:
event: detection
op: extension
extension name: ext-ticketing
extension action: get_ticket_count
extension request:
sensor_id: '{{ .routing.sid }}'
status: new,acknowledged,in_progress
path: count
value: 10
op: is greater than
Dashboard¶
The dashboard provides real-time visibility into the ticket queue.
Returns:
- Ticket counts by status
- Ticket counts by severity
- SLA breach counts (tickets exceeding MTTA or MTTR targets)
Reporting¶
SOC performance reports provide aggregated metrics for measuring team effectiveness and detection quality.
Summary Report¶
Query parameters:
| Parameter | Description |
|---|---|
oids |
Organization IDs (comma-separated) |
from |
Start of reporting period (RFC 3339 timestamp) |
to |
End of reporting period (RFC 3339 timestamp) |
The summary report includes per-organization and aggregate metrics:
- MTTA -- Average and median time to acknowledge, with SLA compliance
- MTTR -- Average and median time to resolve, with SLA compliance
- Volume -- Total ticket counts, true positives, and false positives
- Classification rates -- True positive vs false positive percentages
Webhook Notifications¶
The extension automatically sends webhook notifications for ticket events via LimaCharlie's extension hooks mechanism. These are delivered as gzip-compressed HTTP POST requests to the organization's configured webhook adapter endpoint.
Events forwarded via webhook include: ticket creation, status changes, assignments, escalations, classifications, notes, and investigation updates.
Each webhook payload includes:
action-- The event type (e.g.created,status_changed,assigned)ticket_id-- The affected ticket IDticket_number-- The human-readable ticket numberoid-- The organization IDby-- The user who performed the actionts-- Timestamp of the eventmetadata-- Event-specific details (e.g. old/new status values)
Audit Trail¶
Every action on a ticket is recorded as an immutable event in the ticket's timeline. This provides a complete chain of custody for compliance and review.
Tracked event types:
| Event | Description |
|---|---|
created |
Ticket created from detection |
acknowledged |
Ticket first acknowledged |
status_changed |
Status transition |
assigned |
Analyst assigned |
escalated |
Ticket escalated to a group |
classified |
True positive / false positive classification set |
resolved |
Ticket resolved |
closed |
Ticket closed |
reopened |
Resolved ticket reopened |
note_added |
Note added to ticket |
investigation_linked |
LimaCharlie investigation linked |
detection_added |
Detection grouped into ticket |
detection_removed |
Detection removed from ticket |
severity_upgraded |
Severity increased due to higher-priority detection |
merged_into |
Ticket merged into another ticket |
merged_from |
Ticket received merge from another ticket |
entity_added |
IOC/entity attached |
entity_updated |
Entity verdict or context updated |
entity_removed |
Entity removed |
telemetry_added |
Telemetry reference linked |
telemetry_updated |
Telemetry metadata updated |
telemetry_removed |
Telemetry reference removed |
artifact_added |
Forensic artifact attached |
artifact_removed |
Artifact removed |
tags_updated |
Tags modified (old and new values in metadata) |
summary_updated |
Investigation summary edited |
conclusion_updated |
Investigation conclusion edited |
Data Retention¶
Resolved and closed tickets are retained for the configured retention_days (default 90 days). After the retention period, tickets are archived to long-term storage and removed from the active ticket store.
Archived data is retained for 2 years in long-term storage for compliance and historical reporting.
Unsubscribing¶
Unsubscribing from the extension removes the detection output and deletes all ticket data for the organization. This action is irreversible.
See Also¶
- Investigation -- Investigation records that can be linked to tickets
- D&R Rules Overview -- Detection rules that generate the detections ingested as tickets
- Response Actions -- The
extension requestaction used for D&R rule integration - Using Extensions -- General extension subscription and management