<!-- Copyright (c) 2026 defconxt. All rights reserved. -->
<!-- Licensed under AGPL-3.0 — see LICENSE file for details. -->
---
name: implementing-security-event-enrichment
description: >-
  Implement security event enrichment pipelines that add threat intelligence,
  GeoIP data, asset context, and user identity information to raw SIEM events
  for faster triage and reduced false positives.
domain: cybersecurity
subdomain: security-operations-automation
tags:
  - event-enrichment
  - siem
  - geoip
  - threat-intelligence
  - asset-context
  - triage
version: "1.0"
author: defconxt
license: AGPL-3.0
metadata:
  mitre-attack: []
---

# Implementing Security Event Enrichment

## Overview

Event enrichment transforms raw security events into actionable alerts by adding
contextual data: threat intelligence scores, GeoIP location, asset criticality,
user role information, and historical frequency. Enriched events enable faster
triage, reduce false positive rates, and support automated severity scoring.

Mode: `[MODE: BLUE]` — Event pipeline enhancement.

## Prerequisites

| Requirement | Details |
|---|---|
| Python 3.10+ with `requests`, `geoip2` | Required |
| MaxMind GeoLite2 database for GeoIP lookups | Required |
| Threat intelligence API access (VT, AbuseIPDB) | Required |
| CMDB/asset inventory API for host context | Required |

## Key Concepts

### Enrichment Pipeline

```python
def enrich_event(event: dict, enrichers: list) -> dict:
    """Run event through enrichment pipeline."""
    enriched = {**event, "enrichments": {}}
    for enricher in enrichers:
        name = enricher.__name__
        try:
            enriched["enrichments"][name] = enricher(event)
        except Exception as e:
            enriched["enrichments"][name] = {"error": str(e)}
    return enriched
```

### GeoIP Enrichment

```python
def enrich_geoip(event: dict) -> dict:
    """Add GeoIP data to IP addresses in event."""
    import geoip2.database
    reader = geoip2.database.Reader("/usr/share/GeoIP/GeoLite2-City.mmdb")
    src_ip = event.get("src_ip")
    if src_ip:
        try:
            resp = reader.city(src_ip)
            return {
                "country": resp.country.iso_code,
                "city": resp.city.name,
                "latitude": resp.location.latitude,
                "longitude": resp.location.longitude,
            }
        except Exception:
            return {"country": "unknown"}
    return {}
```

### Asset Context

```python
def enrich_asset(event: dict) -> dict:
    """Add asset context from CMDB."""
    hostname = event.get("hostname", event.get("dest_host"))
    asset_db = {
        "web-01": {"criticality": "high", "owner": "platform", "environment": "production"},
        "db-01": {"criticality": "mission-critical", "owner": "dba", "environment": "production"},
    }
    return asset_db.get(hostname, {"criticality": "unknown", "owner": "unassigned"})
```

## Workflow

### Step 1: Enrich Single Event

```bash
node scripts/agent.js --action enrich --event '{"src_ip": "185.220.101.1", "hostname": "web-01"}'
```

### Step 2: Batch Enrichment

```bash
node scripts/agent.js --action batch-enrich --input /tmp/events.json
```

### Step 3: Enrichment Stats

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

## Verification

- [ ] GeoIP enrichment adds country and coordinates for public IPs
- [ ] TI enrichment adds threat score and malicious indicators
- [ ] Asset context adds criticality and owner information
- [ ] Enrichment failures are captured without blocking pipeline

## References

- [MaxMind GeoIP2 Python API](https://github.com/maxmind/GeoIP2-python)
- [Elastic Enrich Processor](https://www.elastic.co/guide/en/elasticsearch/reference/current/enrich-processor.html)
- [Splunk Lookups](https://docs.splunk.com/Documentation/Splunk/latest/Knowledge/Aboutlookupsandfieldactions)
