<!-- Copyright (c) 2026 defconxt. All rights reserved. -->
<!-- Licensed under AGPL-3.0 — see LICENSE file for details. -->
---
name: implementing-security-ticket-automation
description: >-
  Automate security ticket creation, enrichment, routing, SLA tracking,
  and lifecycle management across ticketing platforms with deduplication,
  priority scoring, and escalation workflows.
domain: cybersecurity
subdomain: security-operations-automation
tags:
  - ticketing
  - jira
  - servicenow
  - automation
  - sla
  - incident-management
version: "1.0"
author: defconxt
license: AGPL-3.0
metadata:
  mitre-attack: []
---

# Implementing Security Ticket Automation

## Overview

Security teams drown in manual ticket creation and routing. This technique
automates the full ticket lifecycle: auto-creating tickets from SIEM alerts,
enriching with asset and threat context, deduplicating related alerts into
single incidents, routing by severity and team, enforcing SLA timelines,
and escalating breached tickets.

Mode: `[MODE: BLUE]` — Operational efficiency and response tracking.

## Prerequisites

| Requirement | Details |
|---|---|
| Python 3.10+ with `requests` | Required |
| Ticketing platform API (Jira, ServiceNow, PagerDuty) | Required |
| SIEM webhook or polling integration | Required |
| Asset inventory for enrichment | Required |

## Key Concepts

### Ticket Creation and Enrichment

```python
from datetime import datetime, timezone
from typing import Any


def create_security_ticket(
    alert: dict[str, Any],
    enrichment: dict[str, Any] | None = None,
) -> dict[str, Any]:
    """Create an enriched security ticket from an alert."""
    severity_map = {"critical": "P1", "high": "P2", "medium": "P3", "low": "P4"}
    priority = severity_map.get(alert.get("severity", "medium"), "P3")

    ticket = {
        "ticket_id": f"SEC-{datetime.now(timezone.utc).strftime('%Y%m%d%H%M')}",
        "title": f"[{priority}] {alert.get('alert_name', 'Security Alert')}",
        "description": _build_description(alert, enrichment),
        "priority": priority,
        "severity": alert.get("severity", "medium"),
        "assignee": _route_ticket(alert),
        "labels": ["security", "automated", alert.get("source", "unknown")],
        "created": datetime.now(timezone.utc).isoformat(),
        "sla_hours": _get_sla_hours(priority),
    }
    return ticket


def _build_description(alert: dict, enrichment: dict | None) -> str:
    lines = [
        f"Alert: {alert.get('alert_name', 'N/A')}",
        f"Source: {alert.get('source', 'N/A')}",
        f"Host: {alert.get('hostname', 'N/A')}",
        f"Time: {alert.get('timestamp', 'N/A')}",
    ]
    if enrichment:
        lines.append(f"Asset Owner: {enrichment.get('owner', 'N/A')}")
        lines.append(f"Criticality: {enrichment.get('criticality', 'N/A')}")
    return "\n".join(lines)


def _route_ticket(alert: dict) -> str:
    severity = alert.get("severity", "medium")
    if severity in ("critical", "high"):
        return "soc-tier2"
    return "soc-tier1"


def _get_sla_hours(priority: str) -> int:
    return {"P1": 1, "P2": 4, "P3": 24, "P4": 72}.get(priority, 24)
```

### Deduplication Engine

```python
def deduplicate_alerts(
    alerts: list[dict[str, Any]],
    group_keys: list[str] | None = None,
) -> list[dict[str, Any]]:
    """Group related alerts into single incidents."""
    keys = group_keys or ["hostname", "alert_name"]
    groups: dict[str, list[dict[str, Any]]] = {}
    for alert in alerts:
        group_key = "|".join(str(alert.get(k, "")) for k in keys)
        groups.setdefault(group_key, []).append(alert)

    incidents: list[dict[str, Any]] = []
    for key, group in groups.items():
        incidents.append({
            "group_key": key,
            "alert_count": len(group),
            "first_seen": min(a.get("timestamp", "") for a in group),
            "last_seen": max(a.get("timestamp", "") for a in group),
            "severity": max((a.get("severity", "low") for a in group),
                          key=lambda s: ["low", "medium", "high", "critical"].index(s)),
        })
    return incidents
```

## Workflow

### Step 1: Process Alert Queue

```bash
node scripts/agent.js --action process-alerts
```

### Step 2: Check SLA Compliance

```bash
node scripts/agent.js --action sla-check
```

### Step 3: Escalate Breached Tickets

```bash
node scripts/agent.js --action escalate
```

## Verification

- [ ] Tickets auto-created from SIEM alerts with enrichment
- [ ] Related alerts deduplicated into single incidents
- [ ] Routing assigns correct team by severity
- [ ] SLA breach triggers automated escalation

## References

- [Jira REST API](https://developer.atlassian.com/cloud/jira/platform/rest/v3/)
- [ServiceNow Table API](https://docs.servicenow.com/bundle/tokyo-application-development/page/integrate/inbound-rest/concept/c_TableAPI.html)
- [NIST SP 800-61r2 — Incident Prioritization](https://csrc.nist.gov/publications/detail/sp/800-61/rev-2/final)
