<!-- Copyright (c) 2026 defconxt. All rights reserved. -->
<!-- Licensed under AGPL-3.0 — see LICENSE file for details. -->
---
name: building-detection-as-code-pipeline
description: >-
  Build CI/CD pipelines for detection content lifecycle management. Covers
  version-controlled Sigma rules, automated validation, conversion, testing
  against sample data, and deployment to SIEM platforms.
domain: cybersecurity
subdomain: blue-team
tags:
  - detection-as-code
  - ci-cd
  - sigma
  - github-actions
  - detection-engineering
version: "1.0"
author: defconxt
license: AGPL-3.0
metadata:
  mitre-attack: []
  mitre-attack: []
---

# Building Detection-as-Code Pipeline

## Overview

Detection-as-Code (DaC) treats detection rules as software artifacts — version
controlled, peer reviewed, tested, and deployed through CI/CD pipelines. This
approach eliminates manual SIEM rule creation, ensures consistency, enables
rollback, and provides audit trails for compliance.

## Prerequisites

| Requirement | Install |
|---|---|
| Git | Version control for rule repository |
| sigma-cli | `pip install sigma-cli` |
| GitHub Actions / GitLab CI | Pipeline orchestration |
| Python 3.10+ | Validation and testing scripts |
| SIEM API access | For automated deployment |

## Key Concepts

### Repository Structure

```
detection-rules/
├── .github/
│   └── workflows/
│       ├── validate.yml
│       └── deploy.yml
├── rules/
│   ├── credential_access/
│   ├── execution/
│   ├── lateral_movement/
│   └── persistence/
├── pipelines/
│   └── custom_fields.yml
├── tests/
│   ├── samples/
│   └── test_rules.py
├── config/
│   ├── targets.yml
│   └── exclusions.yml
└── scripts/
    ├── validate.py
    └── deploy.py
```

### GitHub Actions Validation Pipeline

```yaml
name: Detection Rule Validation
on:
  pull_request:
    paths: ['rules/**/*.yml']

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.12'
      - run: pip install sigma-cli pysigma-backend-splunk pysigma-backend-elasticsearch
      - name: Validate rule syntax
        run: |
          find rules/ -name '*.yml' -exec sigma check {} +
      - name: Convert to Splunk
        run: |
          find rules/ -name '*.yml' -exec sigma convert -t splunk -p splunk_cim {} +
      - name: Convert to Elastic
        run: |
          find rules/ -name '*.yml' -exec sigma convert -t elasticsearch -p ecs_windows {} +
      - name: Check required fields
        run: python3 scripts/validate.py rules/
```

### Deployment Pipeline

```yaml
name: Deploy Detection Rules
on:
  push:
    branches: [main]
    paths: ['rules/**/*.yml']

jobs:
  deploy-splunk:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: pip install sigma-cli pysigma-backend-splunk
      - name: Convert and deploy
        env:
          SPLUNK_URL: ${{ secrets.SPLUNK_URL }}
          SPLUNK_TOKEN: ${{ secrets.SPLUNK_TOKEN }}
        run: |
          for rule in $(git diff --name-only HEAD~1 -- 'rules/*.yml'); do
            query=$(sigma convert -t splunk -p splunk_cim "$rule")
            python3 scripts/deploy.py --target splunk --query "$query" --rule "$rule"
          done
```

### Rule Testing with Sample Data

```python
import subprocess
import yaml

def test_rule_against_sample(rule_path: str, sample_path: str) -> bool:
    """Convert rule to grep-compatible regex and test against sample."""
    with open(rule_path) as f:
        rule = yaml.safe_load(f)
    detection = rule.get("detection", {})
    selection = detection.get("selection", {})
    for field, value in selection.items():
        if isinstance(value, str):
            result = subprocess.run(
                ["grep", "-c", value, sample_path],
                capture_output=True, text=True,
            )
            if int(result.stdout.strip() or 0) > 0:
                return True
    return False
```

## Workflow

1. **Author rule** — Write Sigma YAML in feature branch
2. **Run local validation** — `sigma check rule.yml`
3. **Open pull request** — CI runs validation and conversion
4. **Peer review** — Detection engineer reviews logic and FP analysis
5. **Merge** — Triggers deployment pipeline
6. **Deploy** — Converted queries pushed to SIEM via API
7. **Monitor** — Track rule firing rate and false positive ratio
8. **Iterate** — Tune rules based on production data

## Verification

| Check | Method |
|---|---|
| CI passes | All sigma check and convert steps exit 0 |
| Rules deploy | SIEM API returns success for each rule push |
| No regressions | Converted output matches expected baseline |
| Coverage tracked | ATT&CK matrix coverage script reports delta |
| Audit trail | Git log shows who changed what and when |

## References

- [Sigma CLI Documentation](https://sigmahq.io/docs/guide/getting-started.html)
- [Detection Engineering Weekly](https://www.detectionengineering.net/)
- [MITRE ATT&CK Navigator](https://mitre-attack.github.io/attack-navigator/)
- [Splunk REST API](https://docs.splunk.com/Documentation/Splunk/latest/RESTREF)
