Deep Dive: Detection-as-Code and ATT&CK Mapping, Advanced tier
PractitionerEngineering practice; ATT&CK and Sigma references are to the published projects.
Doc 13 §2 states the principles; this document is the engineering manual. Audience: detection engineers and technical leads in S/A-tier CDCs, or teams demanding this of an MSSP. Everything below is vendor-neutral; Sigma is used as the authoring format because it is open and convertible to most platforms.
1. Repository layout
Treat the detection repo as a software project. A layout that has proven durable:
detections/
├── rules/ # one YAML file per detection
│ ├── windows/
│ │ ├── win_priv_group_addition.yml
│ │ └── win_lolbin_certutil_download.yml
│ ├── linux/
│ ├── macos/
│ ├── identity/ # IdP / directory detections
│ ├── cloud/ # IaaS/SaaS control plane
│ └── network/
├── tests/
│ ├── samples/ # sanitised log events per rule (positive & negative)
│ │ └── win_priv_group_addition/
│ │ ├── should_fire_01.json
│ │ └── should_not_fire_01.json
│ └── emulation/ # scripted attack emulation mapped to rules
├── suppressions/ # tuning as code: owner + expiry per entry
│ └── win_priv_group_addition.yml
├── runbooks/ # triage steps, versioned next to the rule
├── pipelines/ # CI definitions, converters, deploy scripts
├── navigator/ # generated ATT&CK Navigator layers (JSON)
└── docs/ # conventions, onboarding, this workflow
Conventions that pay off: one rule per file · file name = rule id · everything reviewable in a diff · no logic that exists only in the SIEM console.
2. Anatomy of a rule in Sigma-style YAML
Original example, detecting addition to a privileged directory group:
title: Addition To Privileged Group
id: 3f2a9c1e-7b4d-4e8a-9c21-5d8e4b2a7f60 # stable UUID, never reused
status: production # experimental | test | production | retired
description: >
Detects a user being added to a highly privileged directory group.
Legitimate additions should follow the PAM change process; anything
outside it warrants investigation.
references:
- internal: UC-0042 # link to the use-case record
author: <team, not individual> # bus-factor hygiene
date: 2026/07/10
modified: 2026/07/10
tags:
- attack.persistence # ATT&CK tactic
- attack.t1098.007 # technique/sub-technique: Account
# Manipulation: Additional Local or Domain Groups
- cia.integrity # OCDF: primary CIA objective
- tier.essential # OCDF tier tag (E/S/A)
logsource:
product: windows
service: security
detection:
selection:
EventID: 4728 # member added to security-enabled global group
TargetGroupName|contains:
- 'Domain Admins'
- 'Enterprise Admins'
- '<your tier-0 groups>'
filter_pam_process:
SubjectUserName|startswith: 'svc-pam-' # your PAM service account convention
condition: selection and not filter_pam_process
falsepositives:
- Emergency break-glass procedure (verify against break-glass log)
level: high
fields: [SubjectUserName, TargetUserName, TargetGroupName]
Metadata discipline is the point: the tags block is what makes coverage measurable, per §4; the id is what makes history traceable, status drives pipeline behaviour, and falsepositives seeds the runbook. Extend the schema with custom fields if needed, such as owner, review-by date or data-source dependency, but validate them in CI so they stay populated.
Suppressions live in their own files, never inline hacks:
# suppressions/win_priv_group_addition.yml
- reason: "IAM migration project batch adds"
match: { SubjectUserName: 'svc-iam-migrate' }
owner: detection-engineering
ticket: CDC-1234
expires: 2026-09-30 # CI fails the build on expired suppressions
3. The CI/CD pipeline
Merge to main is the only road to production. Stages:
- Lint & schema validation: YAML parses; mandatory fields present; UUID unique; tags reference valid ATT&CK IDs, validated against the ATT&CK STIX data rather than a hand-maintained list.
- Unit tests: run each rule against its
should_fireandshould_not_firesamples with a Sigma-aware test harness or a scratch instance of your platform. A rule without at least one positive and one negative sample fails the build. - Conversion: compile Sigma to the target platform's query language with sigma-cli or pySigma backends. Conversion errors fail the build; review the compiled output for expensive constructs.
- Staging deploy: push to a staging or QA workspace and smoke-test against recent live data for volume, so an unexpectedly hot rule gets caught here, not in analysts' queues.
- Production deploy: API-driven; the pipeline records rule id ↔ platform object id.
- Drift detection: a nightly job diffs platform state against the repo; console edits are flagged and reverted or back-ported the same week.
- Emulation validation, scheduled rather than per-commit: periodically execute mapped attack emulations such as Atomic Red Team tests matching each rule's technique tags, in a lab or canary scope and confirm the alert fires end-to-end, through the alert pipeline, not just the query.
Adoption reality: build stages 1–3 first, a week of work with immediate payoff, then 5–6, then automate 7. Do not gate initial adoption on the full pipeline.
4. ATT&CK mapping methodology — mapping honestly
ATT&CK mapping is easy to do badly. Rules that make it useful:
- Map to sub-technique where one exists; technique level only when the detection genuinely spans sub-techniques. Tactic-only tags are placeholders, not mappings.
- Map the behaviour the logic actually catches, not the scenario that inspired it. A rule catching
certutildownloads maps to T1105, Ingress Tool Transfer, even if you wrote it "because ransomware". - One detection may map to several techniques; several detections per technique is normal and good, since depth beats breadth on high-value techniques.
- Score coverage per technique on an honesty scale, not a checkbox:
- 0: no relevant telemetry collected
- 1: telemetry exists and could be hunted, no detection
- 2: detection deployed, not validated in the last 12 months
- 3: detection deployed and validated, having fired in test
- Scope the matrix before scoring: filter ATT&CK to your threat profile's techniques, per CTI deep dive §5, and your platforms. "37% of all of ATT&CK" is meaningless; "level ≥2 on 80% of the techniques our top three threat actors use" is a management-grade statement.
- Generate, don't hand-paint: the pipeline should emit an ATT&CK Navigator layer JSON from the rule tags plus validation results, so the coverage picture is always current. Publish it to the team monthly; bring the threat-profile-scoped view to GOVERN quarterly.
Common traps: counting a noisy, permanently-suppressed rule as coverage; mapping identity attacks only under Credential Access and forgetting Initial Access; scoring on rule existence while the required log source was decommissioned last quarter. Tie rule metadata to log-source dependency and check it in drift detection.
5. Metrics for this practice
% rules with passing unit tests · % rules validated by emulation ≤12 months · median idea→production lead time · drift incidents per month, target zero · expired suppressions, target zero · coverage level ≥2 on threat-profile techniques.
Sources
- Sigma project & pySigma converters. https://github.com/SigmaHQ/sigma
- MITRE ATT&CK® and ATT&CK Navigator. https://attack.mitre.org · https://mitre-attack.github.io/attack-navigator/
- Red Canary, Atomic Red Team, an attack emulation library. https://github.com/redcanaryco/atomic-red-team
- MITRE, 11 Strategies of a World-Class Cybersecurity Operations Center, 2nd ed.
Open CDC Framework, licensed CC BY 4.0. ATT&CK® is a registered trademark of The MITRE Corporation.